Idempotency
POST /v1/access_codes and POST /v1/access_codes/:id/unlock_attempts both accept an Idempotency-Key header. Retrying a request with the same key and the same body returns the original response — no duplicate access code is created, and no physical unlock is accidentally triggered twice.
POST /v1/access_codes
Idempotency-Key: guest-4b-checkin-2026-08-01
{ "deviceId": "...", "validFrom": "...", "validUntil": "..." }Reusing a key with a different body is rejected
If the same Idempotency-Key is sent again with a different request body, the API returns 409 Conflict rather than silently creating a second code or overwriting the first — this is deliberate: a guest must never end up with two live access codes because of a retried request with a subtly different payload.
Key scope
Keys are scoped per tenant and expire after 24 hours — generate a new, unique key for every logical operation (e.g. per guest check-in, or per unlock attempt), not once per integration.
unlock_attempts replays failures too
Unlike POST /v1/access_codes, a retried unlock_attemptscall with the same key replays the cached result even when that result was a failure — a wrong code, an expired code, whatever it was. This is deliberate: a network retry landing on a fresh attempt could otherwise burn an extra try against the code's failed-attempt lockout, or re-trigger a real physical action.