레퍼런스HTTP APISession control

Run the session's next turns on another profile

POST
/v1/sessions/{id}/profile

Moves an active, paused or stopped session onto profile_id, a profile this host's catalog allows with the session's repository, or, for a session created without one, a profile whose repository_mode is optional or none. It takes effect at the next turn that starts: a turn running now finishes on the profile it started with, and its worker then leaves so the next one claims the new profile and restores the session's checkpoint, conversation included. The session then runs the new profile's default model, whatever model it was created with. Earlier turns keep their record and cost; each turn's attempts[].profile_id says what it ran on.

The new profile must run the same runtime kind and version, since the next worker restores checkpoints that runtime took, and must be billed the same way (billing: none or not), since the session's cost limit stays as it is. A session created from an agent release runs the release's profile and answers 409 RELEASE_PROFILE_MISMATCH. The change settles in the request: the receipt is succeeded with result {previous_profile_id, profile_id}, and a status event on the stream carries both. Naming the profile the session already runs changes nothing and still answers succeeded.

Scope: sessions:control (API key or cookie session). Idempotency-Key: required.

Authorization

headerAuthorizationBearer <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:control

Path Parameters

id*string

The session's id.

Match^([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)$
Formatuuid

Header Parameters

Idempotency-Key*string

Required, 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.

Length1 <= length <= 255
X-Requested-With?"werft-web"

Required with a cookie session: the literal werft-web.

Value in"werft-web"

Request Body

application/json
  1. body
expected_revision*integer
Range0 <= value <= 2147483647
profile_id*string
Length1 <= length

Response Body

The session runs profile_id from its next turn on.

application/json
  1. response
receipt_id*string
Match^([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)$
Formatuuid
receipt_status*string
Value in"accepted""succeeded""failed""unknown"
Example Request
curl -X POST 'https://example.com/v1/sessions/497f6eca-6276-4993-bfeb-53cbbbba6f08/profile' \  -H 'Idempotency-Key: string' \  -H 'Content-Type: application/json' \  -d '{  "expected_revision": 8,  "profile_id": "claude-coding-fast"}'
Example Response
{  "receipt_id": "c4a1e9d2-7b3f-4e8a-a6c5-1d2e3f4a5b6c",  "receipt_status": "succeeded"}