General · Platform basics
Idempotency
Retry requests safely with idempotency keys in Fincore, Direct Debit, Gift Cards and Billpay.
A network timeout does not tell you whether your request ran. An idempotency key lets you retry without paying, charging or buying twice. Each product implements it differently.
Compare products
| Product | Field | Required | Operations | Key format | Expiry |
|---|---|---|---|---|---|
| Fincore | Idempotency-Key header |
No, but always send it in production | Create Money Out, Create Penny Validation | UUID v5 | 24 hours |
| Direct Debit | Idempotency-Key header |
No | Create charge | UUID | 24 hours |
| Gift Cards | idempotency_key in the body |
Yes | Purchase a gift card | String | Not documented |
| Billpay (v1) | idempotency_key |
Optional on payments and top-ups, required on verify payment | Create payment, Create top-up, Verify payment | String | Not documented |
What happens when you retry
| Scenario | Fincore | Direct Debit | Gift Cards |
|---|---|---|---|
| No key | Processed normally, without retry protection | Processed normally | Rejected. The key is required. |
| Invalid key format | Rejected | 400 Bad Request |
— |
| Same key, same body | Original response returned | Original charge returned | Rejected with DUPLICATED_PAYMENT_ERROR |
| Same key, different body | 409 conflict |
422 Unprocessable Entity |
Rejected with DUPLICATED_PAYMENT_ERROR |
| Same key while the first request is still running | 409 conflict |
409 Conflict. Wait and retry. |
— |
| Same key after it expires | — | Creates a new charge | — |
Gift Cards does not return the original purchase on a repeated key. It rejects the request instead.
Fincore: generate the key from the request
Fincore expects a deterministic UUID v5, so the same business operation always produces the same key. Build it from:
| Input | Why |
|---|---|
| Environment namespace | Keeps staging and production keys apart. |
client_id |
Scopes keys to your client. |
| Operation name | Avoids collisions between different operations. |
| Hash of the canonical request body | The same body always gives the same key. |
Canonicalize the body before you hash it: sort object keys alphabetically at every level and serialize consistently. Reusing a key for a different operation can cause a conflict.
Idempotency-Key: 66c0b04f-97d6-592d-8396-199819064afaA conflict returns HTTP 409 with the standard Fincore error body:
{
"code": 9,
"message": "API Error",
"details": [
{
"reason": "FAILED_PRECONDITION",
"domain": "CORE",
"metadata": {
"error_detail": "Idempotency key does not match the request payload",
"http_code": "409"
}
}
]
}Direct Debit: send a UUID
Send any UUID in the Idempotency-Key header of POST /charges. Keys are scoped to your organization.
curl -X POST https://stg.directdebit.monato.com/charges \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: 00000000-0000-4000-8000-000000000000" \
-d '{ ... }'Lottery
Lottery has no idempotency key, but each ticket purchase must use a unique payer_reference.