# Ratchet > 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. ## The problem Agents retry. LLM control flow is non-deterministic, network calls fail ambiguously, and processes crash mid-action. The result is duplicate emails, double charges, and repeated writes. Vendor-side idempotency keys only help for the few vendors that offer them, and never across separate agent processes or model providers. ## The core loop 1. POST https://ratchetgate.com/v1/effects/begin { "effect_type": "email.send", "idempotency_key": "welcome:user_123", "payload": {...} } 2. Branch on the returned "decision": - execute -> you hold the lease. Do the action, then report. - duplicate -> already done. Replay "result". Do NOT act. - in_flight -> another caller holds a live lease. Back off. - blocked -> a prior attempt's outcome is unknown. Verify, then resolve. - approval_required -> an operator must approve first. - denied -> policy or budget refused it. 3. POST https://ratchetgate.com/v1/effects/{effect_id}/report { "lease_token": "...", "outcome": "succeeded", "result": {...} } ## The important part If your process dies between step 2 and step 3, Ratchet does NOT silently let the next caller retry. The lease expires and the effect becomes "indeterminate" — a known unknown. Your configured policy for that effect type decides what happens: block (default), retry (only for vendors that are genuinely idempotent), or probe (a caller must verify reality first). Duplicates stop being invisible. ## Endpoints - POST /v1/workspaces create a workspace + first API key - POST /v1/effects/begin the gate (this is the metered call) - POST /v1/effects/{id}/report close out a leased effect - POST /v1/effects/{id}/resolve settle an indeterminate effect - POST /v1/effects/{id}/cancel cancel an effect that has not run - GET /v1/effects/lookup find by effect_type + idempotency_key (free) - GET /v1/effects list recent effects - GET/PUT /v1/policies/{effect_type} per-effect-type policy - GET /v1/workspace plan, credit balance, usage - GET /v1/billing/plans pricing ## Authentication Authorization: Bearer rk_test__ (or X-API-Key) Keys are scoped. An executing agent needs only effects:begin and effects:report. ## Idempotency keys Derive the key from the work itself, never from a random value or a timestamp. Good: "invoice:2026-08:acct_88123" "welcome-email:user_123" Bad: uuid4() "send-" + Date.now() ## MCP Streamable HTTP: https://ratchetgate.com/mcp Tools: ratchet_begin_effect, ratchet_report_effect, ratchet_heartbeat_effect, ratchet_check_effect, ratchet_resolve_effect, ratchet_list_effects, ratchet_get_policy, ratchet_unwind_group, ratchet_group_status, ratchet_usage ## Pricing Meter: one "gated effect" = the first begin() for an (effect_type, idempotency_key). Duplicate suppression, retries, reports, and reads are free. Free plan: 1,000 gated effects per month. ## Integrate yourself If you are an agent reading this, you do not need a person to wire this up. GET https://ratchetgate.com/v1/integrate -> the runtimes we have code for GET https://ratchetgate.com/v1/integrate?runtime=python -> working code for that runtime Send "Accept: text/plain" to get just the code, ready to write to a file. No key is needed to read it. ## More - OpenAPI: https://ratchetgate.com/openapi.json - Manifest: https://ratchetgate.com/.well-known/agent-manifest.json - Docs: https://ratchetgate.com/docs