Skip to content

Idempotency

Send Idempotency-Key on a POST under /v1 or /portal and a retry with the same key returns the first answer instead of doing the work twice. It matters most on the routes that create something — most directly, POST /v1/issues and POST /portal/requests — where a retried request without it would create a second issue.

Terminal window
curl -X POST https://api.pealboard.com/v1/issues \
-H "Authorization: Bearer pb_AbCdEf0123456789AbCdEf0123456789AbCdEf01" \
-H "X-Workspace-Id: 3fae5b2a-6c9e-4b2b-9c39-2e5e5b7a1a11" \
-H "Idempotency-Key: 7c2b9e10-4a3f-4e7a-9b3a-2f6d1c8a0e55" \
-H "Content-Type: application/json" \
-d '{"repositoryId":"a1b2c3d4-...", "title":"Board columns misalign at 360px"}'

Retrying the exact same request with the same header returns the same 201 body a second time, with one extra response header:

Idempotent-Replay: true

The key is not global. Pealboard scopes a replay to the credential, the HTTP method, the path and the key together, so:

  • The same key sent by a different credential is a different operation, not a collision.
  • The same key sent to a different route is a different operation.
  • A guessed key reveals nothing, because it cannot be replayed without also presenting the credential that set it.
  • Only a successful response (any 2xx) is recorded. A retry after a failure runs again rather than replaying the failure — a transient error is not meant to become permanent for the life of the key.
  • A recorded answer is kept for 24 hours. After that, the same key starts a new operation.
  • A key is at most 255 characters. Longer is 422 invalid_request.

Idempotency-Key is honored on every POST under /v1 and /portal, with one exception: POST /v1/api-keys accepts the header but does not record a replay. The key is returned once and never stored, only a digest of it is; a recorded answer would keep the plaintext key itself in storage for 24 hours, which is the one thing this route promises not to do. A retry issues a second key — revoke whichever you did not keep.

The header is called out explicitly in the description of the two routes it matters for — POST /v1/issues and POST /portal/requests — because those are the creates most likely to be retried by a client that cannot tell whether its first attempt was received. Sending it on a route where a retry would not otherwise duplicate anything costs nothing; Pealboard still records and replays the answer.