Skip to main content
Send a message and wait for the run to reach a terminal state or an interrupt.
The method name is SendMessage in the JSON-RPC envelope. There is no /message/send path and no message/send method name.

Request

params

message

Parts

A part is a field-presence union — exactly one content key, plus optional filename, mediaType, and metadata.
There is no file part on the wire. A file attachment lowers to raw (inline bytes) or url, with filename and mediaType set alongside it.
Inbound file parts are fetched through the platform’s outbound egress policy. Attachments are capped at 20 MiB per file and images at 4096 × 4096.

Response

The result is a field-presence union of exactly one key.
Which one you get depends on what the run did. A run that called a tool, handed off to another agent, or emitted an A2UI surface commits to Task mode and returns a task — a tool call is not the only thing that commits. Only a bare prose reply with none of those returns a message with no task transition. Write your client to handle both.

Interrupts

When the run reaches TASK_STATE_INPUT_REQUIRED, SendMessage stops draining and returns the persisted task snapshot rather than hanging until the stream closes. TASK_STATE_AUTH_REQUIRED is a real state on the wire, but no production path constructs it today — in practice this interrupt is always INPUT_REQUIRED. For an approval gate, resume with a follow-up SendMessage carrying a noorle.gate_decision data part and both taskId and contextId. Only user callers may resolve a gate over A2A. See A2A overview.

Errors

Returned with HTTP 200 and the error in the JSON-RPC envelope. Truly malformed JSON (not valid JSON at all) is rejected before it reaches this handler, typically as an HTTP 422. Reusing a taskId that already exists fails with -32600 (invalid_request) rather than overwriting the existing task.