레퍼런스HTTP APIPush requests

Ask for the session's latest checkpoint to be pushed

POST
/v1/sessions/{id}/push-requests

Pins the session's latest committed checkpoint: its checkpoint_revision, the git_commit its verified manifest names, the repository and the target branch. The commit cannot be chosen. checkpoint_revision (default: the latest committed one) may name the revision you looked at; it is refused as checkpoint_moved once a newer one has been saved. Work the session did after that revision may not be in it. repository_id (default: the session's own) may name another catalog repository the session's release lists in github.repositories and its profile allows; the session's workspace has it as a git remote of that name. branch (default: none) makes the target agent/<session-id>-<branch> instead of agent/<session-id>, so one session can push to several branches, each its own pull request. The request starts requested and nothing is pushed until a holder of sessions:approve approves it (POST .../push-requests/{push_request_id}/approve); the push itself is the platform's, never the worker's.

A session has at most one open request (requested, approved or pushing) per repository and branch; there is no limit on how many it makes. Every attempt, refused ones included, leaves a request_push receipt naming the repository and branch; a refusal's error.details.receipt_id names it. A replayed Idempotency-Key answers the request it created.

Scope: sessions:write (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:write

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
repository_id?string
Length1 <= length <= 128
branch?string
Match^[a-z0-9][a-z0-9-]{0,39}$
checkpoint_revision?integer
Range0 <= value <= 2147483647

Response Body

The request, pinned and waiting for a decision.

application/json
  1. response
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
session_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
repository_id*string
Length1 <= length
checkpoint_revision*integer
Range0 <= value <= 2147483647
git_commit*string
Match^[0-9a-f]{40}$
target_branch*string
Length1 <= length
state*string
Value in"requested""approved""rejected""pushing""pushed""failed"
requested_by*
requested_at*string
Match^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
Formatdate-time
resolved_by*||null
resolved_at*|null
resolution_reason*string|null
request_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
resolution_receipt_id*|null
finished_at*|null
push_receipt_id*|null
origin*string
Default"direct"
Value in"direct""intent"
flow*string
Default"legacy"
Value in"legacy""actions"
pr_state*|
Defaultnull
pr_error*|
Defaultnull
pr_number*|
Defaultnull
pr_url*|
Defaultnull
Example Request
curl -X POST 'https://example.com/v1/sessions/497f6eca-6276-4993-bfeb-53cbbbba6f08/push-requests' \  -H 'Idempotency-Key: string' \  -H 'Content-Type: application/json' \  -d '{  "repository_id": "docs",  "branch": "fix-typo"}'
Example Response
{  "id": "5b9e2c17-4f3a-4d6e-8a1b-7c0d9e2f3a41",  "session_id": "0f8b6a52-3d1e-4c7a-9b2f-5e6d7c8a9b01",  "repository_id": "sample-app",  "checkpoint_revision": 3,  "git_commit": "4f2a9c1e7b3d5a8f0c6e2b9d1a4f7c3e5b8d0a2c",  "target_branch": "agent/0f8b6a52-3d1e-4c7a-9b2f-5e6d7c8a9b01",  "state": "requested",  "requested_by": {    "principal": {      "kind": "user",      "id": "3e7f1a90-5c2d-4b8e-8f61-2a9d0c4b7e35"    },    "actor_user_id": "3e7f1a90-5c2d-4b8e-8f61-2a9d0c4b7e35",    "agent_id": null  },  "requested_at": "2026-10-11T08:30:00Z",  "resolved_by": null,  "resolved_at": null,  "resolution_reason": null,  "request_receipt_id": "c4a1e9d2-7b3f-4e8a-a6c5-1d2e3f4a5b6c",  "resolution_receipt_id": null,  "finished_at": null,  "push_receipt_id": null}