Skip to main content

Timeline and Events

An agent has one durable timeline. REST and Remote MCP read the same underlying events but use different response envelopes. Store returned cursors unchanged; their internal format is not a client-generated timestamp or UUID.

For agents with application requests, broad timeline/debug/wait reads require all retained application history to belong to the calling principal and current owner, with content and artifacts retained. Foreign, transferred or purged request history returns REST 403 application_request_scope_required or an MCP tool error; use the scoped request endpoints. Filters, a known message ID, management scope or staff targeting do not bypass that boundary. Each wait snapshot rechecks authority; locks end before polling sleep.

REST timeline​

GET /api/v1/agents/{id}/timeline/ requires agents:read.

ParameterBehavior
directioninitial (default), older, or newer
cursorBoundary cursor from a previous response or event
limitDefault 40, clamped to 1–100

The response contains events, oldest_cursor, newest_cursor, has_more_older, has_more_newer, processing_active, and processing_snapshot. These flags describe navigation in each direction. To read older history, pass oldest_cursor with direction=older; to catch up, pass newest_cursor with direction=newer. Empty windows may have null boundary cursors.

curl --fail-with-body -G -H "X-Api-Key: $API_KEY" \
--data-urlencode "cursor=$CURSOR" --data-urlencode "direction=newer" \
--data-urlencode "limit=100" "$API_BASE/agents/$AGENT_ID/timeline/"

REST does not interpret after_cursor on the timeline GET route; it is ignored rather than treated as the boundary. Remote MCP get_agent_timeline additionally supports after_cursor, and returns next_cursor, latest_cursor, and has_more alongside its other fields. MCP rejects timeline limits outside 1–100 while REST clamps them. Keep the last non-null cursor when a timeline window is empty. Do not share response parsers between the transports without adapting the envelope.

Event payloads​

Every event has kind and cursor. Event-specific fields may evolve; preserve unknown fields and handle unknown kinds without discarding your saved cursor.

KindContent
messagetimestamp and nested message
stepsentries, entryCount, collapsible, collapseThreshold, earliestTimestamp, latestTimestamp; a cluster has no required top-level timestamp
thinkingtimestamp, reasoning, and completionId
plantimestamp, snapshot, changes, displayText, and action metadata
user_actiontimestamp and nested action with actor, action type, count, and permitted metadata

Message fields include id, cursor, inReplyToMessageId, bodyText, bodyHtml, subject, timestamp, channel, isOutbound, attachments, isPeer, peerAgent, peerLinkId, sourceKind, and sourceLabel. Many optional contact/source fields are nullable. Nested timeline payloads use camelCase even though REST envelope fields use snake_case.

Email subject is separate from body content; it is null for absent/blank subjects and non-email messages. Retained provider payloads resolve lowercase subject, then Subject, then a case-insensitive subject header; an explicit blank string takes precedence. Malformed multivalued subjects are unavailable rather than converted to text. New accepted email inputs retain their subject before timeline and security capture. Historical idempotency responses remain the original acceptance snapshot, even when current history has additional independently retained subject evidence.

Prefer bodyText for plain-text clients. Treat HTML and tool output as untrusted content when displaying it. Attachments can be visible before their bytes are available; see File security.

Step entries include their own id, cursor, timestamp, toolName, caption, parameters, result, and status. A step status such as complete is distinct from browser task status completed. Timeline events are not a list of independently addressable task/run objects.

Waiting for later events​

POST /api/v1/agents/{id}/events/wait/ is read-only and requires agents:read.

FieldBehavior
after_cursorOptional opaque boundary. Events exactly at this cursor are excluded.
timeout_secondsInteger 0–30, default 10
limitInteger 1–100, default 20
event_typesOptional array: message, steps, thinking, plan; omit or use an empty array to avoid a type filter
filtersOptional object described below

Both matched and timed-out calls return matched, timed_out, events, next_cursor, latest_cursor, and waited_seconds. Continue with latest_cursor, including after a timeout: the server may have advanced past events excluded by your filters. Omitting the initial cursor searches a recent timeline window and can match an older event; it does not mean "start listening now."

Supported filters are from_actor_type, from_agent_id, to_agent_id, message_id, peer_link_id, channel, status, and tool_name. Actor types are agent, human_user, external, and system. Inbound MCP messages are external; agent and peer messages are agent; steps, thinking, and plan events are system.

Message IDs and peer/channel filters apply to messages. status and tool_name apply to step events. message_id matches that exact message, not a reply to it. An ordinary outbound reply to a person has no to_agent_id. Use the channel actually used by the workflow: email for REST email messages, mcp for MCP replies.

Unknown request fields and unsupported filters return 400 on waits and debug traces. This is stricter than the model serializers used for ordinary agent/task updates. Allow your HTTP timeout to exceed the requested wait time. Save cursors durably and use bounded retries after transport failure.

Other collection shapes​

CollectionPagination
Agents, archived agents, browser agents, browser taskspage, page_size (default 10, maximum 100), with count, next, previous, results
MCP list_agentspage, page_size (default 20, maximum 100), with agents, total, has_next
/agents/{id}/web-tasks/limit (default 50, maximum 200) and optional task status; returns results, limit
Contacts, peer links, webhooks, pending actionsFeature-specific collection envelope; no page-number contract
SCIMstartIndex, count; see SCIM

Follow a page-number response's next URL until it is null. Do not send the same page_size or cursor conventions to every collection.

Application request correlation​

Use Application Requests for principal-owned request detail and explicitly linked response rows. Their revision/page cursors are separate from timeline event cursors. A timeline message_id still matches that exact message. Legacy timeline visibility and processing status remain agent-wide; new service credentials do not gain timeline or protected audit access from request admission.

Automatic events and recovery​

The gated GET /agents/{id}/events/ inventory is separate from the timeline/event-wait contract. Its per-agent sequence orders retained catch-up, not HTTP delivery. Automatic request/reply references require explicit application-request lineage and original submission-principal scope. A timeline cannot backfill missed automatic capture. Keep catch-up cursors and handle 410 event_cursor_expired through authorized request reconciliation. See webhook operations and deployment limits.

Typed application results are separate encrypted request artifacts. Timeline chat replies retain their existing semantics and cannot establish validated fulfillment. Request revisions and automatic agent.request.updated envelopes add only safe result status/schema hashes/opaque artifact references; retrieve native content through the principal-scoped result route. Candidate values are excluded from persisted tool parameters. See structured results.