A write can fail halfway: your connection drops. Your software then does not know whether Rally received the request. An Idempotency-Key lets you send it again with no risk of a duplicate.

Which requests

Send an Idempotency-Key on every POST. It is optional, but without it a second send creates a duplicate.

  • Use a unique value per request, for example a UUID.
  • It is never empty and is 255 characters at most. Otherwise the API answers INVALID_INPUT.
  • Rally keeps it for 24 hours.
curl https://gorally.games/v1/leagues \
  -X POST \
  -H "Authorization: Bearer $RALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6a1f0c3e-creer-ligue-mardi" \
  -d '{"name":"Ligue du mardi","sport":"CURLING","timeZone":"America/Toronto"}'

What the API does

Rally compares the key and the request body, byte for byte.

  • First time: the request runs, and its response is stored.
  • Same key, same body: Rally replays the original response and writes nothing again. The replay carries the Idempotent-Replayed: true header.
  • Same key, different body: the API refuses.

A refusal returned during execution is replayed like a success: missing rights, item not found, conflict. A 5xx is never stored: it means “retry”.

A body rejected while being read does not reserve the key: malformed JSON, invalid or missing field. Fix the request and send it again with the same key: it runs, without Idempotent-Replayed.

The replay carries the request_id of your new request, not the original one.

The three errors

They all answer 409.

Code Cause What to do
IDEMPOTENCY_KEY_REUSED This key was already used with a different body. Use a new key for this new request.
IDEMPOTENT_REQUEST_IN_FLIGHT A request with this key is still running. Retry in a moment, with the same key.
IDEMPOTENCY_OUTCOME_UNKNOWN A request with this key was interrupted with no known outcome. Read the item to see whether it exists, then resume with a new key.

For IDEMPOTENCY_OUTCOME_UNKNOWN, Rally does not replay: a connection lost right after the write looks like one lost right before. Replaying could create the duplicate the key exists to prevent.

Not on PATCH

Never send an Idempotency-Key on a PATCH. The API ignores it.

PATCH /matches/{matchId} protects itself another way, with a revision lock. You send expectedRevision, the revision you read. If someone wrote in the meantime, the API answers CONFLICT.

curl https://gorally.games/v1/matches/f4e3d2c1-b0a9-4f8e-8d7c-6b5a4f3e2d1c \
  -X PATCH \
  -H "Authorization: Bearer $RALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":3,"event":"COMPLETER","score":{"a":7,"b":5,"unitsPlayed":8}}'

After a CONFLICT, read the match again and decide. Do not send it blindly again: you would overwrite the other program’s work.

What next

  • Read the “Pagination” guide to walk through lists.
  • Keep the “Errors” guide at hand for the other codes.

Next guide: Pagination →