Dory is in development. The invite-only beta has not opened yet; prices and limits are planned and may change.

Idempotency and retries

An idempotency key identifies one intended mutation, including its original method, target and body. Generate it before the request, keep it through an uncertain network outcome, and reuse it only for that same operation. A fresh key after a timeout can create a second effect.

Wire behavior

  • Control API: Idempotency-Key (≤ 255 chars) is required on POST /computers, POST /computers/{id}/snapshots, POST /images, POST /billing/topups and POST /api-keys, and accepted on every other control API POST and PATCH . Kept 24 h per account with the request hash and response.
    • Same key, different body: 409 idempotency_mismatch. Same key while the first is still running: 409 idempotency_in_progress (+ Retry-After). Replay: original response + Idempotent-Replayed: true.
    • Credentials are never stored for replay. This covers every response that contains a credential: access tokens, preview access_url and cpt_ tokens, hook URLs, share-link URLs, API-key and webhook secrets. A replay returns the metadata with that field null and secret_already_returned: true. The SDK and CLI then tell the user to mint, create or rotate a new one.
  • Data plane: only POST /exec and POST /processes accept Idempotency-Key. For 24 h from initial acceptance, the computer's agent retains the canonical request hash and {proc_id, status} metadata, scoped to computer ID and route, not output. Same key with a different request body returns 409 idempotency_mismatch. Before the first request has a process record, a concurrent duplicate returns 409 idempotency_in_progress with Retry-After: 1. Once that record exists, a duplicate returns 200 application/json, Idempotent-Replayed: true, and {proc_id, status}, where status is running or exited. This replay response applies even if the original request selected stream or background; it never launches another process and never replays an NDJSON body. The supervisor updates status on exit and retains the terminal status for the rest of the deduplication window, independently of output retention. Fetch available output separately from GET /processes/{proc_id}/output; it may have expired after the one-hour retention period. Every other data-plane POST is not idempotent; the docs and SDKs say so.
  • SDK retry rule: retry control API calls on 429/503 with Retry-After. Retry data-plane calls only when the response has CE-Not-Forwarded: true. Never retry after 502/504 or a network error once the request was sent, except keyed exec/process start with the caller's original key.
  • Lifecycle verbs are naturally idempotent: stopping a stopped computer returns 200 with its state.

Replay is not renewed authority

An idempotent result does not waive current authentication, scope, restriction, expiry or hold checks. Some replies contain a secret that is returned only once; a replay can identify the resource without reissuing that secret. Follow SecretAlreadyReturned and ProcessReplay as distinct recovery paths. Keyed exec replay attaches to retained process identity; it does not rerun the command to reconstruct missing output.

For asynchronous effects, retain the operation ID and poll Operations. A local waiter timeout is not a cancel signal. Check current state before choosing another action, and never alter a body under the old key merely to bypass a refusal.

Dory is in development; these pages describe the planned service and may change. Questions: support@computeengines.com.