Skip to main content
Every POST under /api requires an Idempotency-Key header. The key lets you replay a request that timed out or failed in transit without creating the resource twice.

Header: Idempotency-Key

Send a random UUID:
The header name is case-insensitive, so IDEMPOTENCY-KEY and idempotency-key both work. The API reference writes it as IDEMPOTENCY-KEY. A POST without the header returns 400 with the message Missing Idempotency-Key header. This check runs ahead of authentication, so it fires before an invalid API key is reported.
Idempotency applies to POST only. PUT, PATCH, and DELETE are not deduplicated and do not require the header. Sending one on those methods has no effect.

What MoonPay Enterprise Stores

MoonPay Enterprise fingerprints each request as a hash of the request body plus the URL path, and stores it against your key alongside the response.
1

First request

MoonPay Enterprise runs the request. If the response status is 2xx, MoonPay Enterprise stores the status code and response body against the key.
2

Replay with the same key and same body

MoonPay Enterprise returns the stored status and body without running the operation again.
3

Replay with the same key and a different body

MoonPay Enterprise returns 409 Conflict. The response carries no explanatory body.
MoonPay Enterprise stores successful responses only. If the first attempt returns 4xx or 5xx, nothing is stored, and a retry with the same key runs the operation from scratch. Retrying a failed request is not a safe replay.This is how duplicate records get created. On POST /api/customers/{id}/identifications/v2, a partner who retries after an error can end up with several identifications for one customer, each one resetting the customer’s status. Read the retry rules in Onboarding Lifecycle and KYB before you add retry logic to an onboarding flow.

Key Considerations

  • One key per operation. Generate a fresh UUID for each new operation, and reuse that same key only when retrying that exact request.
  • A new key means a new operation. Retrying with a fresh UUID bypasses deduplication entirely and creates a second resource. This is the most common cause of duplicates.
  • Keys never expire. There is no time window. A key you used last year still returns its stored response today.
  • The query string is not fingerprinted. Only the path and body are hashed. Two requests to the same path with the same body but different query parameters count as the same request.
  • Idempotency does not make an endpoint an upsert. It stops one request from running twice. It does not stop two different requests from creating two records.

Example: Creating an Autoramp

Request

Response (First Request)

Response (Retry With the Same Key and Body)

Byte for byte the stored response, including the original created_at:
A replayed response is served from the cache, so it carries the stored status and body without response headers. It has no X-API-Version echo. See API Versioning.

Handling Errors Correctly

Because failures are never stored, decide what to do based on the status you got back:
On a timeout or 5xx against a creating endpoint, check state before you retry. Poll GET /api/customers/{id}/identifications or the relevant collection to see whether the record already exists. A retry after a partial failure runs the operation again and creates a second record.