Skip to contentSkip to navigation
Hatcel
Developers
2026-10-08API status

Idempotency

Retry a write safely with an Idempotency-Key

A request that timed out may or may not have worked. Every POST carries an Idempotency-Key, so a retry gets the first answer instead of making a second customer.

How it works

  • Every POST must send Idempotency-Key: a unique string, up to 255 characters. Without one the POST is a 400. A UUID per operation is ideal.
  • Same key, same request: the first answer is replayed - status and body - with Idempotent-Replayed: true.
  • Same key, different request: a 422 idempotency_mismatch. The method, path and body are compared, ignoring key order in the JSON.
  • Same key while the first is still running: a 409 conflict. Retry shortly.
  • A request that was refused or failed does not keep its key, so fixing it and retrying with the same key runs it again.
  • Keys belong to one API key and are kept for at least 24 hours.
curl -X POST "https://api.hatcel.com/customers" \
  -H "Authorization: Bearer $HATCEL_API_KEY" \
  -H "Hatcel-Version: 2026-10-08" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Alex",
    "email": "alex@example.com"
  }'

PATCH and DELETE

These take no key, and need none: sending the same PATCH twice sets the same values twice. A second DELETE of the same customer is a 404, because the first one worked.

Changing what you read

Between your read and your change, somebody at the venue may edit the same customer. Send If-Match and your change applies only to the version you read, so it never overwrites theirs without you knowing.

  • Every record you retrieve answers an ETag header: its version. A customer also carries it as version, so one read from a list needs no second GET; quote it to send it.
  • Send it back as If-Match on PATCH /customers/{id}. The check and the change are one step on our side, so nothing can land between them.
  • Changed since you read it: a 412 precondition_failed, and nothing is written. GET it again, check your change still makes sense, and send the new ETag.
  • If-Match is optional, but every key should send it.
  • A successful PATCH answers the customer's new ETag. Tags and lists are added and removed one at a time, never overwritten, so they take no If-Match.

Request bodies

A body is JSON, sent with Content-Type: application/json, and at most 64 KB. An unknown field is a 400, so a misspelt field is never silently ignored.