---
title: "Stop the session's in-flight turn"
method: POST
path: "/v1/agent/turn/cancel"
tags: ["Agent"]
---

# Stop the session's in-flight turn

`POST /v1/agent/turn/cancel`

## Request

- Base URL: `http://localhost:9998`
- URL: `http://localhost:9998/v1/agent/turn/cancel`
- Auth: HTTP bearer

The explicit Stop (kernel work model, D5). Cancels the running turn
promptly: the stream emits the terminal `turn-ended` frame with reason
`cancelled`, partial assistant text is committed to the transcript, and
the session survives for the next turn — stopping a turn does not cost
the conversation. Idempotent: cancelling when no turn is running is a
`200` no-op, not a conflict. Disconnect inference backs this endpoint
up: a turn whose SSE watchers all vanish is cancelled after a short
grace window, while a turn that never had a watcher (fire-and-forget)
runs to its budget.

## Request body

- object
  - `session_id` string, required: The session whose turn to cancel
  - `run_id` string: Optional. The run to stop; when it is not the running run, nothing is cancelled (`200`), so a Stop aimed at a finished run never stops the one after it.

## Response `200`

No turn was running, or `run_id` named a run that is not the running one (idempotent no-op)

- object
  - `ok` true
  - `session_id` string
  - `cancelled` false

## Other responses

- `204`: The in-flight turn was cancelled; `turn-ended(cancelled)` rides the SSE stream
- `404`: Unknown session

---

[API](https://skmtc.dev/modelpiper/apis/toolpiper-api.md) · [All operations](https://skmtc.dev/modelpiper/apis/toolpiper-api/llms.txt) · [OpenAPI document](https://skmtc.dev/modelpiper/apis/toolpiper-api/revisions/6722bf56385c?raw)
