Docs
Dashboard
API reference / BasicsBeta

Idempotency keys

Retry a request that creates something without creating it twice.

A network error can leave you not knowing whether a request arrived. Retrying a request that creates something could then create it twice: two sessions, two agent runs. An idempotency key prevents that. It is a unique value you make up for each operation, such as a UUID, and send as the Idempotency-Key header.

How it works

  • The same key with the same body within 24 hours returns the first response again, with the same status and body, and the header Idempotent-Replayed: true. Nothing is created or started twice. A replay counts against the route’s rate limit like any request.
  • Bodies count as the same when their JSON is equal; the order of the keys does not matter.
  • The same key with a different body, or on another route: 422 idempotency_mismatch. Make a new key for a new operation.
  • While the first request with that key is still being answered: 409 idempotency_in_progress. Try again shortly, with the same key.
  • Only successful (2xx) responses of up to 64 KB are kept. After an error, the same key can be sent again and the request really runs. If a server stops before it answers, the key is free again after 10 minutes.
  • Keys belong to your project: all its API keys and console logins share them. One exception: a new API key (POST /v1/project/api-keys) is replayed only to the same caller (the same API key or console login; anyone else gets 422), and revoking that key forgets the kept response.
  • For agent runs, the values of variables are not compared, because they are never stored in any form. A retry with the same key and other values gets the first run.
  • You can make up to 300 new keys per minute per project (429 after that). A key that is not 1 to 255 printable characters without spaces gets 400 invalid_idempotency_key.

Where it works

RouteReference
POST /v1/crawlsStart a crawl
POST /v1/sessionsCreate a session
POST /v1/sessions/bulkStop, resume or delete many sessions
POST /v1/agent/runsStart a run
POST /v1/agent/runs/{id}/messagesSend a message to a run
POST /v1/agent/runs/{id}/resumeResume a run
POST /v1/tasksCreate a task
POST /v1/tasks/{id}/runsRun a task
POST /v1/profilesCreate a profile
POST /v1/extensionsUpload an extension
POST /v1/project/api-keysCreate an API key

Other routes ignore the header. POST /v1/sessions/:id/browser/script streams its output, so it is never replayed: sending it again runs the script again.

Example

IDEMPOTENCY_KEY=$(uuidgen)   # one key per operation, reused for its retriescurl -X POST https://api.boxline.dev/v1/sessions \  -H "x-api-key: $BOXLINE_API_KEY" \  -H "content-type: application/json" \  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \  -d '{"timeout": 600}'

The SDKs send a key with every call to the routes above, and reuse it when they retry, so their own retries never start anything twice. Pass your own key when you may send the same request again, such as a job that restarts. The same key with a different body gets 422 idempotency_mismatch (IdempotencyMismatchError in the SDKs). While the first request is still being answered, a second one gets 409 idempotency_in_progress with Retry-After: 1; the SDKs wait and try again by themselves.

These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.