Optional preflight policy decision (no reservation created)
Returns ALLOW / DENY, optionally with Caps for soft landing. This endpoint does not reserve budget. Clients that require concurrency safety MUST use /v1/reservations. IDEMPOTENCY (NORMATIVE): - On replay with the same idempotency_key, the server MUST return the original successful response payload. TENANCY (NORMATIVE): - subject.tenant MUST match the effective tenant derived from auth; otherwise the server MUST return 403 FORBIDDEN. DEBT/OVERDRAFT STATE (NORMATIVE): - If the subject scope has debt > 0 or is_over_limit=true, server SHOULD return decision=DENY with reason_code=DEBT_OUTSTANDING or reason_code=OVERDRAFT_LIMIT_EXCEEDED respectively. Server MUST NOT return 409 for these conditions on /decide. CLOSED TENANT (NORMATIVE): - If the owning tenant's status is CLOSED (deployments with a governance plane), a fresh (non-replay) evaluation MUST return decision=DENY with reason_code=TENANT_CLOSED, reflecting as-if-live the 409 TENANT_CLOSED the persisting mutation surface returns (same-key replays of pre-close decisions follow the IDEMPOTENCY rule above and the replayed-decision caveat below). Server MUST NOT return 409 for this condition on /decide. A tenant record whose status cannot be determined (malformed record) MUST fail closed with 500 INTERNAL_ERROR — see the closed-tenant binding in ERROR SEMANTICS.
Idempotency on /decide is for request deduplication only. A replayed ALLOW response reflects budget state at the time of the original call; clients MUST NOT treat a replayed decision as current budget authorization.
Request
- Base URL: https://api.cycles.local
- URL: https://api.cycles.local/v1/decide
- Auth: API key in header X-Cycles-API-Key
Headers
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 outcome and payload (including any server-generated identifiers such as reservation_id), except that remaining_ttl_ms on a replayed createReservation or extendReservation success is a volatile response observation and is not part of the attested CyclesEvidence payload. When emitted, it MUST be recomputed from the original expires_at_ms and the current authoritative server time, never copied from the stored response; it MUST be 0 if the reservation is no longer ACTIVE. All other fields replay verbatim.
Request body
Example request
{
"estimate": {
"unit": "USD_MICROCENTS",
"amount": 500000
}
}Response
Decision result
Example response
{
"decision": "ALLOW",
"affected_scopes": [
"tenant:acme-corp",
"tenant:acme-corp/workspace:prod"
]
}Changes
No recorded changes to this operation across all 1 revision of this API.