In Part 2, we discovered that A2A’s object model centres on the “nouns” Agent Card, Task, Message, Part, and Artifact. A client sends messages; the remote agent responds with an immediate Message or a stateful Task. Artifacts — the durable outputs — live on the Task, not as a separate top-level response type.
This post covers the “verbs”: how agents find each other, how work flows at runtime, and the confusions that surfaced when I first read the specification (but are hopefully clarified by the end of this blog). These runtime patterns allow agents to discover each other, delegate work, track long-running operations, and exchange results across distributed systems. (Note: Part 4 will add sequence and state diagrams plus concrete request/response traces.)
By the end of this post, you’ll understand the core runtime flow behind the A2A protocol and how it supports scalable agent communication architectures that can be combined with technologies such as Apache Kafka.
Here’s an introductory diagram showing A2A runtime flow: you discover an agent via its Agent Card, call SendMessage, receive an instant Message or a long-running Task, and then track the Task by polling, SSE streaming, or push webhook.

Diagram showing A2A runtime: Agent Card discovery, SendMessage branching to Message or Task, and three update paths for tasks — GetTask polling, SSE streaming, and webhook push notifications.
A2A runtime Interaction mechanisms
A2A supports three patterns for short and long-running work. All map to the same core operations (SendMessage, GetTask, CancelTask, and others) but differ in how updates reach the client. See the streaming and async topic for normative detail.
1. Request/response and polling
The simplest path: the client sends a message and receives either:
- an immediate Message (stateless, complete in one step), or
- a Task (stateful, long-running)
For long-running operations (LROs), the client polls GetTask to retrieve status, history, and artifacts until the task reaches a terminal state. Polling is always available as a baseline; it is straightforward but can be chatty at scale.
2. Streaming (Server-Sent Events)
For real-time progress, A2A uses Server-Sent Events (SSE) — a long-lived HTTP response where the server pushes incremental updates to the client.
Key points:
- SSE is unidirectional (server → client). The client still sends work via normal A2A requests such as
SendMessage. SendStreamingMessagestreams updates for a message-level interaction.SubscribeToTasklets a client re-attach to an in-flight task after a connection drop — the server replays missed events where possible.
A stream emits a StreamResponse that is exactly one of: task, message, statusUpdate, or artifactUpdate — so messages, status, and artifact chunks can all appear on the same stream.
SSE runs over standard HTTP/1.1 or HTTP/2, which makes it proxy- and firewall-friendly compared with bespoke WebSocket setups. For background on the mechanism, see MDN’s SSE guide.
3. Push notifications
For disconnected clients or LROs where polling and streaming are impractical, the server can send asynchronous notifications to a client-configured webhook (a Push Notification Service).
- The client registers a config via
CreateTaskPushNotificationConfig(and related list/get/delete operations). - When task state changes, the server POSTs to the webhook.
- The client then calls
GetTaskto fetch the full updated state.
Push in A2A is server → client only. There is no spec-defined client-to-server push, so there is no spec-defined symmetric asynchronous notification channel in both directions.
Agent discovery with agent cards
Agent Cards are the discovery and trust layer. Before any task is sent, a client needs to answer: Who is this agent? What can it do? How do I authenticate? Which transport should I use?
Discovery strategies defined in the agent discovery documentation include:
- Well-Known URI (recommended for broad discovery) – Fetch
https://{agent-domain}/.well-known/agent-card.json(RFC 8615). - Curated registries – Enterprise directories or marketplaces where agents publish cards and clients search by skill, tag, or provider. The spec does not yet standardise a registry API.
- Direct configuration – The client is pre-configured with an Agent Card URL or JSON — common in development and tightly coupled deployments.
An Agent Card is JSON with a schema defined in the specification. Typical fields include identity, service URL, capabilities (streaming, push notifications), authentication schemes, skills, and supportedInterfaces (URL + protocolBinding + protocol version for each transport).
Agent Cards can contain sensitive information (internal URLs, restricted skills). The spec recommends protecting card endpoints with authentication, network controls, or selective disclosure via registries — and using dynamic credentials rather than embedding static secrets in the card.
Cards change infrequently (new skills, auth updates). Standard HTTP caching (Cache-Control, ETag) applies; clients should honour conditional requests rather than re-fetching on every call.
Understanding the A2A task lifecycle
When a remote agent receives a message, it has two fundamental response paths:
Immediate message
For short, self-contained interactions. The agent returns a Message and the exchange is complete. There’s no task state to track.
Stateful task
For work that takes time, requires multiple turns, or may need additional input. The agent returns a Task and executes it over a lifecycle: progress updates, streaming or push notifications, possible input-required pauses, and eventually a terminal state with artifacts.
This dual response model is central to A2A. Client code should treat “got a Message” and “got a Task” as equally normal branches of SendMessage, not as rare edge cases.
Implementers also choose agent personalities that affect what you see in the wild:
- Message-only agents – Always return messages; use
contextIdto tie turns together. - Task-only agents – Always return tasks, even for simple replies (modelled as already-completed tasks).
- Hybrid agents – Negotiate scope with messages, then commit to a task for tracked execution.
Once a task reaches a terminal state (completed, failed, canceled, rejected), it is immutable — follow-up work starts a new task, often in the same contextId with referenceTaskIds pointing at the prior task.
Understanding the full lifecycle — especially input-required loops and terminal state handling — gets tricky quickly. Part 4 will walk through sequence and state diagrams in more depth to make it concrete.
A2A protocol bindings and transport options
A2A separates what agents say from how it is transported. The specification defines three standard protocol bindings that map abstract operations to concrete transports:
| Binding | Notes |
|---|---|
| JSON-RPC 2.0 over HTTPS | Common default in SDKs and examples |
| gRPC | Unary and streaming RPC mappings |
| HTTP+JSON / REST | Resource-oriented endpoints; SSE for streaming operations |
Agents declare supported bindings in the Agent Card’s supportedInterfaces list. Clients parse entries in order of preference order and select the first binding they support. Custom bindings (WebSocket, MQTT, and others) are permitted under the project’s governance process — they change the transport, whereas extensions add behavior on top of an existing binding.
Deploying Agent2Agent services beyond the specification
I was surprised to find that agent deployment is not defined by A2A. The protocol standardizes the communication layer; how you host, scale, and secure agents is up to you. That said, a typical pattern looks like this:
- Wrap and expose – An existing agent is wrapped as an A2A-compatible server, often using a framework SDK or Agent Development Kit (ADK) that handles protocol details.
- Deploy as a network service – Commonly an HTTPS endpoint (a container, VM, or serverless function) with TLS and token-based authentication.
- Publish an Agent Card – Describing skills, capabilities, auth requirements, and supported interfaces.
- Discover and delegate – A client agent retrieves the card, sends a structured request, tracks the resulting task or message, and consumes artifacts.
In effect, A2A turns agents into loosely coupled distributed services that can discover each other, delegate work, and exchange results without a shared runtime or monolithic platform. Your choice of orchestrator, event backplane, and observability stack sits outside the protocol — which is where Kafka, workflow engines (E.g. Cadence), and gateway layers (E.g. MCP) enter the picture in later parts of this series.
Common Agent2Agent protocol questions and misconceptions
When I first read the A2A specification, several things did not make complete sense to me immediately. The protocol is defined — but it separates concerns in ways that differ from how many of us sketch agent systems on a whiteboard. The points below are the ones I had to reread to fully understand; they may save you the same round trip.
Where do artifacts appear in an A2A response?
SendMessage and SendStreamingMessage return a Messageor aTask — not a bare Artifact at the top level. Artifacts live inside the Task (and can arrive incrementally via TaskArtifactUpdateEvent on a stream). A completed task response includes an artifacts array; during working, that array may still be empty. Think of it as: Message/Task = response envelope; Artifact = deliverable payload on a task.
Is there a separate authentication or deployment step in the protocol?
Not as distinct lifecycle phases. Authentication schemes are declared on the Agent Card; the client applies them on every request. Deployment is outside the normative spec — see the section above.
User vs Client Agent — who speaks A2A?
The User (human or automated service) initiates the goal. The Client Agent speaks the A2A protocol on their behalf. The User is a first-class concept in the interaction model but is not an A2A wire endpoint.
Can messages be streamed, or only artifacts?
Both can appear on a stream via SendStreamingMessage. The distinction between messages and artifacts is semantic (coordination vs durable work product), not “messages never stream.” Artifacts additionally support chunked delivery (append, lastChunk on artifact update events).
How many artifacts can a task produce?
A task carries an artifacts array — zero or more over its lifetime. Each artifact must contain at least one part. Multiple artifacts per task are normal (e.g. a report plus a chart).
Client-to-server push notifications?
No. Push is server → client only, via webhook to a client-configured Push Notification Service.
Is there a “subscribe to an agent” model?
Not in the base protocol. Work is client-initiated. You can approximate a standing subscription with a long-running task that rarely completes and streams artifact parts over time, but that is a pattern, not first-class pub/sub. Fan-out event feeds fit an event backbone like Kafka better than they fit A2A natively.
How does the protocol extend without forking?
Through Extensions (URI-identified capabilities on the Agent Card) and custom protocol bindings (alternative transports). See also the bindings section above.
How are errors handled?
The spec defines error categories (authentication, authorization, validation, not found, system) and A2A-specific types such as ContentTypeNotSupportedError and VersionNotSupportedError, mapped per binding to HTTP status codes, JSON-RPC errors, or gRPC status.
Key takeaways from the Agent2Agent runtime model
At runtime, A2A orchestrates work through a small set of patterns:
- Discover via Agent Card (well-known URI, registry, or direct config)
- Send via
SendMessageand expect Message or Task in response - Track long-running work via polling (
GetTask), streaming (SendStreamingMessage,SubscribeToTask), or push webhooks - Consume artifacts from the completed task
The Agent2Agent protocol complements MCP (tools) rather than replacing it, and it standardizes the agent conversation layer — not deployment, agent fleet lifecycle, or your event backplane.
Check out the new Instaclustr MCP Gateway. More details are available here.
Next: Part 4 — diagrams for the object model, runtime sequence, and task lifecycle.