Skip to content

Reserve budget for a planned action (concurrency-safe)

POST
/v1/reservations

Atomically reserves the estimated amount across server-derived scopes and returns a reservation_id. Reservations expire at expires_at_ms; commits are accepted through (expires_at_ms + grace_period_ms).
If dry_run=true, server MUST evaluate the full reservation request and return decision/caps/affected_scopes/balances as if the reservation were live, but MUST NOT modify balances, persist a reservation, or require commit/release.
DRY-RUN RESPONSE RULES (NORMATIVE): - reservation_id and expires_at_ms MUST be absent. - affected_scopes MUST be populated regardless of decision outcome (ALLOW / ALLOW_WITH_CAPS / DENY). - If decision=ALLOW_WITH_CAPS, caps MUST be present; otherwise caps MUST be absent. - If decision=DENY, reason_code SHOULD be populated; it is the primary diagnostic signal for why the dry_run was denied. - balances MAY be populated (recommended for operator visibility), but MUST reflect a non-mutating evaluation.
OVER-LIMIT BLOCKING (NORMATIVE): - If ANY affected scope has debt > overdraft_limit (is_over_limit=true), the reservation MUST be rejected
with 409 OVERDRAFT_LIMIT_EXCEEDED, regardless of available remaining budget.

  • This blocks new work when overdraft reconciliation is needed.
    IDEMPOTENCY (NORMATIVE): - On replay with the same idempotency_key, the server MUST return the original successful response payload, including the original reservation_id (if any).
    TENANCY (NORMATIVE): - subject.tenant MUST match the effective tenant derived from auth; otherwise the server MUST return 403 FORBIDDEN.

Authorizations

ApiKeyAuth
Type
API Key (header: X-Cycles-API-Key)

Parameters

Header Parameters

X-Idempotency-Key

Optional idempotency key header. If both header and body idempotency_key are provided, they MUST match. Server MUST enforce idempotency per endpoint by (effective tenant, endpoint, idempotency_key). On replay of an idempotent request that previously succeeded, server MUST return the original successful response payload (including any server-generated identifiers such as reservation_id).

Type
string
Min Length
1
Max Length
256

Request Body

application/json
JSON
{
  
"idempotency_key": "string",
  
"subject": "string",
  
"action": {
  
  
"kind": "string",
  
  
"name": "string",
  
  
"tags": [
  
  
  
"string"
  
  
]
  
},
  
"estimate": {
  
  
"unit": "string",
  
  
"amount": 0
  
},
  
"ttl_ms": 60000,
  
"grace_period_ms": 5000,
  
"overage_policy": "REJECT",
  
"dry_run": false,
  
"metadata": {
  
  
"additionalProperties": "string"
  
}
}

Responses

Reservation decision (ALLOW/DENY with optional caps)

application/json
JSON
{
  
"decision": "string",
  
"reservation_id": "string",
  
"reserved": {
  
  
"unit": "string",
  
  
"amount": 0
  
},
  
"expires_at_ms": 0,
  
"scope_path": "string",
  
"affected_scopes": [
  
  
"string"
  
],
  
"caps": {
  
  
"max_tokens": 0,
  
  
"max_steps_remaining": 0,
  
  
"tool_allowlist": [
  
  
  
"string"
  
  
],
  
  
"tool_denylist": [
  
  
  
"string"
  
  
],
  
  
"cooldown_ms": 0
  
},
  
"balances": [
  
  
{
  
  
  
"scope": "string",
  
  
  
"scope_path": "string",
  
  
  
"remaining": {
  
  
  
  
"unit": "string",
  
  
  
  
"amount": 0
  
  
  
},
  
  
  
"reserved": {
  
  
  
  
"unit": "string",
  
  
  
  
"amount": 0
  
  
  
},
  
  
  
"spent": {
  
  
  
  
"unit": "string",
  
  
  
  
"amount": 0
  
  
  
},
  
  
  
"debt": {
  
  
  
  
"unit": "string",
  
  
  
  
"amount": 0
  
  
  
},
  
  
  
"allocated": {
  
  
  
  
"unit": "string",
  
  
  
  
"amount": 0
  
  
  
},
  
  
  
"overdraft_limit": {
  
  
  
  
"unit": "string",
  
  
  
  
"amount": 0
  
  
  
},
  
  
  
"is_over_limit": true
  
  
}
  
],
  
"reason_code": "string",
  
"retry_after_ms": 0
}

Playground

Authorization
Headers
Body

Samples

Powered by VitePress OpenAPI