Tasks, messages, and artifacts
Lesson 3 of 5 in A2A and Agent Interop — Honestly Sized.
The Agent Card gets you an introduction. The Task is the actual contract.
A task is a stateful unit of work with a server-generated id, optionally grouped with related tasks by a contextId. That one design choice — the server owns the id and the state — is what separates A2A from a tool call. A tool call is a request whose result you await. A task is a record you can come back to: query it later, cancel it, subscribe to it, resume it after your own process restarts.
The core operations follow from that: SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, SubscribeToTask, plus CRUD for push-notification configuration.
A2A task lifecycle (spec 1.0 states)
- SUBMITTED
The client sent work; the server minted a task id. Nothing has necessarily started yet.
- WORKING
The remote agent is executing. Progress reaches you by polling, streaming, or webhook — your choice, constrained by its advertised capabilities.
- INPUT_REQUIRED
Interrupted, not failed: the agent needs a clarification or a decision. Your client must be able to answer later — possibly after a restart.
- AUTH_REQUIRED
The task needs a credential mid-flight. The spec defines an in-task authorization mechanism for exactly this.
- COMPLETED
Terminal. Outputs are attached to the task as artifacts.
- FAILED
Terminal. The agent tried and could not finish — distinct from refusing the work.
- CANCELED
Terminal, via CancelTask. Long-running work needs a stop button, and this is it.
- REJECTED
Terminal. The agent declined the task outright — out of scope, over policy, not permitted.
Inside a task, two different things travel — and conflating them is the most common A2A modelling mistake.
A Message is one communication turn, with a role of ROLE_USER or ROLE_AGENT, built from Parts that may be text, files, or structured data. Messages are for initiating work, asking clarifying questions, and status chatter. An Artifact is an output, attached to the task. The spec is explicit that messages “SHOULD NOT be used to deliver task outputs.”
The reason is operational, not aesthetic. Artifacts are addressable results attached to a durable record: fetchable later, referenceable by id, gradeable by your evals. A deliverable smuggled inside conversational text is only recoverable by parsing a transcript — which is precisely the brittleness structured outputs exist to eliminate.
| Element | What it is | Use it for | Do not use it for |
|---|---|---|---|
Message | One turn, role | Kicking off the task, clarifying questions, answering an | Shipping the deliverable — the spec says messages SHOULD NOT deliver task outputs. |
Artifact | An output attached to the Task. | The actual results: the reviewed contract, the generated report, the reconciliation file. | Chatty progress narration; artifacts are results, not commentary. |
Task state | The lifecycle enum — terminal, interrupted, or in progress. | Deciding what your orchestrator does next: wait, answer, retry, escalate, give up. | Inferring semantics from prose. Branch on the state, never on the wording of a status message. |
Polling
Call GetTask (and ListTasks) on an interval. Always available, no server-side capability required, survives your process restarting. The cost is latency and wasted requests — but for a task that takes forty minutes, a thirty-second poll is not the bottleneck. Start here; it is the fallback everything else degrades to.
Streaming
SendStreamingMessage and SubscribeToTask, gated on capabilities.streaming. Best latency and the natural fit for interactive UIs. But a stream is a live connection: if your client dies mid-task, you need the polling path anyway to find out what happened. Treat streaming as an optimisation over a durable record, never as the record.
Push notifications
Webhooks, gated on capabilities.pushNotifications, configured through the push-notification config operations. The right choice for hour-long work where holding a connection is silly. It also drags in real webhook engineering: a reachable authenticated endpoint, replay and duplicate handling, and the assumption that any inbound payload is untrusted until you verify it.
Tool: Protocol Picker — Practise the vertical/horizontal call on your own integrations — tool, task, or neither — in the Protocol Picker.
Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.