#idempotency#retries#dedupe

“retries and double submits mean my endpoint sometimes processes the same thing twice”

Dedupe jobs and deliveries with idempotency keys

Pass an idempotency_key when you create a job so a double-submit doesn't schedule twice, and dedupe on the X-Fliq-Delivery-Id header so an at-least-once retry doesn't double-charge.

Two things can cause a duplicate: you create the same job twice (a client retried the POST), or Fliq delivers the same job twice (at-least-once delivery — a worker crashed after calling you but before recording the result). Fliq gives you a guard for each.

Guard 1 — don’t schedule twice: idempotency_key

Pass an idempotency_key when creating a job. A repeat create with the same key returns the existing job instead of scheduling a new one.

curl -X POST https://api.fliq.sh/jobs \
  -H "Authorization: Bearer fliq_sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/api/charge",
    "http_method": "POST",
    "scheduled_at": "2026-06-12T10:00:00Z",
    "body": "{\"invoice_id\":\"inv_123\"}",
    "idempotency_key": "charge-inv_123",
    "max_retries": 3
  }'
await fetch("https://api.fliq.sh/jobs", {
  method: "POST",
  headers: {
    "Authorization": "Bearer fliq_sk_your_token",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://yourapp.com/api/charge",
    http_method: "POST",
    scheduled_at: "2026-06-12T10:00:00Z",
    body: JSON.stringify({ invoice_id: "inv_123" }),
    idempotency_key: `charge-${invoiceId}`, // same key => same job, scheduled once
    max_retries: 3,
  }),
});

Guard 2 — don’t process twice: X-Fliq-Delivery-Id

Delivery is at-least-once. Every call Fliq makes to your endpoint carries a stable X-Fliq-Delivery-Id header that is the same across retries of the same attempt. Record it the first time you see it and ignore repeats — then double processing is impossible even if the request arrives twice.

// Your endpoint that Fliq calls:
export async function POST(req) {
  const deliveryId = req.headers.get("X-Fliq-Delivery-Id");

  // Atomic insert; unique constraint on delivery_id.
  const fresh = await markSeen(deliveryId); // false if we've handled it before
  if (!fresh) return Response.json({ status: "duplicate-ignored" });

  await chargeInvoice(/* ... */);
  return Response.json({ status: "ok" });
}

What Fliq handles for you

  • Create-time dedupe. idempotency_key makes job creation safe to retry — a flaky network on your side won’t schedule the work twice.
  • A stable delivery id. X-Fliq-Delivery-Id is constant across retries, giving your endpoint a single key to dedupe on. This applies to buffer item deliveries too.
  • At-least-once, honestly. Fliq tells you it’s at-least-once rather than pretending exactly-once — and hands you the header to close the gap.
Build idempotent workflows on Fliq — free during beta