Ask for the session's latest checkpoint to be pushed
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.
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
repository_id?string1 <= length <= 128branch?string^[a-z0-9][a-z0-9-]{0,39}$checkpoint_revision?integer0 <= value <= 2147483647The request, pinned and waiting for a decision.
application/json- response
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)$uuidsession_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)$uuidrepository_id*string1 <= lengthcheckpoint_revision*integer0 <= value <= 2147483647git_commit*string^[0-9a-f]{40}$target_branch*string1 <= lengthstate*string"requested""approved""rejected""pushing""pushed""failed"requested_by*requested_at*string^(?:(?:\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))$date-timeresolved_by*||nullresolved_at*|nullresolution_reason*string|nullrequest_receipt_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)$uuidresolution_receipt_id*|nullfinished_at*|nullpush_receipt_id*|nullorigin*string"direct""direct""intent"flow*string"legacy""legacy""actions"pr_state*|nullpr_error*|nullpr_number*|nullpr_url*|nullcurl -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"}'{ "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}