Retries and long requests
Make a write safe to retry with Idempotency-Key, and run long calls in the background with Prefer respond-async.
Retry a write safely
Networks drop answers. If a POST, PUT, PATCH or DELETE times out, you can't tell whether it ran. Send an
Idempotency-Key header and retry with the same key: the first answer comes back instead of the call running again.
curl -X POST https://dev.app.ingenee.ai/api/v1/titles \
-H "Authorization: Bearer $INGENEE_API_KEY" -H "content-type: application/json" \
-H "Idempotency-Key: 4f7d2c1e-import-run-118-row-42" \
-d '{ "source": "manual", "title": "The Long Road", "year": 2019, "type": "movie" }'- The key is any string of 1 to 255 visible ASCII characters. A UUID per logical operation works well.
- A replayed answer has the same status and body as the first, plus the header
idempotent-replayed: true. - Keys belong to one API key and are kept 24 hours. After that the same key runs the call again.
- The same key on a different request (another path, query or body) is refused with
422 IDEMPOTENCY_KEY_REUSED. - While the first call is still running, a retry gets
409 REQUEST_IN_PROGRESS. Wait and retry. - A
5xxanswer is not kept, so a retry after a server error runs again. GETcalls ignore the header; they are safe to repeat anyway.
Run a long call in the background
A few calls can run for a long time: generating or extending a schedule, and re-running enrichment. Their reference
pages say Send Prefer: respond-async. With that header the call answers 202 Accepted at once:
curl -i -X POST https://dev.app.ingenee.ai/api/v1/channels/f27a91c3-4b6d-4e08-a5d2-9c1e3b7f0a64/schedule/generate \
-H "Authorization: Bearer $INGENEE_API_KEY" -H "content-type: application/json" \
-H "Prefer: respond-async" -d '{}'location: /v1/requests/9a0f5d3c-2b1e-4c7a-8f6d-1e2d3c4b5a69
preference-applied: respond-async
{ "id": "9a0f5d3c-2b1e-4c7a-8f6d-1e2d3c4b5a69", "status": "running", "poll": "/v1/requests/9a0f5d3c-2b1e-4c7a-8f6d-1e2d3c4b5a69" }Poll GET /v1/requests/{id} every few seconds:
{
"id": "9a0f5d3c-2b1e-4c7a-8f6d-1e2d3c4b5a69",
"operation": "generateSchedule",
"status": "done",
"createdAt": "2026-10-30T12:01:04.120Z",
"completedAt": "2026-10-30T12:02:51.733Z",
"response": { "status": 201, "body": { "versionId": "…", "versionNum": 7, "itemCount": 412 } }
}While status is running, response is null. When it is done, response is exactly what the call would have
returned, error or not: check response.status.
- Only the API key that made the request can read it. Any other key gets
404. - Results are kept 24 hours.
Prefer: respond-asyncon a call that doesn't support it is ignored, and the call runs normally.- Combine both headers to make a background call safe to retry: a retry with the same
Idempotency-Keyreturns the same request id while it runs, then its result.