API referenceIdempotency
Idempotency
A write that times out may or may not have happened. Send it with an Idempotency-Key and you can send it again safely: the first request to arrive does the work, and every repeat gets its answer back. No second order, kitchen ticket or stock movement is made.
By method
Required on POST
A POST without one is
400 idempotency_key_required.Accepted on PATCH
Setting a value twice is harmless, but a key stops a late retry from undoing a newer change.
Ignored on GET
A read changes nothing, so there is nothing to repeat.
The key
- One key per operation, made fresh: a UUID is ideal. It must match
^[A-Za-z0-9._:~+/=-]{8,255}$, 8 to 255 letters, digits and- _ . : ~ + / =; the quoted form is accepted. Anything else is400 invalid_idempotency_key. - It belongs to the API key that sent it: no other key or restaurant sees it. It is kept for 24 hours from the first request; after that the same key runs as a new request.
- Send the same key only with the same request: method, path and body. Bodies are compared as JSON, so spacing and key order do not matter. The same key with a different request is
422 idempotency_key_reused. - Every code sample in this reference makes a fresh key each time it runs (
$(uuidgen),crypto.randomUUID(),uuid.uuid4()). Keep the one you sent if you may need to retry.
KEY=$(uuidgen) # one key for this one order; reuse it only to retry it
curl -X POST "$TABLEBUDDY_URL/api/v1/orders" \
-H "Authorization: Bearer $TABLEBUDDY_API_KEY" \
-H "Idempotency-Key: $KEY" \
-H 'Content-Type: application/json' \
-d '{"type":"COUNTER","lines":[{"menu_item_id":"MENU_ITEM_ID","quantity":1}]}'
# Timed out? Send exactly the same request with the same $KEY:
# the order is made once, and the retry gets its answer.What a repeat gets
- Kept: a success,
404 not_foundand409 refused. A repeat gets the same status and body, markedIdempotent-Replayed: truewith theOriginal-Request-Id. It is the answer the request got, not the record’s state now: read the record for that. A refusal stays the key’s answer, so use a new key to try again after fixing it. - Released:
422 invalid_request(correct the body; the same key may be used) and any5xx(nothing was kept; retry with the same key). - Still running:
409 idempotency_key_in_usewithRetry-After. Wait, then send it again. - Never read: a request refused before its key is read (a 400, 401, 403, 413, 415 or 429) does not use the key up.
What it guarantees
A write and the answer a retry will get are saved in one database transaction: both, or neither. If a server stops part-way, nothing it began is kept, and a retry made 60 seconds or more after the first attempt runs the request. Replays are authenticated and checked like any request, count toward the rate limit and carry their own request-id.