OlammaAPI

Retries

Networks fail. An Idempotency-Key lets you repeat a write safely: it happens once, however many times you send it.

How it works

  1. Pick a key for the change you mean. 8–100 characters, unique to that one change, like order-1042-add or a random UUID you store with the job.
  2. Send it with the write in the Idempotency-Key header.
  3. If you don’t get an answer, send the exact same call again with the same key. If the first one went through, you get its outcome back, marked Idempotent-Replayed: true, and nothing is written twice.
Response 200, replayed
{
  "replayed": true,
  "outcome": "done",
  "refs": ["tr_…"],
  "note": "This request already ran. Read the objects again for their current state."
}

Good to know

  • The same key with a different body is refused with conflict: a key stands for one change.
  • While the first call is still running, a repeat gets in_progress. Wait a moment and repeat it again.
  • If a first attempt’s outcome can’t be known after ten minutes, you get unknown_outcome rather than a second write. Read the objects to see what happened.
  • Outcomes are kept for seven days. Use a new key for each new change.

A retry loop

// Retry a call on 429 or a server error, keeping the same Idempotency-Key.
async function send(url, options, attempts = 4) {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429 && response.status < 500) return response;
    if (attempt === attempts) return response;
    const wait = Number(response.headers.get("Retry-After")) || 2 ** attempt;
    await new Promise(resolve => setTimeout(resolve, wait * 1000));
  }
}

await send(`${BASE}/tables/tt_…/records`, {
  method: "POST",
  headers: { ...headers, "Idempotency-Key": `order-${order.id}-add` },
  body: JSON.stringify({ records: [{ cells: { tf_customer: order.customer } }] }),
});

Never retry a write without an Idempotency-Key. Without one, a retry after a dropped answer can write twice.