Skip to content

Idempotent requests

A timeout or connection error does not tell you whether your request was executed. Retrying a GET is always safe, but blindly retrying a POST can create the same resource twice. Idempotency keys solve this: they make POST requests safe to retry.

Send the HTTP header Idempotency-Key with a value of your choice (1 to 200 characters, for example a UUID) on any POST request:

Terminal window
curl "https://api.schulungstool.de/v1/participations/" \
-H "Authorization: Token <API key>" \
-H "Idempotency-Key: a7fbbb17-5f16-4cbd-9942-ad9b4c4a3c34" \
-H "Content-Type: application/json" \
-d '{"user": "4bcb84b8-6bc5-48f4-a15e-d87e056bd01c", "course": "06285ae7-38a0-484a-b779-b11490c706c0", "due_date": "2027-01-31"}'

The first request is executed normally. If it succeeds (status 2xx), the response is stored for 24 hours. If you send the same request with the same key again, the API does not execute it a second time: it returns the stored response, byte for byte, marked with the HTTP header Idempotent-Replayed: true.

Only successful responses consume a key. If a request fails (status 4xx or 5xx), the key is released and the next request with it is executed normally.

  • Generate a fresh random value (for example a UUIDv4) for every new operation.
  • Reuse the exact same key only to retry the exact same request.
  • Keys are scoped per API key: two of your API keys never see each other’s keys.

A key belongs to exactly one request. The API compares the HTTP method, the path including the query string, the Content-Type header and the raw request body:

Status Type Situation
400 IdempotencyKeyInvalidError The key is empty or longer than 200 characters.
409 IdempotencyKeyInUseError The first request with this key is still running. The response carries Retry-After with the number of seconds to wait.
422 IdempotencyKeyReuseError The key was already used for a different request. Use a new key.
  • Timeout or connection error: retry with the same key; this is exactly what idempotency keys are for.
  • Status 429 or 5xx: retry with the same key (for 429 wait the seconds given in Retry-After, for 5xx use exponential backoff), see Errors and rate limiting.
  • Status 409: wait the seconds given in Retry-After, then retry with the same key.
  • Other 4xx errors: fix the request first, then send it with a new key; the changed request would otherwise be rejected with 422.
  • On GET, PUT, PATCH and DELETE the header is ignored: these methods are already idempotent.
  • Keys expire after 24 hours; after that, the same key is treated as new.
  • Exception: POST /v1/users/{id}/login-link/ never stores or replays responses, because the generated link expires after 30 seconds. The header is still validated, and a key already used elsewhere is rejected with 422.