“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_keymakes job creation safe to retry — a flaky network on your side won’t schedule the work twice. - A stable delivery id.
X-Fliq-Delivery-Idis 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.
Related
- API Reference —
idempotency_keyand the job object - Buffers — at-least-once delivery and
X-Fliq-Delivery-Id - Retry a failed webhook with backoff
Reference: /docs/api-reference