Skip to main content
This guide shows you how to stream agent responses in real time using Server-Sent Events (SSE). You will learn about the two streaming endpoints, the SSE event format, and how to resume interrupted streams.

Prerequisites

When to stream

Use streaming when you need real-time updates as the agent processes a message:
  • Showing incremental progress to users
  • Displaying partial results as they arrive
  • Monitoring long-running tasks
For simple request/response interactions, use message:send instead.

Stream a new message

Use message:stream to send a message and receive the response as an SSE stream:
The -N flag disables cURL’s output buffering, which is necessary for receiving SSE events in real time.

SSE event format

Each event follows the W3C SSE wire format. The server currently sends only id and data lines. The event and retry fields are declared for forward compatibility but are not sent:

Event types

Each SSE event carries an A2AStreamResponse with exactly one field:

Subscribe to an existing task

If you have a task ID (from a non-blocking message:send or after a stream dropped), use tasks:subscribe to stream updates:

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.
If an SSE stream drops, 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 the feature is implemented. This will work with both message:stream and tasks:subscribe.

Cancel a task

Cancel an in-flight task:
The task transitions to TASK_STATE_CANCELED.

JSON-RPC streaming binding

You can also stream via the JSON-RPC binding by sending a message/stream method to the base A2A endpoint:
The SSE events carry JSON-RPC response envelopes instead of raw A2AStreamResponse objects.

Next steps