> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aion.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Task Updates

> How a client follows a task the Python SDK server runs: streams, push notifications and polling.

A run belongs to the agent server, not to the request that started it. It goes on when the client disconnects, and
the task stores its outcome either way. A client follows the task through one of the A2A methods below.

## Durable and ephemeral updates

| Kind | What it is |
| - | - |
| Durable | What the task stores: status changes with their messages, artifacts, the outcome. |
| Ephemeral | Live-only progress the task never stores: response and thinking deltas (see [Streaming Delta Semantics](https://docs.aion.to/sdk/python/streaming/stream-delta.md)), ephemeral messages, reactions, and status updates flagged `aion:ephemeral`. |

An ephemeral update reaches only the streams open on the server running the task, as it happens. Everything durable
can be read again later.

## Delivery methods

| Method | How it is delivered | What arrives | Connection held |
| - | - | - | - |
| `SendStreamingMessage` | Server-sent events on the request, opened and closed by the stored `Task`. | Everything, ephemeral included. | Until the task has an outcome or waits for input. |
| `SendMessage` | One JSON response: the `Task` once it has an outcome or waits for input. With `configuration.returnImmediately`, the task at once while the run goes on. | Durable only. | As for the stream; none with `returnImmediately`. |
| Push notifications | `configuration.taskPushNotificationConfig` on a send, or `CreateTaskPushNotificationConfig`. The server POSTs each change the task stores to the webhook; an outcome or a wait for input arrives as the full `Task`. | Durable only. | None. |
| `SubscribeToTask` | Server-sent events: the stored task, then the live events until the task stops. A task that already has an outcome is refused with `UnsupportedOperationError` (`-32004`). | On the server running the task, everything. On another server, the task's stored events, so durable only. | Until the task stops. |
| `GetTask` | One JSON response: the stored task, its history cut to `historyLength`. | Durable only. | None. |

`SendMessage` always answers with a `Task`, never a bare `Message`, and every stream closes with the stored `Task`.
How a subscription is served when several servers share one database is described in
[Multiple Instances](https://docs.aion.to/sdk/python/running/multiple-instances.md).

## When a stream ends early

A stream that closes on a `Task` that is still `SUBMITTED` or `WORKING`, and a `SendMessage` answered with one, did
not see the run end. Two things cause it:

* a2a-sdk drops a subscriber that falls 1024 events behind, and logs `Evicting event queue sink`.
* A stopping server closes its connections.

The run itself is not affected. Resubscribe with `SubscribeToTask`, or poll `GetTask`, for the outcome. To stop a
run, call `CancelTask`; disconnecting does not stop it.

## Push notifications

A webhook receives exactly what the task stores, and never an ephemeral update. That includes every outcome the
task stores, also those the run did not write itself:

* a cancel written by another server of the agent;
* the `FAILED` of an agent that raised;
* a task settled `FAILED` when its server shut down, with `aion:settledReason` set to `server_shutdown`;
* a task settled `FAILED` as abandoned after `AION_STALE_TASK_TIMEOUT`, with `aion:settledReason` set to
  `task_abandoned`.

See [Multiple Instances](https://docs.aion.to/sdk/python/running/multiple-instances.md#behaviour-to-plan-for) for when the server settles
a task.

Each delivery carries the configuration's `token` as `X-A2A-Notification-Token`, and its `authentication` as
`Authorization: <scheme> <credentials>`; credentials without a scheme are sent as `Bearer`.
`CreateTaskPushNotificationConfig` answers with the configuration as stored: an `id` the request left empty is the
task's id.

Deliveries are made one at a time from the task's event loop, each after its change is stored. A webhook that answers
slowly therefore holds back the delivery of the run's later events, on every channel, for up to
`PUSH_NOTIFICATION_TIMEOUT_SECONDS` (default 5 seconds) per delivery. Connecting to the webhook is limited to
5 seconds. On a server the Aion platform hosts, a webhook URL must be `http` or `https` and resolve to public addresses
only; see [Environment Variables](https://docs.aion.to/sdk/python/configuration/environment-variables.md#storage-settings).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.