Idempotency
Network calls fail in ambiguous ways: a request times out, but did the document get created? Idempotency keys let you safely retry mutating requests without creating duplicates.
How it works
Send an Idempotency-Key header (a unique value per logical operation, a UUID v4 is ideal) on POST requests that create resources:
Idempotency-Key: 7c1f1d6e-0b2a-4a1e-9b1a-2a4e9b1a2a4e
- The first request with a given key executes normally and the result is cached.
- Any retry with the same key returns the original result instead of creating a second document.
- Keys are retained for 24 hours.
Generate one key per intent (e.g. "create invoice for order #1234") and reuse it across retries of that intent, not across different operations.
import { randomUUID } from 'node:crypto';
const key = randomUUID();
async function createInvoiceWithRetry(payload: unknown) {
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch('https://prod.api.fakturnia.pl/external/v1/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${await getToken()}`,
'Content-Type': 'application/json',
'Idempotency-Key': key, // same key on every retry
},
body: JSON.stringify(payload),
});
if (res.status < 500 && res.status !== 429) return res.json();
await new Promise(r => setTimeout(r, 2 ** attempt * 500)); // backoff
}
throw new Error('exhausted retries');
}
Pair idempotency keys with backoff. Retrying
5xx/429responses is only safe when the same key guarantees the operation runs at most once.
Document creation is the main idempotent endpoint. Reads are naturally idempotent and need no key.