{"openapi":"3.1.0","info":{"title":"Ratchet API","version":"0.1.0","description":"An effect gate for AI agents. Ask before you act; Ratchet answers durably so the same real-world side effect is attempted at most once, stays inside a declared budget, and leaves an auditable record.","license":{"name":"Apache-2.0"}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A scoped Ratchet API key: rk_<env>_<prefix>_<secret>"}},"schemas":{}},"paths":{"/v1/effects/begin":{"post":{"operationId":"beginEffect","summary":"Ask permission to perform a side effect","tags":["Effects"],"description":"The gate. Returns a decision that tells the caller whether to perform the action, replay a recorded result, wait, or stop. Call this immediately BEFORE the side effect, and report the outcome immediately after.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["effect_type","idempotency_key"],"additionalProperties":false,"properties":{"effect_type":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9]([a-z0-9._-]{0,62}[a-z0-9])?$","description":"Namespaced kind of side effect, e.g. \"email.send\" or \"payment.charge\". Policy is configured per type."},"idempotency_key":{"type":"string","minLength":1,"maxLength":255,"description":"Stable identifier for this logical action. Derive it from the work itself (e.g. a hash of recipient + template + period), never from a random value or a timestamp."},"payload":{"description":"The action being gated. Only a fingerprint is stored; the raw value is never persisted. Reusing a key with a different payload is rejected."},"estimated_cost_micros":{"type":"integer","minimum":0,"maximum":1000000000,"default":0,"description":"Declared external cost of this effect in micro-USD (1e-6 USD). Used only for budget ceilings; Ratchet never collects it."},"agent_id":{"type":"string","maxLength":128,"description":"Which agent is acting. For operator visibility."},"run_id":{"type":"string","maxLength":128,"description":"Groups effects belonging to one agent run."},"request_summary":{"type":"object","additionalProperties":true,"description":"Small, non-sensitive metadata shown in the console. Redact secrets before sending."},"lease_seconds":{"type":"integer","minimum":5,"maximum":3600,"description":"Requested lease length. Clamped to the policy maximum for this effect type."},"group_key":{"type":"string","maxLength":255,"description":"Declares this effect part of a unit of work that can be rolled back as a whole. Use one stable key per logical workflow, e.g. \"booking:trip_8812\"."},"compensation":{"type":"object","required":["effect_type","payload"],"additionalProperties":false,"description":"How to undo this effect if the unit of work has to be rolled back. Declare it now, while you still know what undoing means — it cannot be reconstructed later.","properties":{"effect_type":{"type":"string","maxLength":64,"pattern":"^[a-z0-9]([a-z0-9._-]{0,62}[a-z0-9])?$"},"payload":{"description":"Arguments the compensating action will need."}}},"compensates_effect_id":{"type":"string","maxLength":64,"description":"Set when THIS effect is the compensation for another. Reporting it succeeded marks the original reversed."}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["decision","effect_id","effect_type","idempotency_key","state","attempt"],"properties":{"decision":{"type":"string","enum":["execute","duplicate","in_flight","blocked","approval_required","denied"],"description":"execute: you hold the lease, perform the effect. duplicate: already done, replay `result`, do NOT perform it. in_flight: another caller holds a live lease. blocked: a prior attempt's real-world outcome is unknown. approval_required: an operator must approve first. denied: policy, budget, or a rejected approval refused it."},"effect_id":{"type":"string"},"effect_type":{"type":"string"},"idempotency_key":{"type":"string"},"state":{"type":"string","enum":["awaiting_approval","pending","succeeded","failed","indeterminate","denied","cancelled"]},"attempt":{"type":"integer"},"lease_token":{"type":"string","description":"Present only when decision is \"execute\". Required to report the outcome."},"lease_expires_at":{"type":"string","format":"date-time"},"result":{"description":"Present when decision is \"duplicate\": the recorded outcome to replay."},"retry_after_seconds":{"type":"integer"},"reason":{"type":"string"},"prior_attempt":{"type":"object","properties":{"attempt":{"type":"integer"},"state":{"type":"string"},"started_at":{"type":"string","format":"date-time"},"last_known_at":{"type":"string","format":"date-time"},"on_indeterminate":{"type":"string","enum":["block","retry","probe"]}}},"billing":{"type":"object","properties":{"metered":{"type":"boolean","description":"True only when this call created a new gated effect."},"included_remaining":{"type":["null","integer"]}}}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/{effectId}/report":{"post":{"operationId":"reportEffect","summary":"Report the outcome of a leased effect","tags":["Effects"],"description":"Closes out an effect you hold the lease for. Reporting \"succeeded\" records a result that later duplicate callers replay instead of re-running the action. Reporting \"failed\" asserts the action did not happen, which permits a fresh attempt.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lease_token","outcome"],"additionalProperties":false,"properties":{"lease_token":{"type":"string","minLength":8,"maxLength":128},"outcome":{"type":"string","enum":["succeeded","failed"],"description":"Report \"failed\" ONLY when you know the side effect did not reach the outside world. If you are unsure, report nothing and let the lease lapse — that records an honest `indeterminate`."},"result":{"description":"Recorded and replayed verbatim to future duplicate callers."},"failure_reason":{"type":"string","maxLength":1024},"actual_cost_micros":{"type":"integer","minimum":0,"maximum":1000000000}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"effect_id":{"type":"string"},"state":{"type":"string"},"attempt":{"type":"integer"},"settled_at":{"type":["null","string"]},"actual_cost_micros":{"type":"integer"}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/{effectId}/heartbeat":{"post":{"operationId":"extendLease","summary":"Tell Ratchet you are still working","tags":["Effects"],"description":"Extends a lease you still hold. Use it for work that may outrun its lease: keep the lease short so a real crash is caught quickly, and heartbeat while you are alive. An expired or superseded lease cannot be revived — by then the outcome is already recorded as unknown, and erasing that would defeat the point.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lease_token"],"additionalProperties":false,"properties":{"lease_token":{"type":"string","minLength":8,"maxLength":128},"extend_seconds":{"type":"integer","minimum":5,"maximum":3600,"description":"Fresh lease length from now. Clamped to the policy maximum."}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/{effectId}/resolve":{"post":{"operationId":"resolveEffect","summary":"Settle an indeterminate effect after verifying reality","tags":["Effects"],"description":"The escape hatch that makes a \"block\" policy safe: once you have checked the vendor and know what actually happened, record it here. The effect leaves the indeterminate state and normal begin() semantics resume.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["outcome"],"additionalProperties":false,"properties":{"outcome":{"type":"string","enum":["succeeded","failed","cancelled"]},"evidence":{"type":"string","maxLength":2048,"description":"How you verified the real-world outcome. Stored in the audit trail."},"result":{"description":"Recorded when outcome is \"succeeded\", and replayed to duplicate callers."}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/{effectId}/cancel":{"post":{"operationId":"cancelEffect","summary":"Cancel an effect that has not executed","tags":["Effects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string","maxLength":1024}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/{effectId}/approval":{"post":{"operationId":"decideApproval","summary":"Approve or reject an effect awaiting a human decision","tags":["Effects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["approve"],"additionalProperties":false,"properties":{"approve":{"type":"boolean"},"note":{"type":"string","maxLength":1024}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/{effectId}":{"get":{"operationId":"getEffect","summary":"Fetch one effect record","tags":["Effects"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"effect_id":{"type":"string"},"effect_type":{"type":"string"},"idempotency_key":{"type":"string"},"state":{"type":"string"},"attempt":{"type":"integer"},"result":{},"failure_reason":{"type":["null","string"]},"denial_reason":{"type":["null","string"]},"agent_id":{"type":["null","string"]},"run_id":{"type":["null","string"]},"estimated_cost_micros":{"type":"integer"},"actual_cost_micros":{"type":"integer"},"lease_expires_at":{"type":["null","string"]},"approval_state":{"type":["null","string"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"settled_at":{"type":["null","string"]}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects/lookup":{"get":{"operationId":"lookupEffect","summary":"Look up an effect by type and idempotency key","tags":["Effects"],"description":"A free, non-metered read. Useful for reconciling state after a crash without consuming allowance.","parameters":[{"schema":{"type":"string"},"in":"query","name":"effect_type","required":true},{"schema":{"type":"string"},"in":"query","name":"idempotency_key","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"effect_id":{"type":"string"},"effect_type":{"type":"string"},"idempotency_key":{"type":"string"},"state":{"type":"string"},"attempt":{"type":"integer"},"result":{},"failure_reason":{"type":["null","string"]},"denial_reason":{"type":["null","string"]},"agent_id":{"type":["null","string"]},"run_id":{"type":["null","string"]},"estimated_cost_micros":{"type":"integer"},"actual_cost_micros":{"type":"integer"},"lease_expires_at":{"type":["null","string"]},"approval_state":{"type":["null","string"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"settled_at":{"type":["null","string"]}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/effects":{"get":{"operationId":"listEffects","summary":"List recent effects","tags":["Effects"],"parameters":[{"schema":{"type":"string","enum":["awaiting_approval","pending","succeeded","failed","indeterminate","denied","cancelled"]},"in":"query","name":"state","required":false},{"schema":{"type":"string"},"in":"query","name":"effect_type","required":false},{"schema":{"type":"string"},"in":"query","name":"run_id","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"effect_id":{"type":"string"},"effect_type":{"type":"string"},"idempotency_key":{"type":"string"},"state":{"type":"string"},"attempt":{"type":"integer"},"result":{},"failure_reason":{"type":["null","string"]},"denial_reason":{"type":["null","string"]},"agent_id":{"type":["null","string"]},"run_id":{"type":["null","string"]},"estimated_cost_micros":{"type":"integer"},"actual_cost_micros":{"type":"integer"},"lease_expires_at":{"type":["null","string"]},"approval_state":{"type":["null","string"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"settled_at":{"type":["null","string"]}}}}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/groups/{groupKey}/unwind":{"post":{"operationId":"unwindGroup","summary":"Roll back a unit of work and get the compensation plan","tags":["Groups"],"description":"Marks the group as unwinding — it will refuse new forward steps — and returns the exact compensations to perform, in reverse completion order. Ratchet does not perform them: gate each one with begin (using its suggested idempotency key, so the undo is itself at-most-once), do the work, then report it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string","maxLength":1024}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"groupKey","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"group_id":{"type":"string"},"group_key":{"type":"string"},"state":{"type":"string","enum":["open","committed","unwinding","unwound","unwind_failed"]},"reason":{"type":["null","string"]},"steps":{"type":"array","description":"Compensations to perform, in the order given — reverse of completion order.","items":{"type":"object","additionalProperties":true}},"irreversible":{"type":"array","description":"Effects that succeeded but declared no compensation. These cannot be rolled back automatically.","items":{"type":"object","additionalProperties":true}},"unresolved":{"type":"array","description":"Effects whose real-world outcome is unknown. Resolve these BEFORE rolling back around them.","items":{"type":"object","additionalProperties":true}},"next_step":{"type":"string"}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/groups/{groupKey}/commit":{"post":{"operationId":"commitGroup","summary":"Mark a unit of work complete","tags":["Groups"],"description":"Records that every step succeeded. A committed group can still be unwound later if the outcome turns out to be wrong.","parameters":[{"schema":{"type":"string"},"in":"path","name":"groupKey","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/groups/{groupKey}":{"get":{"operationId":"getGroup","summary":"Inspect a unit of work and what remains to undo","tags":["Groups"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"groupKey","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"group_id":{"type":"string"},"group_key":{"type":"string"},"state":{"type":"string","enum":["open","committed","unwinding","unwound","unwind_failed"]},"reason":{"type":["null","string"]},"steps":{"type":"array","description":"Compensations to perform, in the order given — reverse of completion order.","items":{"type":"object","additionalProperties":true}},"irreversible":{"type":"array","description":"Effects that succeeded but declared no compensation. These cannot be rolled back automatically.","items":{"type":"object","additionalProperties":true}},"unresolved":{"type":"array","description":"Effects whose real-world outcome is unknown. Resolve these BEFORE rolling back around them.","items":{"type":"object","additionalProperties":true}},"next_step":{"type":"string"}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/groups":{"get":{"operationId":"listGroups","summary":"List recent units of work","tags":["Groups"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":200},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/workspaces":{"post":{"operationId":"createWorkspace","summary":"Create a workspace and its first API key","tags":["Workspace"],"description":"Self-serve signup. Returns the API key exactly once — it is stored only as a keyed hash and cannot be retrieved again. Also returns a console session cookie.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","email"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"email":{"type":"string","format":"email","maxLength":254}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"workspace_id":{"type":"string"},"name":{"type":"string"},"api_key":{"type":"string","description":"Shown once. Store it securely."},"api_key_prefix":{"type":"string"},"plan":{"type":"string"},"console_url":{"type":"string"}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/console/signout":{"post":{"operationId":"consoleSignOut","summary":"Destroy the console session cookie","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/workspace":{"get":{"operationId":"getWorkspace","summary":"Plan, prepaid balance, and current-period usage","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/keys":{"get":{"operationId":"listApiKeys","summary":"List API keys (secrets are never returned)","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}},"post":{"operationId":"createApiKey","summary":"Mint a scoped API key","tags":["Workspace"],"description":"Grant only the scopes an agent needs. A worker that performs effects needs effects:begin and effects:report, and nothing else.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"scopes":{"type":"array","items":{"type":"string","enum":["effects:begin","effects:report","effects:read","effects:admin","policies:read","policies:write","workspace:read"]},"maxItems":10},"daily_budget_micros":{"type":["integer","null"],"minimum":0,"description":"Hard ceiling on external spend this key may declare per UTC day."}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/keys/{keyId}":{"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key immediately","tags":["Workspace"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"keyId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/policies":{"get":{"operationId":"listPolicies","summary":"List configured effect-type policies","tags":["Policies"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"effect_type":{"type":"string"},"mode":{"type":"string","enum":["allow","require_approval","deny"]},"on_indeterminate":{"type":"string","enum":["block","retry","probe"]},"lease_seconds":{"type":"integer"},"max_attempts":{"type":"integer"},"max_cost_micros":{"type":["null","integer"]},"daily_budget_micros":{"type":["null","integer"]},"retention_days":{"type":"integer"},"is_default":{"type":"boolean"}}}}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/policies/{effectType}":{"get":{"operationId":"getPolicy","summary":"Resolve the effective policy for an effect type","tags":["Policies"],"description":"Returns the workspace default with is_default=true when no explicit policy exists.","parameters":[{"schema":{"type":"string"},"in":"path","name":"effectType","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"effect_type":{"type":"string"},"mode":{"type":"string","enum":["allow","require_approval","deny"]},"on_indeterminate":{"type":"string","enum":["block","retry","probe"]},"lease_seconds":{"type":"integer"},"max_attempts":{"type":"integer"},"max_cost_micros":{"type":["null","integer"]},"daily_budget_micros":{"type":["null","integer"]},"retention_days":{"type":"integer"},"is_default":{"type":"boolean"}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}},"put":{"operationId":"upsertPolicy","summary":"Create or replace the policy for an effect type","tags":["Policies"],"description":"on_indeterminate is the important field. \"block\" (the default) refuses to auto-retry an effect whose real-world outcome is unknown. Use \"retry\" only when the underlying vendor is genuinely idempotent, and \"probe\" when a caller must verify first.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"mode":{"type":"string","enum":["allow","require_approval","deny"]},"on_indeterminate":{"type":"string","enum":["block","retry","probe"]},"lease_seconds":{"type":"integer","minimum":5,"maximum":3600},"max_attempts":{"type":"integer","minimum":1,"maximum":50},"max_cost_micros":{"type":["integer","null"],"minimum":0},"daily_budget_micros":{"type":["integer","null"],"minimum":0},"retention_days":{"type":"integer","minimum":1,"maximum":400}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectType","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"effect_type":{"type":"string"},"mode":{"type":"string","enum":["allow","require_approval","deny"]},"on_indeterminate":{"type":"string","enum":["block","retry","probe"]},"lease_seconds":{"type":"integer"},"max_attempts":{"type":"integer"},"max_cost_micros":{"type":["null","integer"]},"daily_budget_micros":{"type":["null","integer"]},"retention_days":{"type":"integer"},"is_default":{"type":"boolean"}}}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}},"delete":{"operationId":"deletePolicy","summary":"Remove a policy and fall back to workspace defaults","tags":["Policies"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"effectType","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"List webhook endpoints","tags":["Webhooks"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}},"post":{"operationId":"createWebhook","summary":"Register a signed webhook endpoint","tags":["Webhooks"],"description":"Destinations must be https DNS hostnames on port 80/443. Private, loopback, and link-local addresses are refused both at registration and again at delivery time. Redirects are never followed. The signing secret is returned once.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"additionalProperties":false,"properties":{"url":{"type":"string","maxLength":2048},"events":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","enum":["effect.succeeded","effect.failed","effect.indeterminate","effect.approval_required","effect.approved","effect.rejected","effect.denied","budget.exceeded"]}}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","summary":"Disable a webhook endpoint","tags":["Webhooks"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/webhooks/deliveries":{"get":{"operationId":"listWebhookDeliveries","summary":"Recent delivery attempts","tags":["Webhooks"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/email/preferences":{"get":{"operationId":"getEmailPreferences","summary":"Which alerts this workspace receives","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/email/preferences/{category}":{"put":{"operationId":"setEmailPreference","summary":"Turn one alert category on or off","tags":["Workspace"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["enabled"],"additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"category","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/email/messages":{"get":{"operationId":"listEmails","summary":"Recent alerts sent to this workspace","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/usage/ledger":{"get":{"operationId":"listLedger","summary":"Immutable record of every credit movement","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/audit":{"get":{"operationId":"listAudit","summary":"Audit trail","tags":["Workspace"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/billing/plans":{"get":{"operationId":"listPlans","summary":"Plans and credit packs","tags":["Billing"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/billing/crypto/assets":{"get":{"operationId":"listCryptoAssets","summary":"Assets this instance accepts, and on what terms","tags":["Billing"],"description":"Which assets are acceptable is operator policy — a payer cannot introduce one or set its terms. Ratchet is non-custodial: it holds no key and takes custody of nothing.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/billing/crypto/intents":{"post":{"operationId":"createCryptoIntent","summary":"Quote a crypto payment for prepaid credit","tags":["Billing"],"description":"Returns an address, an exact token amount, and a memo. Credit is applied only after the transfer confirms on-chain. A transfer short of the quote is not credited.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token_mint","usd_micros"],"additionalProperties":false,"properties":{"token_mint":{"type":"string","maxLength":64},"chain":{"type":"string","enum":["solana","ethereum","base","bitcoin"]},"usd_micros":{"type":"integer","minimum":1,"maximum":100000000000}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"get":{"operationId":"listCryptoIntents","summary":"Recent crypto payment intents and their state","tags":["Billing"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/billing/crypto/intents/{intentId}/submit":{"post":{"operationId":"submitCryptoTransaction","summary":"Submit a transaction hash for a chain without a memo","tags":["Billing"],"description":"Ethereum, Base, and Bitcoin transfers carry no memo, so a payment cannot identify itself. Submit the transaction hash and Ratchet verifies it on-chain: destination, asset, amount, and confirmations are all re-derived rather than trusted. A transaction can only ever settle one payment.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tx_hash"],"additionalProperties":false,"properties":{"tx_hash":{"type":"string","minLength":64,"maxLength":66}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"intentId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/billing/checkout":{"post":{"operationId":"startCheckout","summary":"Begin a prepaid credit purchase","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pack_id"],"additionalProperties":false,"properties":{"pack_id":{"type":"string","enum":["pack_25","pack_100","pack_500"]}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/billing/subscribe":{"post":{"operationId":"startSubscription","summary":"Subscribe to a paid plan","tags":["Billing"],"description":"Returns a hosted checkout URL. The plan is granted when the signed webhook confirms the subscription — never on the browser returning to the success URL.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan_id"],"additionalProperties":false,"properties":{"plan_id":{"type":"string","enum":["pro","scale"]}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/billing/test/settle":{"post":{"operationId":"settleTestCheckout","summary":"Settle a test-mode credit purchase (no real charge)","tags":["Billing"],"description":"Available only while the test billing adapter is active. Idempotent on session_id, exactly as a live provider webhook would be.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["session_id","pack_id"],"additionalProperties":false,"properties":{"session_id":{"type":"string","maxLength":200},"pack_id":{"type":"string","enum":["pack_25","pack_100","pack_500"]}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}}}}},"/v1/billing/webhook/stripe":{"post":{"operationId":"stripeWebhook","summary":"Stripe webhook receiver (signature-verified)","tags":["Billing"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Invalid request."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Missing or invalid API key."}}}},"402":{"description":"Insufficient prepaid credit.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Insufficient prepaid credit."}}}},"403":{"description":"Scope, policy, or budget refusal.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Scope, policy, or budget refusal."}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Not found."}}}},"409":{"description":"Conflicting state or idempotency-key reuse.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Conflicting state or idempotency-key reuse."}}}},"413":{"description":"Payload too large.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Payload too large."}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code."},"message":{"type":"string"},"detail":{"type":"object","additionalProperties":true}}}},"description":"Rate limit exceeded."}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/healthz":{"get":{"operationId":"healthz","summary":"Liveness probe","tags":["Meta"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/readyz":{"get":{"operationId":"readyz","summary":"Readiness probe (checks the database)","tags":["Meta"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/.well-known/agent-manifest.json":{"get":{"operationId":"agentManifest","summary":"Capability manifest for agent discovery","tags":["Meta"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/integrate":{"get":{"operationId":"integrate","summary":"Runnable integration code for a given runtime","tags":["Meta"],"description":"Returns working code for the caller's own runtime. Omit \"runtime\" to list what is available. Send Accept: text/plain to get just the code, ready to pipe to a file.","parameters":[{"schema":{"type":"string","maxLength":32},"in":"query","name":"runtime","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/llms.txt":{"get":{"operationId":"llmsTxt","summary":"Concise machine-oriented documentation index","tags":["Meta"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/mcp/info":{"get":{"operationId":"mcpInfo","summary":"MCP server metadata and tool list","tags":["Meta"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}}},"servers":[{"url":"https://ratchetgate.com","description":"This instance"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Effects","description":"The gate: begin, report, resolve."},{"name":"Groups","description":"Units of work that can be rolled back as a whole."},{"name":"Policies","description":"Per-effect-type rules for retries, budgets, and approval."},{"name":"Workspace","description":"Keys, usage, ledger, audit."},{"name":"Webhooks","description":"Signed event delivery."},{"name":"Billing","description":"Plans and prepaid credit."},{"name":"Meta","description":"Health, manifest, discovery."}]}