cimplify
Concepts

Idempotency

Every write method on the SDK accepts an optional `{ idempotencyKey }` as its second argument. Replays of the same key against the same body return the original response and never a duplicate side effect.

The contract

await client.cart.addItem(
  { item_id: "prod_studio-tee", quantity: 1 },
  { idempotencyKey: "add-tee-2026-05-07-abc123" },
);

await client.cart.applyCoupon("WELCOME10", { idempotencyKey: "coupon-…" });

await client.checkout.process(checkoutBody, { idempotencyKey: "checkout-…" });

await client.uploads.init("hero.png", "image/png", 12_345, { idempotencyKey: "upl-…" });

Auto-generation

Omit the option and the SDK mints a UUID for you, transparently. That covers the common case: single-flight writes from a typed client where retries are not yet a concern. Override only when you need cross-process replay safety or a deterministic key.

How replay works on the server

The server stores the response keyed by (business_id, route, idempotency_key) for 24 hours. Subsequent requests with the same key:

BodyResult
Identical to originalCached response replayed; no side effect
Different from original409 with code IDEMPOTENCY_KEY_REUSED
Original still in flight409 with code ALREADY_PROCESSING; caller should poll, not retry

When to override the default

Double-submit guards

A user double-clicks the "Place order" button. Without an explicit key, two requests each get their own UUID, and the server runs the side effect twice. Bind the key to the user action, not the request.

const checkoutKey = useMemo(() => crypto.randomUUID(), [cartId]);

async function placeOrder() {
  const r = await client.checkout.process(body, { idempotencyKey: checkoutKey });
  if (!r.ok) return showError(r.error);
  router.push(`/orders/${r.value.order_id}`);
}

CI replays

A CI job that adds a fixture cart, then re-runs after a flaky network blip, should converge to the same final state. Use a deterministic key derived from the test run identifier.

const runId = process.env.GITHUB_RUN_ID ?? "local";
await client.cart.addItem(
  { item_id: "prod_x", quantity: 1 },
  { idempotencyKey: `fixture-cart-${runId}` },
);

Webhook receivers

On the inbound side, treat each event's id as the idempotency key for the operation you trigger downstream. Same fact, same fingerprint, same result.

Don't reuse keys across resources

Idempotency is scoped per route. /cart/items and /checkout can both see the same key with no conflict. Within a single route, treat keys as one-shot for a given logical operation; reusing one key for two distinct intents will trigger IDEMPOTENCY_KEY_REUSED.

Methods that accept idempotency keys

ServiceMethods
client.cartaddItem, applyCoupon
client.checkoutprocess, submitAuthorization
client.authrequestOtp, verifyOtp
client.orderscancel
client.subscriptionscancel, skipNext
client.schedulingcancelBooking, rescheduleBooking
client.uploadsinit
client.fxlockQuote

Next

On this page