Interrupted states: INPUT_REQUIRED and AUTH_REQUIRED
A task can stop and wait for you, and the two kinds of waiting are answered in different places: input on the task itself, authorization outside the protocol.
The planner sends code-reviewer a diff of payments-api and asks for a review. The reviewer cannot start, because it does not know which branch the diff is against. Later the planner asks deployer to deploy build 2026.10.06-1 to staging, and that task stops until an operator approves it.
Neither task has failed. When you finish this section, you can recognize an interrupted task, answer it in the right place, and detect the moment it resumes.
Two states that wait
Interrupted state: a state in which the agent has stopped work and needs something before it can continue. The proto marks exactly two states this way, TASK_STATE_INPUT_REQUIRED and TASK_STATE_AUTH_REQUIRED, and the proto marks each of them as interrupted.
An interrupted task keeps its id, history, and artifacts, and its status message says what the agent needs. A blocking SendMessage returns as soon as the task reaches either state. TASK_STATE_INPUT_REQUIRED needs an answer, sent as a new message on the same task. TASK_STATE_AUTH_REQUIRED needs a credential or an approval, sent outside A2A, and the task can resume without a client message.
Answering on the same task
The reviewer creates task e5c95b09 for the planner's diff, stops, and the blocking call returns the task with its question:
"task": {
"id": "e5c95b09-6d4b-4b3b-8693-91e81472d12f",
"contextId": "49c5a238-4158-455d-8d63-b2cb39c0ecac",
"status": {
"state": "TASK_STATE_INPUT_REQUIRED",
"message": {
…
"role": "ROLE_AGENT",
"parts": [
{
"text": "Which base branch should I compare this diff against?"
}
]
},
"timestamp": "2026-10-06T09:00:00.500Z"
},
…The answer is an ordinary SendMessage that names the task: the client continues with a new message that has the same taskId and contextId. The planner answers main with both ids. The second reply returns the same task in TASK_STATE_COMPLETED, with the review.json artifact. Figure 4.3 follows the whole exchange.
SendMessage and its reply, and steps 4 to 9 answer the question on the same task. Ids are shortened to 8 characters.Authorization that arrives outside A2A
An agent can need permission partway through a task, for example human approval before a destructive action. Such an agent must move the task to TASK_STATE_AUTH_REQUIRED. The credential takes another road:
The deployer's third stream frame names the place where an operator approves:
"statusUpdate": {
"taskId": "ecf2dcb6-79c8-48f8-8868-24a0541781f4",
"contextId": "9e8e6bcf-b117-48b9-992a-67971cddcb1b",
"status": {
"state": "TASK_STATE_AUTH_REQUIRED",
"message": {
…
"role": "ROLE_AGENT",
"parts": [
{
"text": "An operator must approve this deploy at http://localhost:41243/approve/ecf2dcb6-79c8-48f8-8868-24a0541781f4"
}
]
},
"timestamp": "2026-10-06T09:00:00.750Z"
}
}The approval never enters the protocol. In the kit an operator sends POST /approve/<task id> to the deployer, as the kit README lists. No client message follows. After the agent receives the credential, it is allowed to continue the task at once. The client does not have to send another message.
A client that is itself an agent can pass the request upstream by moving its own task to TASK_STATE_AUTH_REQUIRED. Security schemes and in-task authorization covers what such a chain does to credentials.
TASK_STATE_AUTH_REQUIRED while the stream stays open, and the operator's approval travels outside A2A before the same stream carries the result. Read top to bottom. Steps 2 to 4 and 7 to 9 are the six frames of one stream. Steps 5 and 6 are plain HTTP outside A2A. Ids are shortened to 8 characters.When the stream closes
In this capture the stream stays open through the wait. Closing is a MUST only at terminal states, and the HTTP+JSON binding closes at a terminal state or at an interrupted state. An agent that waits for a credential outside A2A should keep its open response streams after it moves the task to TASK_STATE_AUTH_REQUIRED. The specification does not settle this (conflict D3).
Upstream, PR #2270 on branch dev-1.1, approved on 2026-09-29 and unreleased, makes both interrupted states non-terminal. It says that entering one does not require closing a stream. On main, §11.7 and the streaming guide still close at both kinds of state.
The kit closes at TASK_STATE_INPUT_REQUIRED and stays open through TASK_STATE_AUTH_REQUIRED, as the kit README lists. The SDKs split the same way:
| SDK | When the server closes a SendStreamingMessage stream |
|---|---|
| a2a-python 1.2.2 | when the agent's execute() call returns, so the agent code decides |
| a2a-go | after a Message, a terminal state, or TASK_STATE_INPUT_REQUIRED, and it stays open through TASK_STATE_AUTH_REQUIRED |
| a2a-java | after a terminal state, a Message, or an error, and both interrupted states keep it open after execute() returns |
| a2a-js | after a terminal state, TASK_STATE_INPUT_REQUIRED, or a Message, and TASK_STATE_AUTH_REQUIRED keeps it open |
| a2a-dotnet | when the handler returns or calls a TaskUpdater method for a terminal or interrupted state |
| a2a-rs | after a terminal event or when the executor's stream ends, with no rule for interrupted states |
A closed stream ends your watching, never the task. Call GetTask, and if the task is not terminal, act on its state and call SubscribeToTask, as SendStreamingMessage and SubscribeToTask shows.
Keep watching while someone else acts
Without an open stream, the client can miss task updates, so subscribe with SubscribeToTask, register a webhook, or poll with GetTask.
The kit's planner subscribes. Its blocking SendMessage returns task a31361b3 in TASK_STATE_AUTH_REQUIRED, and it calls SubscribeToTask at once, in exchanges 7 and 8 of 19-planner.http. It alerts the operator only after the first frame arrives, because the specification defines no replay of earlier events.
A2A protocol 1.0.1 · 3303592 · 2026-05-28 · Edition 2026.10