A2A Message: Roles, Fields, and When to Use It

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

FieldRequiredDescription
messageIdYesUnique identifier, created by whoever creates the message
roleYesWho sent it: ROLE_USER (client to server) or ROLE_AGENT (server to client)
partsYesThe message content, as a list of Parts
contextIdNoAssociates the message with a conversation context
taskIdNoAssociates the message with a Task
referenceTaskIdsNoIDs of other tasks this message refers to for additional context
metadataNoAny extra key-value metadata
extensionsNoURIs 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 a taskId only if a task was created.
  • Messages from the client may carry both, either, or neither. If both are given they must match, meaning the contextId has to be the one set on the task. If only taskId is given, the server infers contextId from it.
  • messageId is created by the sender. Agents can use it to detect duplicate messages, so SendMessage can be made idempotent.
  • referenceTaskIds is 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: the taskId does 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