Retries and idempotency
Which requests are safe to retry, and how idempotency keys stop a retry from doing something twice.
On this page
Reads are safe to retry
Every endpoint on api.nexgapp.com is a GET today, and a read never changes anything at NexG. If a call times out or fails with a 5xx, send it again, waiting longer each time (1, 2, then 4 seconds is plenty). After a 429, wait for Retry-After first.
Idempotency keys for writes
Arrives with the first write
Booking a service, POST /v1/orders, is the first write and is not served yet. This is how it is designed to behave.
A retried write must not happen twice: a second airport transfer is a second car nobody asked for. So every write carries an Idempotency-Key header, and NexG keeps the first answer it gave for that key.
- The key is 16 to 128 characters. A random UUID is a good choice.
- A second request with the same key gets the first answer back, and books nothing new. That holds even if the body differs, so never reuse a key for a different booking.
- Keys are scoped to your merchant and to the endpoint, so they cannot collide with another merchant's.
import { randomUUID } from 'node:crypto';
// Make the key once per booking and save it with the booking before sending,
// so a retry after a crash or a timeout reuses it.
const booking = await db.bookings.create({ ...details, idempotencyKey: randomUUID() });
const res = await fetch('https://api.nexgapp.com/v1/orders', {
method: 'POST',
headers: {
'X-Api-Key': process.env.NEXG_API_KEY,
'Idempotency-Key': booking.idempotencyKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(details),
});Events you send NexG
Webhooks run the other way, with the same goal. Give every event an id that stays the same on every retry; NexG records each id once and answers a repeat as a duplicate. Sign each attempt again, because the signature includes the time. See Webhooks.
The key NexG sends a bank
When NexG opens a collection at a bank, it sends Idempotency-Key set to its payment reference, so one payment can only ever open one collection. A bank adapter must answer a retry the same way:
| NexG sends | The bank answers |
|---|---|
| A new key | 201 Created, with the new collection. |
| The same key and the same body | 200 OK, with the collection it already opened. |
| The same key and a different body | 409 Conflict. |