Idempotency
Safe retries on POST with the Idempotency-Key header.
Safe retries on POST with the Idempotency-Key header.
Pivotal’s POST endpoints accept an Idempotency-Key header. Send the same key with the same body twice and you get the same response twice — the second request doesn’t create a duplicate resource.
This matters because networks fail. If a POST /customers request times out, you can’t tell whether the customer was created or not. With an idempotency key you can retry safely.
customer-create-aurora-2026-05-26. Whatever you pick has to be unique per logical operation.POST without an Idempotency-Key works exactly as before — at-most-once becomes at-least-once on retry.When you send Idempotency-Key and the request succeeds, Pivotal stashes:
A second request with the same key returns the cached response, byte-for-byte, with the same id and display_id.
If you send the same Idempotency-Key with a different body, Pivotal returns 409 Conflict:
This catches a common bug: the same key getting reused across two unrelated operations because someone hardcoded Idempotency-Key: 1.
If two requests with the same key arrive concurrently, the second one returns 409:
Retry after a short delay and you’ll get the result of the first one (assuming it succeeded).
Use idempotency keys for:
You don’t need one for:
GET requests — already idempotent by definition.DELETE — soft delete twice on the same record is fine; the second call returns the same body.PATCH — same effect both times unless your patch is non-idempotent (rare with PATCH).Three patterns work well, in order of preference:
customer-create-{external-id}-{epoch-day} is fine if you trust your external-id. Avoid plain {external-id} — you may legitimately want to recreate after a delete.sha256(body) + ":" + floor(now / 60s). Self-contained but slightly more code.What doesn’t work: a global counter (collides on cold starts), the current Unix epoch (collides under concurrency), the user’s email (the same user might legitimately create multiple resources).
Idempotent responses carry Idempotent-Replay: true on the second (cached) response:
Log that header to confirm retries are doing what you expect.