Skip to main content

Overview

Network failures and timeouts are unavoidable. Without idempotency, retrying a failed request can create duplicate payouts, refunds, or other financial operations with real monetary consequences. Idempotency keys let you retry any POST request with the guarantee that the operation executes exactly once.

Sending an idempotency key

Use a UUID v4 as the key, or any string up to 255 characters that uniquely identifies this specific operation for your account. An internal order ID or invoice reference works well. The key is scoped to your merchant account. Include it as a header on any mutating POST request:
POST /api/service/checkout/session/create
Idempotency-Key: 7a3b08d1-2c4e-4f5a-9b6c-1d2e3f4a5b6c
Content-Type: application/json
X-Ivy-Api-Key: <your-api-key>
The key is optional. When omitted, the request executes normally with no idempotency guarantees. When the same key is sent again with identical parameters, the API returns the cached response without re-executing the operation.
The Node SDK automatically generates a UUID v4 idempotency key for every covered POST request, so you get safe retries without any extra code. Pass your own key only when you want to control the value.

Covered endpoints

The following mutating endpoints accept the Idempotency-Key header:
EndpointDescription
POST /api/service/beneficiary-payout/createCreate a beneficiary payout
POST /api/service/checkout/session/createCreate a checkout session
POST /api/service/checkout/session/expireExpire a checkout session
POST /api/service/customer/createCreate a customer
POST /api/service/customer/deleteDelete a customer
POST /api/service/customer/updateUpdate a customer
POST /api/service/fx/executeExecute an FX conversion
POST /api/service/order/createCreate an order
POST /api/service/order/expireExpire an order
POST /api/service/payout/createCreate a payout
POST /api/service/refund/createCreate a refund
POST /api/service/subaccount/createCreate a subaccount
POST /api/service/webhook-subscription/createCreate a webhook subscription
POST /api/service/webhook-subscription/deleteDelete a webhook subscription
POST /api/service/webhook-subscription/updateUpdate a webhook subscription
Read-oriented endpoints (retrieve, list, search, details) are safe to retry without an idempotency key.
POST /api/service/fx/execute previously accepted an idempotencyKey field in the request body. That field still works but is deprecated. Use the Idempotency-Key header instead.

Conflict behaviour

Reusing the same key with different request parameters returns a 409 Conflict:
{
  "message": "This idempotency key has already been used with different parameters.",
  "category": "idempotency_error",
  "docUrl": "https://docs.getivy.de/reference/idempotency"
}
If two requests arrive concurrently with the same key, the second returns 409 Conflict. Retry after a short delay.
Using the same key for two different operations is almost always a bug. The key is scoped globally, so the same key sent to two different routes will conflict.

Error handling

Only successful responses are cached. If the original request fails (for example, a 400 validation error), the idempotency key is released and you can retry with the same key after fixing your request. You do not need a new key to correct a mistake.

Key retention

Idempotency keys are retained for 30 days. After expiry, a previously used key is treated as new and the operation executes again.

Code examples

curl --request POST \
     --url https://api.getivy.de/api/service/payout/create \
     --header 'X-Ivy-Api-Key: YOUR_API_KEY' \
     --header 'Idempotency-Key: 7a3b08d1-2c4e-4f5a-9b6c-1d2e3f4a5b6c' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "amount": 100,
  "currency": "EUR",
  "destination": {
    "financialAddress": {
      "type": "iban",
      "iban": {
        "iban": "DE93500105176719451585",
        "accountHolderName": "Chris Simon"
      }
    }
  }
}'