Skip to the documentation

Retries and concurrency

Idempotency-Key makes a retry safe. ETag and If-Match stop one writer overwriting another.

Idempotency-Key

If a request that starts a run times out, you do not know whether the run started. Starting again may start a second, and a second run spends a second one from the allowance. Send an Idempotency-Key header on every start and every run, with a value you choose for that attempt:

POST /api/v1/search
Idempotency-Key: okafor-east-nashville-1
  • The same key with the same request replays the first answer: 202, the same run, and Idempotent-Replayed: true. Nothing new starts, and nothing more is counted.
  • The same key with a different request is 409 idempotency-key-reused.
  • 1 to 255 characters from A-Z a-z 0-9 . _ : -. A malformed key is 400 invalid-idempotency-key, before the body is read.
  • A key is remembered for as long as its run exists. Use a fresh key for each new piece of work, such as an id from your own system; reuse one only to retry that same request.
  • A request is "the same" when its meaning is: key order and whitespace do not matter, and defaults are filled in before the comparison.

Only starting work is keyed: starting a headless search, an execution, or a run of a search. A GET is safe to retry as it is, a PUT to a chosen id (a client or a search) lands once however often it is sent, and a DELETE of something already gone answers 404. From a client to a shared shortlist lists which calls are safe to send twice.

ETag and If-Match

A headless request has a revision that counts up on every save, and so does a search (its version). A read returns it as the ETag. To change or delete it only if it is still the version you read, send it back as If-Match:

PUT /api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60
If-Match: "3"
  • If the search is still at revision 3, the change is applied and the answer has the new ETag.
  • If someone changed it since, nothing is written and the answer is 412 revision-mismatch. Read it again, merge, and retry with the new ETag.
  • If-Match is optional. Without it, the write wins. W/"3" and 3 are read as "3"; anything that is not a revision is 400 invalid-if-match.
  • A run's results work the same way with a tag that is not a number: "own" while the run keeps its own order, a fingerprint once they are arranged. Send the ETag of the run you read.