A2A Message: Roles, Fields, and When to Use It
A Message is one unit of communication between a client and a server. It has a sender role and one or more Parts that carry the content. It can belong to a conversation context, to a task, or to both.
Fields
| Field | Required | Description |
|---|---|---|
messageId | Yes | Unique identifier, created by whoever creates the message |
role | Yes | Who sent it: ROLE_USER (client to server) or ROLE_AGENT (server to client) |
parts | Yes | The message content, as a list of Parts |
contextId | No | Associates the message with a conversation context |
taskId | No | Associates the message with a Task |
referenceTaskIds | No | IDs of other tasks this message refers to for additional context |
metadata | No | Any extra key-value metadata |
extensions | No | URIs of extensions present in or contributed to this message |
In JSON, role is written with the enum names ROLE_USER and ROLE_AGENT, as in every example on this page.
How the IDs relate
- Messages from the server must carry a
contextId, and ataskIdonly if a task was created. - Messages from the client may carry both, either, or neither. If both are given they must match, meaning the
contextIdhas to be the one set on the task. If onlytaskIdis given, the server inferscontextIdfrom it. messageIdis created by the sender. Agents can use it to detect duplicate messages, soSendMessagecan be made idempotent.referenceTaskIdsis how a client points a follow-up at earlier work. Clients SHOULD use it to reference related tasks explicitly, and agents SHOULD use those tasks to understand the intent of the follow-up.
Sending a message
The first message of a conversation needs only a role, parts, and a messageId. This is the request from the specification’s basic scenario:
POST /message:send HTTP/1.1
Host: agent.example.com
Content-Type: application/a2a+json
Authorization: Bearer token
{
"message": {
"role": "ROLE_USER",
"parts": [{"text": "What is the weather today?"}],
"messageId": "msg-uuid"
}
}The agent then chooses its answer. It MAY create a task to process the message, or MAY return a direct Message for simple interactions. With streaming, a direct answer is a stream that contains exactly one Message and then closes.
Following up on earlier work
A refinement is a new message in the same contextId that references the earlier task. This is the follow-up from Life of a Task
, shown here as the bare message with role written as the protocol enum value:
{
"role": "ROLE_USER",
"messageId": "msg-user-002",
"contextId": "ctx-conversation-abc",
"referenceTaskIds": [
"task-boat-gen-123"
],
"parts": [
{
"text": "Please modify the sailboat to be red."
}
]
}To answer a question the agent asked, the client instead sends the message with the taskId of the paused task. That exchange is shown on the Task
page.
What messages are for
The specification gives messages four jobs:
- Task initiation: clients send messages to start new tasks.
- Clarification: an agent can send a message back to ask for clarification before it starts a task.
- Status messages: agents attach a message to a status update to report progress, ask for input, or share information.
- Task interaction: clients send messages to provide more input or instructions for a running task.
Messages are not meant to deliver results. The specification says messages SHOULD NOT be used to deliver task outputs, and that results SHOULD be returned as Artifacts on a task. Communication goes in messages, and data output goes in artifacts.
Messages and task history
A task’s history holds the messages exchanged while it ran, but not every message is guaranteed to be stored. Transient informational messages may not be kept, and messages exchanged before the task was created may not be stored either. The agent decides what to persist. Clients using streaming can also miss status messages if they disconnect and reconnect, so messages MUST NOT be treated as a reliable delivery mechanism for critical information.
Errors to expect
ContentTypeNotSupportedError: a media type used in one of the message’s parts is not supported by the agent.TaskNotFoundError: thetaskIddoes not exist or is not accessible.UnsupportedOperationError: the message was sent to a task that is already in a terminal state.
Related pages
- Part
: what goes inside
parts. - Task : how messages move a task through its states.
- Task Runtime Guide : choosing between a Message and a Task, and what each state accepts; A2A Error Codes : the A2A-specific errors each operation returns.
- Data Structures : the complete field reference.
Source: A2A official specification: Message, Multi-Turn Interactions, and Messages and Artifacts