Skip to content

Durably admit a caller-owned Turn and its 1:1 Run

PUT
/v1/sessions/{sessionId}/turns/{turnId}
curl --request PUT \
--url https://example.com/v1/sessions/9f2b7c14-59d3-4f7a-b8e1-2a6c05d4e731/turns/9f2b7c14-59d3-4f7a-b8e1-2a6c05d4e731 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "message": "Use a sliding window of 100 requests per minute per API key.", "model": "claude-opus-5", "replyTo": { "interactionId": "toolu_01H8sZ4kQm2rVn9pXfB3tGdA" } }'

Returns after the immutable Turn and QUEUED Run commit. Compute provisioning and engine admission happen asynchronously. Reply to an open Interaction by setting replyTo.interactionId.

sessionId
required

A UUID identifying one Cloud resource; Session, Turn, Publication and Merge ids are minted by the caller so an ambiguous retry addresses the same durable command instead of creating a second one.

string format: uuid
Example
9f2b7c14-59d3-4f7a-b8e1-2a6c05d4e731

A UUID you mint and own; it is the idempotency key for creation and the address of every Turn, artifact and publication underneath

turnId
required

A UUID identifying one Cloud resource; Session, Turn, Publication and Merge ids are minted by the caller so an ambiguous retry addresses the same durable command instead of creating a second one.

string format: uuid
Example
9f2b7c14-59d3-4f7a-b8e1-2a6c05d4e731

A UUID you mint for this Turn; it is both the idempotency key and the id of the Run it creates

Media typeapplication/json

Body of the idempotent Turn admission. The same caller-owned Turn id with the same content is a safe retry; the same id with different content is a conflict.

object
message
required

The prompt to execute; it becomes this Turn’s immutable input

string
>= 1 characters <= 100000 characters
model

Model for this Turn only, overriding the Session default; it must be one the Session’s settled runtime advertises

string
>= 1 characters <= 128 characters
runtime

Compatibility echo only: when present it must equal the Session’s settled runtime. Omit it for ordinary Turns; create a new Session to change runtime.

string
<= 64 characters
replyTo

Answers one specific open Interaction — the id is rechecked at admission and again at engine dispatch, so a stale prompt in a UI cannot answer a different question

object
interactionId
required
string
>= 1 characters <= 255 characters
Example
{
"message": "Use a sliding window of 100 requests per minute per API key.",
"model": "claude-opus-5",
"replyTo": {
"interactionId": "toolu_01H8sZ4kQm2rVn9pXfB3tGdA"
}
}

Turn admitted or replayed

Media typeapplication/json

The 202 result of admitting a Turn: the immutable Turn and its queued Run are already committed to Postgres, while compute provisioning and engine start happen afterwards.

object
turn
required

The durably admitted Turn, normally still pending dispatch at this point

object
id
required

The caller-owned Turn id; the one Run admitted with it carries this exact same value

string format: uuid
sessionId
required

Session this Turn belongs to

string format: uuid
ordinal
required

Session-local admission order starting at 0, and the value Turn paging is keyed on

integer
input
required

The immutable admitted input — the message plus whatever model, runtime and reply the caller actually requested

object
message
required
string
model
string
runtime
string
replyTo
object
interactionId
string
dispatch
required

Durable hand-off state to the engine: pending before a worker claims it, attempted once delivery started, confirmed when the engine accepted it, rejected when it definitively did not

string
Allowed values: pending attempted confirmed rejected
run
required

The single Run this Turn created; its id equals the Turn id

object
id
required

A UUID identifying one Cloud resource; Session, Turn, Publication and Merge ids are minted by the caller so an ambiguous retry addresses the same durable command instead of creating a second one.

string format: uuid
createdAt
required

When admission committed the Turn, which is before any compute necessarily existed

string format: date-time
run
required

The 1:1 Run created with it, normally still queued

object
id
required

Run id, always equal to the id of the Turn that created it

string format: uuid
sessionId
required

Session this Run belongs to

string format: uuid
status
required

queued, dispatching and running are in flight, awaiting means the agent is blocked on human input, and completed, failed, cancelled and crashed are terminal

string
Allowed values: queued dispatching running awaiting completed failed cancelled crashed
attempts
required

How many times a worker has claimed this Run; recovery after a lost worker increments it instead of creating a second Run

integer
cancellationRequested
required

Whether cancellation was durably requested; it stays true after the Run terminates, and it never asserts that an external side effect was undone

boolean
lastError

Coarse machine code for the most recent failure, retained across retries; absent when nothing has failed

object
code
required
string
createdAt
required

When admission committed this Run in queued

string format: date-time
updatedAt
required

Last durable Run state change

string format: date-time
startedAt

When a worker actually began executing; absent while the Run is still queued

string format: date-time
completedAt

When the Run reached a terminal status; absent otherwise

string format: date-time
created
required

False when this request was an exact idempotent replay and the stored Turn was returned unchanged

boolean
Example
{
"turn": {
"id": "8f2d5b41-6e0c-47a9-b3d8-51ca9e07f2b6",
"sessionId": "9f2b7c14-59d3-4f7a-b8e1-2a6c05d4e731",
"ordinal": 1,
"input": {
"message": "Use a sliding window of 100 requests per minute per API key.",
"model": "claude-opus-5",
"runtime": "wamp",
"replyTo": {
"interactionId": "toolu_01H8sZ4kQm2rVn9pXfB3tGdA"
}
},
"dispatch": "pending",
"run": {
"id": "8f2d5b41-6e0c-47a9-b3d8-51ca9e07f2b6"
},
"createdAt": "2026-08-12T09:46:12Z"
},
"run": {
"id": "8f2d5b41-6e0c-47a9-b3d8-51ca9e07f2b6",
"sessionId": "9f2b7c14-59d3-4f7a-b8e1-2a6c05d4e731",
"status": "queued",
"attempts": 0,
"cancellationRequested": false,
"createdAt": "2026-08-12T09:46:12Z",
"updatedAt": "2026-08-12T09:46:12Z"
},
"created": true
}
Location
string

Malformed request

Media typeapplication/json

Failure body returned with every non-2xx JSON response; branch on the machine code, never on prose or on the HTTP status alone.

object
error
required

Stable machine code

string
requiredScope

The installation capability the presented credential lacks, returned with insufficient_scope so an integrator knows exactly which capability to request

string
retryAfterSeconds

Advisory seconds to wait before retrying; returned on rate-limit denials, where the Retry-After header carries the same value

integer
>= 1
key
additional properties
any
Example
{
"error": "invalid_request"
}

The resource is missing or inaccessible

Media typeapplication/json

Failure body returned with every non-2xx JSON response; branch on the machine code, never on prose or on the HTTP status alone.

object
error
required

Stable machine code

string
requiredScope

The installation capability the presented credential lacks, returned with insufficient_scope so an integrator knows exactly which capability to request

string
retryAfterSeconds

Advisory seconds to wait before retrying; returned on rate-limit denials, where the Retry-After header carries the same value

integer
>= 1
key
additional properties
any
Example
{
"error": "cloud_session_not_found"
}

Idempotency, lifecycle, revision or single-flight conflict

Media typeapplication/json

Failure body returned with every non-2xx JSON response; branch on the machine code, never on prose or on the HTTP status alone.

object
error
required

Stable machine code

string
requiredScope

The installation capability the presented credential lacks, returned with insufficient_scope so an integrator knows exactly which capability to request

string
retryAfterSeconds

Advisory seconds to wait before retrying; returned on rate-limit denials, where the Retry-After header carries the same value

integer
>= 1
key
additional properties
any
Example
{
"error": "cloud_session_conflict"
}

The pre-authentication edge budget or durable human-membership/App-installation budget is exhausted

Media typeapplication/json

Failure body returned with every non-2xx JSON response; branch on the machine code, never on prose or on the HTTP status alone.

object
error
required

Stable machine code

string
requiredScope

The installation capability the presented credential lacks, returned with insufficient_scope so an integrator knows exactly which capability to request

string
retryAfterSeconds

Advisory seconds to wait before retrying; returned on rate-limit denials, where the Retry-After header carries the same value

integer
>= 1
key
additional properties
any
Example
{
"error": "cloud_rate_limit_exceeded",
"retryAfterSeconds": 3
}
Retry-After
integer
>= 1
RateLimit-Policy
string

IETF HTTPAPI structured quota policy

RateLimit
string

IETF HTTPAPI structured current service limit

A retryable workspace, runtime or provider condition

Media typeapplication/json

Failure body returned with every non-2xx JSON response; branch on the machine code, never on prose or on the HTTP status alone.

object
error
required

Stable machine code

string
requiredScope

The installation capability the presented credential lacks, returned with insufficient_scope so an integrator knows exactly which capability to request

string
retryAfterSeconds

Advisory seconds to wait before retrying; returned on rate-limit denials, where the Retry-After header carries the same value

integer
>= 1
key
additional properties
any
Example
{
"error": "cloud_workspace_unavailable"
}
Retry-After
integer