Idempotency and limits
Retry POSTs safely and handle the rate limit.
Idempotency
Networks fail. To retry a POST without duplicating its effect, send Idempotency-Key with a unique value per operation (a UUID works; 1 to 255 characters):
KEY=$(uuidgen)
curl -X POST $BACKEND_URL/v1/sellers \
-H "Authorization: Bearer mk_your_api_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{"name":"Acme Store","externalId":"customer-123"}'Run the same command again with the same KEY and body: you get the same response (same status and body) with the header:
Idempotency-Replayed: trueRules:
- Only
POST /v1/*honors the header.PATCHandDELETEignore it: repeating aDELETEalready done responds404. - A replay returns the stored status (e.g.
201). - A key longer than 255 characters responds
400 VALIDATION_ERROR. - The same key with a different body responds
409 CONFLICT(nodetails). Use a new key for a different operation. - The key is kept for 24 hours. After that, the same value counts as a new key.
- The key is scoped per account: two API keys of the same account share idempotency keys. Another account can use the same value without a clash.
- Only success responses are stored. If it failed, you can retry with the same key.
- Don't send two requests with the same key at the same time. Wait for the first response.
The 409 for a different body:
{
"error": {
"code": "CONFLICT",
"message": "Idempotency-Key already used with a different body."
}
}Rate limit
The default is 300 requests per minute, per API key (configurable). The counter belongs to the API key, summed across all /v1 routes. Every authenticated request to /v1 counts, including 4xx errors and idempotency replays. 401 does not count: authentication runs before the limit, and without a valid API key there is no counter to add to.
Authenticated /v1 responses that are not 429 carry (401 does not):
| Header | What it is |
|---|---|
X-RateLimit-Limit | window limit |
X-RateLimit-Remaining | requests still allowed |
X-RateLimit-Reset | seconds until the window restarts (not a date) |
When you exceed it, the response is 429, with the Retry-After header and this body:
HTTP/1.1 429 Too Many Requests
Retry-After: 30{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again after the time given in Retry-After."
}
}How to handle it:
- Stop sending with that API key and wait for
Retry-Afterbefore the next attempt. - Don't retry right away: it only uses up the next window.
- If you often get close to the limit, watch
X-RateLimit-Remainingand slow down before you hit a429.
When retrying a POST after a 429, resend the same Idempotency-Key.
Error format in Errors.