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

# Tasks

# Messages

## What They Are

A **message** is the durable record of a single agent interaction within a session. When you call `POST /send` (via `message/send` or `message/stream`), the mesh runtime creates a message, updates it as execution progresses, and persists snapshots through the gateway. Dashboards and clients can list messages, inspect status, and cancel work that is still running.

The gateway stores each message in PostgreSQL (`messages`) with a stable `message_id`, tenant isolation, the current `state`, user input, assistant output, trace data, and the full A2A task payload in `task_data`.

## Lifecycle

Messages move through a set of **state** values aligned with the A2A execution model:

1. **submitted** — accepted and queued.
2. **working** — actively executing.
3. **input-required** — blocked waiting for human input (approval, form data, confirmation). See [Notifications & Approvals](./notifications).
4. **completed** — finished successfully.
5. **failed** — finished with an error.
6. **canceled** — stopped by operator or API.

Terminal states are **completed**, **failed**, and **canceled**. Cancellation is only applied when the message is not already in one of those states.

```mermaid theme={null}
stateDiagram-v2
	[*] --> submitted
	submitted --> working
	submitted --> canceled
	working --> completed
	working --> failed
	working --> input_required : needs human input
	working --> canceled
	input_required --> working : resolved
	input_required --> failed : expired
	input_required --> canceled
```

## Relation to Sessions

Every message belongs to a **session** via `session_id`. One session can have many messages over time — each `POST /send` call creates a new message. Filter listings by `session_id` to show messages for a single session.

## API

| Endpoint                      | Purpose                                                                  |
| ----------------------------- | ------------------------------------------------------------------------ |
| `POST /send`                  | Send a new message (A2A JSON-RPC — `message/send` or `message/stream`)   |
| `POST /messages/get`          | Paginated list for the tenant; optional `state` and `session_id` filters |
| `POST /messages/get_by_id`    | Full detail for one `message_id`                                         |
| `POST /messages/cancel`       | Cancel a running message (409 if already terminal)                       |
| `POST /messages/pending`      | List messages in `input-required` state (the Approval Queue)             |
| `POST /messages/{id}/resolve` | Submit a human resolution for a pending message                          |

## Canceling Messages

Call `POST /messages/cancel` with `{ "message_id": "<id>" }`. Success returns `{ "ok": true, "message_id": "<id>" }`. If the message is already **completed**, **failed**, or **canceled**, the gateway responds with **409**.

## Resolving Pending Messages

When a message enters `input-required`, it appears in the Approval Queue. Resolution can come from:

* **Dashboard**: click Approve/Deny or submit a form
* **API**: `POST /messages/{id}/resolve` with resolution data
* **Slack**: interactive buttons → `/integrations/slack/interactive`
* **Webhook callback**: `POST /messages/{id}/resolve` with `callback_token`

See [Notifications & Approvals](./notifications) for the full resolution flow.

## Further Reading

* [Sessions](./sessions) — the session lifecycle and how messages fit in
* [Streaming & Events](./streaming) — SSE streaming for real-time message progress
* [A2UI](./a2ui) — the payload format for `input-required` messages
* [Notifications & Approvals](./notifications) — multi-channel notification pipeline
