A2A Task Lifecycle: States, Messages, and Artifacts Explained
What a Task Represents
A task is the fundamental unit of work in A2A. When a client agent wants a server agent to do something, it creates a task. The task contains the instructions (as messages), tracks progress (through state transitions), records the conversation (as a message history), and holds the results (as artifacts). Every task has a unique ID generated by the client, which both parties use to reference the task throughout its lifecycle.
Tasks are deliberately more than simple request-response pairs. A REST API call sends a request and gets a response, then the interaction is over. An A2A task can span multiple exchanges: the client sends instructions, the server asks for clarification, the client provides it, the server delivers partial results, the client requests adjustments, and the server delivers the final output. The task object holds all of this as a coherent, ordered record of the collaboration.
This design reflects the reality of agent collaboration. When you delegate work to another autonomous agent, you rarely get the result in a single exchange. The server agent might need additional context, might discover complications that require client input, or might produce intermediate outputs that the client needs to review before the server continues. The task lifecycle accommodates all of these patterns through its state machine and message history.
The Five Task States
Every task exists in exactly one state at any time. The protocol defines five states, and the valid transitions between them follow a strict graph that prevents invalid or inconsistent state changes.
Submitted. A task enters this state when the server receives it from the client but has not yet started processing. The submitted state is the entry point for every new task. Some servers transition through this state almost instantly, moving to working within milliseconds. Others may queue tasks and hold them in submitted until resources become available. From submitted, a task can move to working (the server begins execution), canceled (the client cancels before processing starts), or failed (the server rejects the task due to validation errors, unsupported skill, or resource constraints).
Working. This state indicates that the server agent is actively processing the task. The server may send intermediate messages during this state, including progress updates, partial results, or status reports. If the client used tasks/sendSubscribe, these updates stream back in real time. The working state can last milliseconds for simple tasks or hours for complex analyses. From working, the task can transition to completed (work finished successfully), input-required (the server needs more information from the client), canceled (either party terminates), or failed (an unrecoverable error occurs).
Input-required. This is the state that makes A2A fundamentally different from simple tool-calling protocols. When the server agent needs additional information from the client, it transitions the task to input-required and includes a message explaining what it needs. The task pauses until the client responds. The client sends a new message to the same task ID using tasks/send, and the task transitions back to working. Multiple rounds of input-required are allowed, enabling complex negotiations and iterative refinements between agents.
Completed. A terminal state indicating that the server finished the work successfully. The task's artifacts contain the deliverable results. Once a task reaches completed, it cannot transition to any other state. The message history is frozen, and the task serves as a permanent record of the collaboration and its outcomes.
Failed. A terminal state indicating that the server could not complete the work. The task includes an error message or a final message explaining what went wrong. Failures can happen for many reasons: the input data was malformed, an external service the server depends on was unavailable, the task exceeded resource limits, or the server encountered a logic error it could not recover from. Like completed, the failed state is final.
Canceled. A terminal state indicating that the task was terminated before completion. Either the client explicitly canceled using tasks/cancel, or the server decided to abort. Canceled tasks may contain partial results if the server had already produced some output before cancellation. Cancellation is cooperative, meaning the server acknowledges the request and stops work, but may complete in-flight operations before fully halting.
State Transition Rules
The protocol enforces specific rules about which transitions are valid. Understanding these rules matters because they determine what your code should expect and what error conditions it needs to handle.
From submitted, valid transitions are: working, canceled, failed. A task cannot skip directly from submitted to completed without passing through working. A task cannot move from submitted to input-required because the server has not started processing yet and cannot know what additional information it needs.
From working, valid transitions are: completed, input-required, canceled, failed. This is the state with the most possible transitions because it is where the actual processing happens and where the most conditions can arise.
From input-required, valid transitions are: working, canceled, failed. When the client provides the requested information, the task returns to working. The client can also cancel a task that is waiting for input, and the server can fail a task if the input-required state times out or becomes invalid.
From completed, failed, or canceled, no transitions are valid. These are terminal states. A completed task stays completed forever. If you need to retry a failed task, you create a new task with a new ID rather than attempting to restart the old one. This immutability simplifies state management because neither the client nor the server needs to handle the possibility of a terminal task suddenly becoming active again.
Messages and Their Role
Messages are the communication units within a task. Every message has a role (either "user" for messages from the client or "agent" for messages from the server) and an array of parts containing the actual content. The message history within a task is an ordered sequence that records the full conversation between the two agents.
The first message in a task comes from the client and contains the initial instructions. This might be a simple text request ("Analyze this dataset and identify the top three trends"), a structured request with parameters (a DataPart containing JSON with specific configuration), or a combination of text instructions and file attachments (a TextPart with context plus a FilePart containing a CSV file).
As the server processes the task, it may add messages to the history. Status update messages tell the client what the server is currently doing ("Loaded the dataset, beginning statistical analysis"). Clarification request messages explain what the server needs when transitioning to input-required ("The dataset contains three date columns. Which one should I use as the primary time axis?"). Progress messages share intermediate results ("Initial analysis complete. Found 47 outliers in the revenue column. Proceeding to trend detection.").
When the client responds to an input-required state, its response is added as a new message in the history. This creates a complete, chronological record of the collaboration. Anyone reviewing the task later can read through the message history and understand exactly what was requested, what questions arose, how they were resolved, and how the work progressed.
Each message contains one or more parts, and the three part types (TextPart, DataPart, FilePart) can be mixed freely within a single message. A server responding to a data analysis request might send a message containing a TextPart summarizing findings, a DataPart with structured statistics, and a FilePart with a chart. This multi-part design lets agents communicate rich, mixed-format information without requiring multiple messages or separate data channels.
Artifacts vs Messages
The distinction between artifacts and messages is one of the most important design decisions in the A2A protocol, and understanding it is key to building agents that handle task outputs correctly.
Messages are the conversation. They represent the back-and-forth dialogue between client and server as work progresses. Messages include instructions, questions, status updates, clarifications, and progress reports. They are the process of collaboration.
Artifacts are the deliverables. They represent the final work products that the server produces when the task completes. Each artifact has a name, a description, and an array of parts (using the same TextPart, DataPart, and FilePart types as messages). Artifacts are attached to the task when it reaches the completed state, and they represent the output of collaboration.
This separation matters for practical reasons. A client agent that delegates a research task will receive many messages during processing: status updates, clarification requests, intermediate observations. But when the task completes, it needs to know which content is the actual deliverable versus which content was just conversation. The artifacts make this distinction explicit. The client can process artifacts as final results (save them, pass them to another agent, present them to a user) while treating messages as historical context.
A single task can produce multiple artifacts. A report generation task might produce one artifact containing the executive summary (TextPart), another containing the detailed analysis (TextPart plus DataPart with tables), and a third containing visualizations (multiple FileParts with charts). Each artifact is a named, self-contained deliverable that the client can handle independently.
Artifacts can also be streamed incrementally during the working state using tasks/sendSubscribe. The server emits TaskArtifactUpdateEvent entries as it generates output, allowing the client to begin processing results before the task fully completes. This is particularly useful for long-running tasks where the client wants to display or act on partial results as they become available.
The Input-Required Pattern in Practice
The input-required state enables a collaboration pattern that no simple RPC protocol supports: multi-turn negotiation between autonomous agents. Understanding how to use this state effectively is critical for building agents that handle complex, ambiguous tasks well.
Consider a client agent that delegates a market research task to a research server agent. The client sends: "Analyze the competitive landscape for autonomous vehicle insurance in North America." The server begins working, loads available data sources, and discovers that the market has distinct segments (personal auto, commercial fleet, ride-share) with very different dynamics. Rather than guessing which segments the client cares about, the server transitions to input-required with the message: "The autonomous vehicle insurance market has three major segments: personal auto policies, commercial fleet coverage, and ride-share platform insurance. Should I analyze all three, or would you prefer I focus on specific segments?"
The client responds with a new message: "Focus on commercial fleet and ride-share. Exclude personal auto." The task transitions back to working. The server continues, narrows its analysis, and eventually completes the task with artifacts containing the focused research.
This pattern can repeat multiple times within a single task. After the client narrows the scope, the server might encounter another decision point: "I have access to data from 2022 through 2026. Two data sources cover the full range but have limited granularity. One source has detailed monthly data but only covers 2024 onward. Which time range and granularity do you prefer?" The client responds, and the server continues.
The input-required pattern works because both participants are autonomous agents capable of making meaningful decisions about how to proceed. A tool cannot ask clarifying questions. An agent can, and A2A gives it a structured way to do so without breaking the task flow or requiring a new task to be created.
Task IDs and Idempotency
Task IDs are generated by the client, not the server. This is a deliberate design choice that gives the client control over task identity and enables idempotent task submission. If a client sends a tasks/send request but does not receive a response (due to network failure, timeout, or other transient error), it can safely resend the same request with the same task ID. The server recognizes the existing task ID and returns the current state rather than creating a duplicate task.
When a client sends a message to an existing task ID, the server appends the message to the task's history. This is how clients respond to input-required states: they send a new tasks/send request with the same task ID and a new message containing the requested information. The server matches the ID, sees that the task is in the input-required state, appends the message, and transitions back to working.
Client-generated IDs also simplify distributed systems where multiple client instances might need to track the same task. The client can use a deterministic ID generation strategy (such as hashing the task parameters) to ensure that the same logical task always maps to the same ID, regardless of which client instance submits it.
Error Handling and Recovery
Errors in A2A fall into two categories, and handling them correctly requires understanding the difference.
Protocol errors mean the request itself was invalid. The JSON was malformed, the method name was wrong, required parameters were missing, or the request failed authentication. Protocol errors return JSON-RPC error responses with standardized codes. The task may or may not have been affected, depending on when the error occurred. Protocol errors are typically retryable after fixing the request.
Task failures mean the request was valid but the server could not complete the work. The server transitions the task to the failed state and includes an error message explaining what went wrong. Task failures are not retryable on the same task because the failed state is terminal. Instead, the client should create a new task, potentially with modified instructions that address the failure cause.
Robust client agents distinguish between these two categories in their error handling. For protocol errors, they retry with corrected requests. For task failures, they examine the error message, determine whether the failure is addressable (maybe the instructions were ambiguous or the input data was in the wrong format), and submit a new task with improved input if appropriate.
The combination of client-generated task IDs and the terminal state guarantee means that error recovery is straightforward. A client always knows the current state of a task by calling tasks/get with the task ID. If the task failed, the client creates a new task. If the task is still working, the client waits or polls. If the connection dropped during a streaming session, the client can reconnect or fall back to polling without any ambiguity about the task's state.
Practical Patterns for Production
Production A2A systems use several patterns built on top of the task lifecycle to handle common operational requirements.
Timeout management. The protocol does not define built-in timeouts, so clients implement their own. A common pattern is to set a maximum duration for each task based on the expected complexity of the skill being invoked. If the task has not completed within the timeout, the client sends a tasks/cancel and either retries or escalates. The timeout should account for input-required states, which pause the clock since the server is waiting on the client, not processing.
Retry with backoff. When a task fails due to transient server issues (resource exhaustion, temporary dependency failures), clients can retry by creating a new task with the same instructions. Implementing exponential backoff between retries prevents overwhelming a struggling server. Some clients include the previous task ID as metadata in the retry task so the server can access the failed task's history if needed.
Task chaining. Complex workflows often require multiple sequential tasks where the output of one becomes the input to the next. The client submits the first task, waits for completion, extracts the relevant artifacts, and includes them as parts in the message for the second task. Each task has its own ID and lifecycle, but the client manages the dependencies between them.
Parallel fan-out. When a client needs results from multiple independent skills, it can submit multiple tasks simultaneously and wait for all of them to complete. This is more efficient than sequential submission because the server agents can process the tasks in parallel. The client tracks multiple task IDs and assembles the combined results when all tasks reach a terminal state.
The A2A task lifecycle is a state machine with five states (submitted, working, input-required, completed, failed, canceled) that manages the full collaboration between agents. Messages record the conversation, artifacts hold the deliverables, and the input-required state enables the multi-turn negotiations that make A2A suitable for complex, autonomous agent collaboration.