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

# Cancel Durable Turn

> Request cooperative cancellation of a detached turn

Requests cancellation of a durable turn and returns its current status with `202 Accepted`.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
POST /v1/agents/{agent_id}/chats/{chat_id}/turns/{turn_id}/cancel
```

Cancellation is cooperative. A `202` response confirms the request was accepted; it does not guarantee the producer has stopped. Poll [Get Turn](/api-reference/chats/get-turn) until `status` leaves `in_progress`.

<ParamField header="Authorization" type="string" required>
  Bearer token obtained from [Authenticate](/api-reference/authentication/authenticate).
</ParamField>

<ParamField path="agent_id" type="string" required>
  Published agent UUID used to run the chat.
</ParamField>

<ParamField path="chat_id" type="string" required>
  Member-owned chat UUID.
</ParamField>

<ParamField path="turn_id" type="string" required>
  Durable turn UUID to cancel.
</ParamField>

The request has no body and does not consume the shared turn-submission throttle.

## Response

The response has the same shape as [Get Turn](/api-reference/chats/get-turn):

<ResponseField name="turn_id" type="string" required>
  Durable turn UUID.
</ResponseField>

<ResponseField name="chat_id" type="string" required>
  Owning chat UUID.
</ResponseField>

<ResponseField name="status" type="string" required>
  Current public status: `in_progress`, `completed`, `failed`, or `cancelled`. It commonly remains `in_progress` in the immediate acknowledgement.
</ResponseField>

<ResponseField name="created_at" type="string" required>
  ISO 8601 acceptance timestamp.
</ResponseField>

<ResponseField name="completed_at" type="string | null" required>
  Terminal timestamp when available.
</ResponseField>

<ResponseField name="last_seq" type="integer" required>
  Highest durable event sequence represented by the snapshot.
</ResponseField>

<ResponseField name="partial_content" type="string | null" required>
  Persisted partial assistant text through `last_seq`.
</ResponseField>

<ResponseField name="result_message_id" type="string | null" required>
  UUID of the persisted terminal assistant message, when one was written. A cancelled turn with persisted partial output can have a non-null value.
</ResponseField>

<ResponseField name="replay_available" type="boolean" required>
  Current exact-replay availability.
</ResponseField>

<ResponseField name="replay_degraded" type="boolean" required>
  Whether exact replay has degraded.
</ResponseField>

<ResponseField name="error" type="object | null" required>
  Safe public error for a failed turn, otherwise null.
</ResponseField>

Calling cancel on an already-terminal turn is idempotent: the server returns its unchanged terminal status. A completion racing with cancellation can therefore return `completed` rather than `cancelled`.

The response fields depend on when cancellation is observed:

* The immediate response to an accepted cancellation can still be `in_progress`, with partial content already visible but no `result_message_id` yet.
* A turn cancelled before producing output can finish with both `partial_content` and `result_message_id` set to `null`.
* A turn cancelled after producing partial output can finish with both `partial_content` and `result_message_id` set; the ID addresses the persisted partial assistant message.
* If completion or failure wins the race, the endpoint returns that terminal status and its corresponding `result_message_id`.

<RequestExample>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST \
    "https://api.trellis.sh/v1/agents/AGENT_ID/chats/9f0ac8f2-7a22-4ec8-a778-b0b1b83a86bb/turns/26e53cf2-b12d-4a2a-a3b7-5382a87f8f5b/cancel" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests

  response = requests.post(
      "https://api.trellis.sh/v1/agents/AGENT_ID/chats/9f0ac8f2-7a22-4ec8-a778-b0b1b83a86bb/turns/26e53cf2-b12d-4a2a-a3b7-5382a87f8f5b/cancel",
      headers={"Authorization": "Bearer YOUR_TOKEN"},
  )
  response.raise_for_status()
  status = response.json()
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch(
    "https://api.trellis.sh/v1/agents/AGENT_ID/chats/9f0ac8f2-7a22-4ec8-a778-b0b1b83a86bb/turns/26e53cf2-b12d-4a2a-a3b7-5382a87f8f5b/cancel",
    {
      method: "POST",
      headers: { Authorization: "Bearer YOUR_TOKEN" },
    },
  );
  const status = await response.json();
  ```
</RequestExample>

<ResponseExample>
  ```json 202 Cancellation requested theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "turn_id": "26e53cf2-b12d-4a2a-a3b7-5382a87f8f5b",
    "chat_id": "9f0ac8f2-7a22-4ec8-a778-b0b1b83a86bb",
    "status": "in_progress",
    "created_at": "2026-08-08T18:00:01.234567+00:00",
    "completed_at": null,
    "last_seq": 7,
    "partial_content": "The portfolio contains",
    "result_message_id": null,
    "replay_available": true,
    "replay_degraded": false,
    "error": null
  }
  ```

  ```json 202 Cancelled theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "turn_id": "26e53cf2-b12d-4a2a-a3b7-5382a87f8f5b",
    "chat_id": "9f0ac8f2-7a22-4ec8-a778-b0b1b83a86bb",
    "status": "cancelled",
    "created_at": "2026-08-08T18:00:01.234567+00:00",
    "completed_at": "2026-08-08T18:00:07.876543+00:00",
    "last_seq": 9,
    "partial_content": "The portfolio contains",
    "result_message_id": "fc7dc568-d4c9-40f0-befc-0764241859d7",
    "replay_available": true,
    "replay_degraded": false,
    "error": null
  }
  ```

  ```json 404 Unknown chat/agent binding theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {"detail":"Chat not found"}
  ```

  ```json 404 Unknown turn theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {"detail":"Turn not found"}
  ```
</ResponseExample>
