Protocol Overview

The Agent2Agent (A2A) protocol defines how AI agents discover each other, exchange messages, manage task lifecycles, and stream results. This page covers the conceptual model — the "what" before the "how."

The Big Picture

An A2A interaction follows this flow:

  Client Agent                Agent (Server)
       │                           │
       │  1. GET /.well-known/agent-card.json │
       │ ─────────────────────────►│
       │          AgentCard        │
       │ ◄─────────────────────────│
       │                           │
       │  2. SendMessage           │
       │ ─────────────────────────►│
       │     Task (or SSE stream)  │
       │ ◄─────────────────────────│
       │                           │
       │  3. GetTask               │
       │ ─────────────────────────►│
       │          Task             │
       │ ◄─────────────────────────│
       │                           │
  1. Discovery — The client fetches the agent's card from /.well-known/agent-card.json
  2. Communication — The client sends a message and receives results
  3. Management — The client can query, cancel, or subscribe to tasks

Core Entities

Tasks

A Task is the central unit of work. When a client sends a message, the server creates a task that progresses through well-defined states:

                      ┌───────────┐
              ┌───────│ Submitted │──────────┐
              │       └─────┬─────┘          │
              │             │                │
              ▼             ▼                ▼
         ┌────────┐   ┌────────┐   ┌──────────┐  ┌──────────┐
    ┌───►│Working │   │Failed *│   │Rejected *│  │Canceled *│
    │    └───┬────┘   └────────┘   └──────────┘  └──────────┘
    │        │                           ▲             ▲
    │   ┌────┼───────────┬───────────┐   │             │
    │   │    │           │           │   │             │
    │   ▼    ▼           ▼           ▼   │             │
    │ ┌───────────┐ ┌─────────┐ ┌──────────┐          │
    │ │Completed *│ │ Input   │ │  Auth    │          │
    │ └───────────┘ │Required │ │ Required │──────────┘
    │               └────┬────┘ └────┬─────┘
    │                    │           │
    └────────────────────┴───────────┘

    * = terminal state (no further transitions)

    The arrows show the usual paths, not the only valid ones.
    Valid transitions (the only two rules enforced):
    1. Terminal states (Completed, Failed, Canceled, Rejected) are final.
    2. Nothing transitions into Submitted.
    Everything else is allowed, e.g. Submitted → Completed,
    Working → Working (repeated Working updates carry progress messages).

Terminal states (Completed, Failed, Canceled, Rejected) are final — no further transitions are allowed.

Messages

A Message is a structured payload sent between agents. Each message has:

  • A unique ID (MessageId)
  • A role — User (from the client) or Agent (from the server)
  • One or more Parts — the actual content

Parts

A Part is a content unit within a message. Four content types are supported:

TypeDescriptionExample
TextPlain text"Summarize this document"
RawInline base64-encoded bytesImage data, binary content
UrlURI reference"https://example.com/doc.pdf"
DataStructured JSON{"table": [...], "columns": [...]}

Artifacts

An Artifact is a result produced by an agent. Like messages, artifacts contain parts. Unlike messages, artifacts belong to a task and can be delivered incrementally via streaming.

Agent Cards

An Agent Card is the discovery document that describes an agent — its name, capabilities, skills, and how to connect. Think of it as a machine-readable business card.

Request/Response Model

A2A supports two communication styles:

Synchronous (SendMessage)

The client sends a message and blocks until the task reaches a terminal or interrupted (InputRequired, AuthRequired) state:

  Client                        Server
     │                             │
     │  SendMessage                │
     │ ───────────────────────────►│
     │                    Executor runs,
     │                    collects events
     │            Task             │
     │ ◄───────────────────────────│
     │                             │

Streaming (SendStreamingMessage)

The client sends a message and receives events in real time (via SSE on the HTTP bindings):

  Client                        Server
     │                             │
     │  SendStreamingMessage       │
     │ ───────────────────────────►│
     │    Task (snapshot)          │
     │ ◄───────────────────────────│
     │    StatusUpdate: Working    │
     │ ◄───────────────────────────│
     │    ArtifactUpdate           │
     │ ◄───────────────────────────│
     │    ArtifactUpdate           │
     │ ◄───────────────────────────│
     │    StatusUpdate: Completed  │
     │ ◄───────────────────────────│
     │                             │

Streaming is ideal for long-running tasks where the client wants progress updates.

Contexts and Conversations

Tasks exist within a Context — a conversation thread. Multiple tasks can share the same context, allowing agents to maintain conversational state across interactions.

When a client sends a message with a context_id, the server groups that task with previous tasks in the same context. If no context_id is provided, the server creates a new one.

Multi-Tenancy

A2A supports multi-tenancy via an optional tenant field on all requests. This allows a single agent server to serve multiple isolated tenants, each with their own tasks and configurations. A client must send the tenant its selected AgentInterface declares on every request (spec §8.3.2 rule 4); ClientBuilder::from_card does this for all eleven methods.

In the REST transport the client sends the tenant as the leading path segment, /{tenant}/tasks/..., and the server also accepts ?tenant= on GET/DELETE and the body field on POST. See Transport Layers.

Next Steps