Idempotency
An idempotency key lets you retry a request without performing the same operation twice. This page covers how to send a key, what happens when you reuse one and which idempotency errors are safe to retry.
Idempotency keys matter most on POST /funds/allocations. If the request times out, you have no way to tell whether the allocation was created. Retrying with the same key returns the result of the first attempt instead of creating a second allocation.
Send an idempotency key
Pass the key in the Idempotency-Key header:
Idempotency-Key: 3f1a7c4e-9b2d-4f8a-a1c6-5e7d9b0f2a34Five endpoints honour the key:
POST /quotesPOST /quotes/carbonPOST /quotes/naturePOST /funds/allocationsPOST /funds/allocations/{id}/reverse
Other endpoints ignore the header. GET requests don't create or change anything, so it has no effect on them either.
Send a key on every quote and funds request
The header is optional, but ekko recommends using it wherever it's honoured. Without one, a retry can perform the same operation a second time.
Retry a request
ekko stores a key only when the operation succeeds. A request that fails leaves the key unused, so you can retry with the same value. The same applies when authentication, authorisation, validation or rate limiting rejects a request before it runs.
When the key has already been stored, ekko doesn't run the operation again. You get the same status code as the first request, with a fresh copy of the resource. ekko doesn't save the original response and replay it, so if the resource has changed since, the response shows the current version.
One field works differently. On a nature quote, contribution.suggestedAmounts is calculated when you ask for the quote rather than stored with it, so a replay returns the values current at the time of the retry.
The Idempotent-Replayed response header tells you which of the two you got: true for a replay, false for a request ekko ran for the first time.
A missing
Idempotent-ReplayedIf the response has no
Idempotent-Replayedheader, idempotency didn't apply, either because the request carried no key or because the endpoint doesn't support it. Retrying that request can perform the operation a second time.
Allocations are also keyed on quoteId, so POST /funds/allocations rejects a second allocation against a quote that has already been allocated, with or without a key. Sending a key changes what comes back: ekko returns the original allocation. Without a key, the rejection doesn't include it, so you can't see what the first attempt created.
Choose a key
You generate the key. Any printable ASCII value of 1 to 255 characters works and a UUID is a common choice. Your own reference works too, as long as it's unique to the operation.
Use the same key for every retry of a request and a different key for a different operation. ekko compares the request body as well: reusing a key with a different body returns IDEMPOTENCY_KEY_REUSED instead of a replay.
Keep personal data out of keys
ekko stores the keys you send. Do not use email addresses or other personal identifiers as key values.
Scope and retention
Keys are scoped to your organisation and expire after one week. After that, the same value starts a new request.
Idempotency errors
| Status | Code | What it means | Retry |
|---|---|---|---|
409 | IDEMPOTENCY_KEY_IN_FLIGHT | The first request with this key is still running | Yes, same key, after Retry-After seconds |
409 | IDEMPOTENCY_RESOURCE_GONE | The resource the key created has since been reversed or deleted | No |
422 | IDEMPOTENCY_KEY_REUSED | The key was used with a different request body | No, send a new key |
400 | IDEMPOTENCY_KEY_INVALID | The key is over 255 characters or contains characters outside printable ASCII | No, send a valid key |
503 | SERVICE_UNAVAILABLE | The idempotency store couldn't be reached, so nothing was performed | Yes, same key, after Retry-After seconds |
Retry only where the table says so. The two 409 codes need different handling, so branch on code rather than on the HTTP status.
See Errors and error handling for the full list of statuses and codes.
Updated 27 days ago
