Idempotency keys are your retry safety net
Every production integration retries. Timeouts happen, connections drop, deploys interrupt in-flight requests. Without idempotency, a retry on a timed-out task creation can queue the same work twice — and charge you twice.
How it works
Attach a unique idempotencyKey to each task when you create it:
{ "taskType": "CHATGPT", "payload": { "prompt": "…", "country": "US" }, "idempotencyKey": "acme-daily-2026-09-18" }
If the same key arrives again — your retry, a crashed-and-restarted worker, a replayed batch — the API returns the original task instead of creating a new one. One key, one task, one charge, ever.
Choosing keys
The key should encode what the task means, not a random UUID per attempt:
"<brand>-<prompt-hash>-<market>-<date>"for scheduled monitoring — a crashed cron that re-runs safely dedupes"<report-id>-<prompt-index>"for report generation — re-running report #4821 can’t double-bill- Batch calls take one key per task; dedup is per task, not per batch
What it protects against
- Client retries: your SDK already retries task creation only when a key is present — this is why
- Cron overlap: a slow run colliding with the next scheduled run submits the same keys, harmlessly
- Crash recovery: resume a half-submitted batch by resubmitting all of it; completed keys no-op
The boundary
Idempotency dedupes creation, not results. Two runs of the same prompt on different days need different keys — they’re different work. Keys scope to “this logical task”, not “this prompt”.
Details in async tasks and batches and the API reference.