Idempotency
Retry any POST safely by sending the same Idempotency-Key.
Networks fail at the worst moments. If a request to create a refund times out, you cannot know whether it went through. Idempotency keys solve this: send a unique key with the first attempt and reuse it on retries, and Borga returns the original response instead of performing the operation twice.
Idempotency-Key: refund:order_5678:item_2Node.jsts
// Derive the key from the operation, not from the attempt. Retrying with the
// same key returns the original response instead of creating a second refund.
await borga.refunds.create(
{ payment: "pay_7Hs2Kq9LmW4xZc1Vb8Ny3Rt6", amount: 990 },
{ idempotencyKey: `refund:order_5678:item_2` },
);curlbash
curl https://api.borga.is/v1/refunds \
-H "Authorization: Bearer sk_test_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: refund:order_5678:item_2" \
-d '{ "payment": "pay_7Hs2Kq9LmW4xZc1Vb8Ny3Rt6", "amount": 990 }'Rules
- Keys are any string of 1 to 255 characters from
A-Z a-z 0-9 _ - : .. - Keys are scoped to your merchant and mode. Two merchants can use the same key without interference.
- A stored response is kept for 24 hours. After that the same key starts a new request.
- Replays return the original status code and body, plus the headers
Idempotency-Key: <key>andIdempotent-Replayed: true. - 4xx responses are stored too, so a retried invalid request returns the same error. 5xx responses are not stored, so a retry after a server error runs again.
- Only POST requests are affected. GET, PATCH and DELETE ignore the header.
Choose good keys
Derive the key from the business operation, not from the attempt: refund:<order>:<line> or a UUID you generate once and persist alongside the intent to act. The Node SDK generates a fresh UUID for every POST when you do not pass one, which protects against its own internal retries but not against your process restarting; pass your own key for anything that moves money.
Errors
| Code | HTTP | Meaning |
|---|---|---|
idempotency_key_in_use | 409 | The first request with this key is still running. Wait and retry with the same key. |
idempotency_key_payload_mismatch | 409 | The key was already used with a different body or on a different route. Use a new key. |
invalid_field with param: "Idempotency-Key" | 400 | The key contains disallowed characters or is too long. |