Enqueue the next input after the current turn
Queues message as the session's next turn in the same engine conversation, after every turn already queued. Only an active session takes input; the other admission states answer the 409 codes below. The 202 means the input is stored under a new sequential turn_id, not that it ran: follow the turn with GET /v1/sessions/{id}/turns/{turn_id} or on the event stream. A session over its budget still queues input but runs no new turn (attention.code: BUDGET_EXCEEDED). The receipt settles with the turn: succeeded when it completes, failed when it fails or is interrupted or cancelled, unknown when its outcome is unknown. A caller who sees the session but may not use its private agent (GET /v1/agents/{id}/usage) is refused with 403 FORBIDDEN, reason_code agent_private, and no one to ask; a retry of an input taken before they lost the agent still gets its stored answer. A sender whose caller limits (GET /v1/agents/{id}/caller-limits) leave out something the session loads, after the limit the session was created under took its part away, is refused with 403 FORBIDDEN, reason_code caller_limited and details.dimension (tool, mcp_server, repository or credential); a rule change counts from the next input.
Scope: sessions:write (API key or cookie session). Idempotency-Key: required.
AuthorizationBearer <token>For servers and scripts: an API key sent as an HTTP bearer token, Bearer <key>. It holds exactly the scopes it was issued with; a key issued before scopes existed holds none. It never needs the CSRF header, and it cannot manage agents, members, teams or API keys. Issue one in the web console under Settings → API keys; each operation names the scope it needs.
Scope: sessions:write
id*stringThe session's id.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$uuidIdempotency-Key*stringRequired, 1–255 characters; a UUID per user intent works. A retry with the same key and the same body returns the original response and runs the command once; the same key with a different body answers 409 IDEMPOTENCY_CONFLICT. A missing or invalid key answers 400 BAD_REQUEST, after the body is read.
1 <= length <= 255X-Requested-With?"werft-web"Required with a cookie session: the literal werft-web.
"werft-web"application/json- body
message*stringAt most 32768 bytes of UTF-8
1 <= lengthmode?string"enqueue"The input is stored as a queued turn.
application/json- response
turn_id*string1 <= lengthreceipt_id*string^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$uuidreceipt_status*string"accepted""succeeded""failed""unknown"curl -X POST 'https://example.com/v1/sessions/497f6eca-6276-4993-bfeb-53cbbbba6f08/messages' \ -H 'Idempotency-Key: string' \ -H 'Content-Type: application/json' \ -d '{ "message": "Now add the endpoint to the README."}'{ "turn_id": "4", "receipt_id": "c4a1e9d2-7b3f-4e8a-a6c5-1d2e3f4a5b6c", "receipt_status": "accepted"}