Idempotency
The Idempotency-Key header lets you safely retry POST requests when a network blip or timeout makes you unsure whether the first attempt landed. Submit the same key again and the server returns the original response instead of running the work twice.
Idempotency-Key: 9f3a8b2e-1d4c-4e7a-b9c1-2f6e8d5a3c7bWhen required
| Endpoint | Idempotency-Key |
|---|---|
POST /api/v1/jobs | Required. Missing header returns 400 bad_request. |
DELETE /api/v1/jobs/:id | Not enforced. See note below. |
| All GET endpoints | Not applicable (already idempotent at the HTTP level). |
Idempotency-Key values
- Opaque string, up to 255 characters. UUIDs are the typical choice but any unique-per-submission string works.
- Scope is per API key. Two different customers can use the same string without collision.
- Generate a fresh key per logical submission. Reusing one across unrelated requests defeats the purpose.
Replay semantics
Use the same key when retrying the same submission:
- First request: creates the job and stores the response under the key.
- Replay with the same body: returns the stored response with the same HTTP status and same JSON body.
- Replay with a different body but the same key: returns
409 idempotency_conflictwith key reused with different request body. - Concurrent retry while the original is still running: returns
409 idempotency_conflictwith duplicate request in flight andRetry-After: 5.
Retry window
POST /jobs keeps an in-progress idempotency key for 30 minutes. If a retry arrives while the original request is still resolving, the retry gets 409 with Retry-After: 5.
Completed responses can be replayed for up to 24 hours. After that, the key may no longer be remembered.
5xx responses
2xx and 4xx responses are replayed on later calls with the same key. 5xx responses are usually not replayed, so a retry can run again. The exception is POST /jobs after the job has already been created: retries return the original 201 with the same job_id.
DELETE semantics
Example
KEY=$(uuidgen)
# First attempt: network blip, you don't get a response
curl -X POST -H "Authorization: Bearer yvt_live_..." \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.youtube.com/@channel", "format": "txt"}' \
"https://api.youtubevideotranscript.io/api/v1/jobs"
# Retry: server returns the original 201 Created with the same job_id
curl -X POST -H "Authorization: Bearer yvt_live_..." \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.youtube.com/@channel", "format": "txt"}' \
"https://api.youtubevideotranscript.io/api/v1/jobs"