KEY TAKEAWAYS
- Choose streaming for an open connection, push for a reachable webhook receiver, or GetTask polling when neither is possible. Streaming and push require separately advertised capabilities.[3]
- A supported SubscribeToTask starts with the current Task. Use that baseline after a disconnect, rather than assuming every missed artifact chunk will be replayed.[3]
- The client decides which complete artifact version is acceptable.[2][8] Task completion, webhook acknowledgment and lastChunk are not that acceptance decision.[2][3]
Choose the update path your client can sustain
Suppose another agent is generating a report for you. Your application has received part of the document when its connection ends. Before commissioning the report again, observe the existing task and recover the output you intend to use. This scenario is hypothetical, not a client we tested. A2A documents polling, streaming and push as ways to follow work; the client still needs to check the document.[3]
Agent2Agent (A2A) separates a Message, a communication turn, from a Task, a record of work, and an Artifact, an output composed of Parts such as text or file references.[3] Here, the client is the application requesting and receiving that work. A send can return a direct Message instead of a Task; a message-only stream closes after that response and supplies no task tracking.[3] Establish which result you received before choosing a follow-up path.
| Your connection | Documented update path | Confirm in the implementation |
|---|---|---|
| Can keep an HTTP connection open; needs incremental output | SendStreamingMessage with capabilities.streaming; SubscribeToTask for an existing non-terminal task.[3] | Interface/version, disconnect handling and how to combine a current snapshot with later updates. |
| Cannot stay connected; can receive webhook requests | Push with capabilities.pushNotifications; authenticate the notification, then typically read current state with GetTask.[1][3] | Receiver authentication, expected task ID, retry bounds and a fallback for missed delivery. |
| Cannot keep a stream or receive a webhook; or needs only occasional status | Poll GetTask. This read needs no streaming/push capability.[3] | Permitted request frequency, rate limits and continued access to artifacts. |
A webhook is an HTTP request the remote agent sends to a receiver your client operates. If you cannot expose that receiver or maintain a stream, consider GetTask polling. Use the implementation's permitted request frequency; these documents do not give this workload a universal polling interval.[1][3]
For a non-streaming task send, the specific SendMessageConfiguration rule and pinned proto define a blocking default: wait until a terminal or interrupted state.[3][5] Setting returnImmediately: true requests nonblocking task return and later observation.[3][5] General operation prose elsewhere says sends return immediately, so we follow the more specific configuration rule rather than promise an immediate handle for every send.[3] This setting does not change a direct Message response or streaming operation.[3]
Reconnect to current work, not an assumed event history
GetTask returns the current Task status and artifacts, with optional message history.[3] historyLength limits recent messages, not a log of all streaming events.[3] SubscribeToTask is available for a non-terminal task on a streaming-capable interface and MUST begin with a Task representing its current state.[3] That snapshot is the current record; a delta is a later incremental update. Starting from the snapshot addresses the gap between a read and a subscription without promising replay of every missed update.
The specification requires streaming events to retain generation order and says the task lifecycle is independent of an individual stream.[3] An ended connection therefore cannot establish whether the task completed, paused or failed. Our recommended recovery starts with current state and an artifact baseline, not a blind append to the partial buffer left before disconnection.
The overview says streams close at interrupted as well as terminal states.[1] The normative operation sections require terminal-state closure and permit non-terminal subscription; they do not establish interrupted-state closure as a universal MUST.[3][6] Preserve that difference when diagnosing an input request. If the task becomes terminal before a subscription succeeds, SubscribeToTask returns UnsupportedOperationError; use GetTask to reconcile the final state instead of resending the job.[3]
A notification is an update, not an acceptance receipt
A v1.0 StreamResponse contains exactly one payload member: task, message, statusUpdate or artifactUpdate.[3][5] In JSON-RPC SSE, that wrapper appears inside the response result; the webhook body is a bare StreamResponse.[3] The overview’s reference to a SendStreamingMessageResponse does not replace that normative payload shape.[1][3] A client must interpret the selected binding rather than reuse one envelope everywhere.
Identity also depends on the payload: a Task carries id; status and artifact updates carry taskId and contextId.[3][5] GetTask and SubscribeToTask requests use id, plus tenant when required by the selected AgentInterface.[3][5] A Message can omit taskId.[5] Do not manufacture a task lookup for a message-only response.
The receiver MUST validate webhook authenticity, and the specific payload section requires the task ID to match an expected task.[3] It also requires HTTP 2xx to acknowledge successful receipt and recommends idempotent processing because duplicates may occur.[3] For the client, idempotent handling means a repeated notification does not apply the same update twice. The acknowledgment means the notification was received, not that the report is correct or accepted. The overview describes authenticated notification followed by GetTask as typical behavior, not a universal MUST to fetch after every event.[1]
The server MUST attempt delivery at least once per configured webhook; an attempt is not guaranteed receipt.[3] Section 4.3.3 makes retries MAY, while security section 13.2 says SHOULD, and both permit stopping after configured consecutive failures.[3][6] We established no universal retry duration, durable retention or exactly-once processing guarantee. Replay and webhook-URL/SSRF guidance exists, but does not prove deployed controls or give every event a unique deduplication ID.[1][3]
Assemble the artifact, then decide whether to accept it
TaskArtifactUpdateEvent.append: true means append to a previously sent artifact with the same ID; lastChunk: true marks the final chunk of that artifact.[3][5] Neither establishes receipt of earlier chunks, completion of the whole task, or acceptable document content. Artifact IDs are unique within a task, so use the task/artifact pair rather than the filename alone.[3][5] The true-case append rule is not a complete replacement or revision protocol for false or unset append.
A current Task snapshot and an artifact delta are different assembly inputs. We recommend using the snapshot as the current baseline, rather than concatenating it to an old incomplete buffer. Follow the implementation's rules for combining snapshots and later updates and handling duplicates. If Parts reference a file, obtain that file through its established access path before evaluating it. If complete content cannot be obtained, hold acceptance; lastChunk cannot supply the missing text.
TASK_STATE_INPUT_REQUIRED and TASK_STATE_AUTH_REQUIRED are interrupted states, not terminal ones.[5] Handle the requested input or authentication through the established continuation path for that task/context. TASK_STATE_COMPLETED, TASK_STATE_FAILED, TASK_STATE_CANCELED and TASK_STATE_REJECTED are terminal states; a terminal task cannot accept further messages or restart.[2][3][5] A refinement begins another interaction in the same context, optionally referencing the prior task; it may yield a new Task or a direct Message.[2]
The lifecycle guide leaves artifact linkage and the choice of acceptable versions to the client, outside the protocol specification.[2][8] A consistent artifact name can help relate refinements, but it is not a version counter.[2] We propose a client acceptance record that identifies the task/artifact pair, retains the exact checked content or its locally computed digest, records the checks and links the result to the prior accepted version. These are application records, not A2A guarantees. A digest identifies content; it does not prove that the content meets your requirements.
A usable reconciliation procedure
The following is our client-side procedure, derived from the documents rather than exercised against a service. It adds an acceptance decision without treating the transport as an approval system.
- 1. Establish the selected Agent Card interface, protocol version and optional update capability. For an ongoing non-streaming task, resolve returnImmediately behavior with that implementation; distinguish a direct Message from a trackable Task.[3][5]
- 2. Save the returned Task.id and contextId with the intended output and acceptance criteria. Bind artifact identity to the task as well as artifactId; keep a partial document provisional.[3][5]
- 3. Observe through the supported path. For push, authenticate and correlate the payload before application handling; keep receipt acknowledgment separate from acceptance.[1][3]
- 4. After a disconnect or significant notification, read current GetTask state or use a supported subscription’s initial Task baseline. Inspect status and current artifacts; do not infer task state from connection closure or assume an all-event replay.[3]
- 5. Reconcile the exact artifact against the current baseline and the implementation's assembly rules. Obtain complete Parts or referenced content and check the intended output requirements. If content is missing, duplicate handling is unresolved or checks fail, hold acceptance.
- 6. If interrupted, satisfy the stated input/authentication requirement through the existing continuation path. If terminal, inspect the outcome and available output against your criteria; failed, canceled or rejected does not count as successful delivery. A refinement is another interaction in the same context, not a restart of the terminal task.[2][3][5]
- 7. Record which checked artifact version the client accepts and link refinements to the previous accepted output. Keep the earlier accepted version until a replacement passes the checks. If observation is inaccessible, record the gap and responsible owner instead of silently repeating consequential work.
GetTask being an idempotent read does not make a new SendMessage an idempotent execution. The specification says Send Message MAY be idempotent and messageId may detect duplicates.[3] A missing or inaccessible task record is not proof that the original work never ran.[3] Any repeat-work decision with material effects needs the chosen implementation’s actual outcome and duplicate-prevention contract.
Worked example: a disconnected report and an accepted revision
Hypothetical, completed decision example—not an experiment. All IDs, observations, documents and client version labels below are fictional. Assume a v1.0 implementation with advertised streaming, documented snapshot/delta handling and accessible complete current artifacts. The requested report must include a findings section, supporting source references and a conclusion; a human checks those requirements and the conclusion’s consistency with the findings. No service or content check was actually run.
| Moment | Hypothetical observation | Client decision |
|---|---|---|
| Start | Task.id T-doc-41, contextId C-report and artifactId A-report are returned for report.txt. | Save the task/context and report criteria; accept no output yet. |
| Partial output; disconnect | Only the first chunk of A-report is in the client’s buffer when the connection ends. | Mark the buffer incomplete. Do not resubmit the report request or accept that buffer. |
| Reconnect while working | SubscribeToTask for T-doc-41 begins with the current Task. | Use the current A-report snapshot as the baseline under the assumed assembly rules. Do not append it to the old partial buffer or assume missed chunks were replayed. |
| Complete report obtained | GetTask for T-doc-41 shows TASK_STATE_COMPLETED. The complete A-report content is accessible and passes all stated checks. | Accept T-doc-41 / A-report as client v1 and retain the exact checked content. Missing content or failed checks would keep acceptance on hold. |
| Refinement completed | A revised conclusion is requested in C-report, referencing T-doc-41. New task T-doc-42 returns artifact A-report-revised, also named report.txt; its complete content passes the checks. | Retain v1 until the new checks pass; then accept T-doc-42 / A-report-revised as v2, linked to v1. Do not restart T-doc-41 or choose by filename. |
A delayed completed notification for T-doc-41 arriving after v2 was accepted would not make v1 current again. Our proposed client record would correlate that notification to the earlier task and preserve v2 as the accepted successor. Authentication can establish the sender; it cannot decide which report version the reader should use.
Implementation evidence and source limits
An implementation may provide stronger event retention, replay, retry/duplicate controls, artifact storage or a separate acceptance service. If its documented guarantees fit the workload, those features may simplify our proposed reconciliation steps. Asynchronous work alone is not a reason to build new infrastructure. Seek evidence for the exact interface/version, retrieval lifetime and access, reconnect snapshot/delta behavior, retry bounds, duplicate handling and the client’s acceptance/version policy. Authorized observations could then test unresolved behavior; none were performed here.
This is a comparison of complementary official documents from one A2A publisher family, not independent implementation corroboration or a statistical sample. No reliability, latency, security effectiveness, restart survival, cost saving, adoption or business impact was measured. The references do not establish all-event replay, exactly-once effects, compensation or business acceptance for any deployed client.
Source identity matters: the captured website labels the specification “Latest Released Version 1.0.0,” while the repository latest-release API returned v1.0.1, published 28 May 2026.[3][9] We discuss protocol 1.0 because the specification uses Major.Minor for compatibility and excludes patch numbers from version negotiation.[3] Repository definitions and supporting prose were pinned to commit 12e9d2fbb9badfe98f8ab4f660697870eeb1940b.[5][6][7] Matching selected passages does not establish the website’s complete deployed commit. Page editorial publication/update dates were not verified; retrieval and hosting timestamps are not rollout dates.
We also found binding details that prevent a universal copy-and-run recipe: the specification’s REST SubscribeToTask mapping says POST while the pinned proto annotation says GET.[3][5] The prose names spec/a2a.proto, but the pinned repository file is specification/a2a.proto.[3][5] The v1.0 migration guide removes TaskStatusUpdateEvent.final; artifact lastChunk remains a different field.[4][5] This article preserves current operation names and separates payload from transport; resolve the chosen interface’s concrete request shape before implementation. It is not a validated adapter or a repaired copy of duplicated extraction examples.
Sources & scope
Documentary synthesis checked 9 October 2026 KST, covering A2A protocol 1.0 operations, lifecycle guidance and proto definitions pinned to repository commit 12e9d2fbb9badfe98f8ab4f660697870eeb1940b. No client, server, webhook, security or recovery experiment was run. The worked document job is hypothetical and unexecuted; client version labels and acceptance records are proposals, not protocol fields.
- A2A: Streaming and asynchronous operations ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation.
- A2A: Life of a task ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation.
- A2A protocol specification: captured latest edition ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation. Captured website label: Latest Released Version 1.0.0; protocol compatibility version 1.0.
- A2A: What is new in v1.0 ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation.
- A2A proto definitions: pinned revision ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation. Pinned to commit 12e9d2fbb9badfe98f8ab4f660697870eeb1940b; commit identity is not a page rollout date.
- A2A specification prose: pinned revision ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation. Pinned to commit 12e9d2fbb9badfe98f8ab4f660697870eeb1940b; commit identity is not a page rollout date.
- A2A streaming guide: pinned revision ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation. Pinned to commit 12e9d2fbb9badfe98f8ab4f660697870eeb1940b; commit identity is not a page rollout date.
- A2A lifecycle guide: pinned revision ↗
Official primary source, retrieved 9 October 2026 KST; editorial page publication/update date not verified. One publisher family; no runtime validation. Pinned to commit 12e9d2fbb9badfe98f8ab4f660697870eeb1940b; commit identity is not a page rollout date.
- Official A2A repository: latest-release API observation ↗
Official API response retrieved 9 October 2026 KST: tag v1.0.1, published_at 2026-05-28T11:34:36Z. Repository release timestamp, not a verified website update or implementation rollout.
Publication history
- — Initial documentary synthesis edited for client terminology, connectivity choice, artifact reconciliation and a completed hypothetical acceptance example. Prepared edition; publication requires separate activation and readback evidence.
Have a correction or a different perspective? Contact Palanthos.