Skip to main content
A task is a stateful unit of work performed by an agent. When you send a message to an agent, the response is either a direct Message (for quick operations) or a Task (for longer-running work). Tasks have a defined lifecycle, can produce artifacts, and can be streamed in real time.

What is a task

A task represents work that an agent performs in response to a message. It has:
  • A unique prefixed UUIDv7 identifier (task.0192f4c8-...)
  • A contextId linking it to a context for conversation continuity
  • A status with a current state and timestamp
  • A history array of messages exchanged during the task
  • An artifacts array of outputs produced by the task
  • metadata including token and credit accounting under $usage
The agent decides whether to respond with a Task or a Message. Quick operations (short completions, classifications) often return a Message directly. Longer workflows return a Task that you monitor for completion.

Task states

A task moves through the following states:
TASK_STATE_REJECTED and TASK_STATE_AUTH_REQUIRED are only visible on the JSON-RPC binding. On the REST (HTTP+JSON) binding, both are mapped to TASK_STATE_FAILED with a descriptive status message.

Terminal vs non-terminal states

Canceling a task in a terminal state returns 409 Conflict.

State transitions

A task transitions through states as follows:
  • TASK_STATE_SUBMITTED to TASK_STATE_WORKING: The agent begins processing.
  • TASK_STATE_SUBMITTED to TASK_STATE_REJECTED: The task was rejected before processing (insufficient credits or invalid configuration).
  • TASK_STATE_SUBMITTED to TASK_STATE_AUTH_REQUIRED: An MCP connector requires authentication before the agent can proceed.
  • TASK_STATE_WORKING to TASK_STATE_COMPLETED: The task finishes successfully.
  • TASK_STATE_WORKING to TASK_STATE_FAILED: An error occurred during processing.
  • TASK_STATE_WORKING to TASK_STATE_INPUT_REQUIRED: The agent paused and needs user input.
  • TASK_STATE_WORKING to TASK_STATE_AUTH_REQUIRED: An MCP connector encountered an auth error during execution.
  • TASK_STATE_AUTH_REQUIRED to TASK_STATE_WORKING: Auth is resolved and the agent resumes.
  • TASK_STATE_INPUT_REQUIRED to TASK_STATE_WORKING: The user provides input and the agent resumes.
  • Any non-terminal state to TASK_STATE_CANCELED: The client cancels the task via tasks/{id}:cancel.
A task in TASK_STATE_INPUT_REQUIRED or TASK_STATE_AUTH_REQUIRED state is not terminated. Send a new message with the required input (for TASK_STATE_INPUT_REQUIRED) or resolve the connector authentication (for TASK_STATE_AUTH_REQUIRED) to resume processing. The SSE stream closes when either state is reached; you must send a new message or re-subscribe to continue receiving updates.

Task history and messages

The history array contains all messages exchanged during the task, oldest first. Each message has:
  • messageId: A prefixed UUIDv7 (e.g. msg.0192f4c8-...)
  • role: Either ROLE_USER (sent by the client) or ROLE_AGENT (sent by the agent)
  • parts: An ordered list of content parts (text, file, or data)
  • metadata: Free-form metadata, including Corti’s $timestamp for timing
You can control how much history the agent considers by setting configuration.historyLength on the message send request.

Artifacts

Artifacts are the tangible outputs a task produces. Each artifact has:
  • artifactId: A prefixed UUIDv7 (e.g. art.0192f4c8-...)
  • name: An optional human-readable name
  • parts: Content parts containing the artifact data
Artifacts are closely tied to the task lifecycle. In healthcare scenarios, artifacts typically correspond to business outputs like clinical notes, coding suggestions, or extracted facts. You can retrieve a specific artifact via:

Streaming events

When you stream a message via message:stream or subscribe to an existing task via tasks/{id}:subscribe, the server sends Server-Sent Events (SSE). Each event carries an A2AStreamResponse with exactly one of the following fields:

SSE event format

Each SSE frame follows the W3C SSE wire format:

Example SSE event

Resumption with Last-Event-ID

The server writes event IDs but does not yet read the Last-Event-ID request header, so resumption without gaps is not implemented. The section below describes the intended design for when this feature ships.
The intended resumption mechanism is to send the Last-Event-ID header with the most recent event ID you received. The server will replay events from that point forward once implemented. This will work with both message:stream and tasks/{id}:subscribe. See Stream responses for implementation details.

Task metadata and usage

Each task carries metadata with Corti’s first-party keys prefixed with $. The $usage object provides token and credit accounting:
You can use this data for cost tracking, budget monitoring, and evaluating cache effectiveness across your agents.

Next steps