Start
Authentication & keys
A bearer key per property, scoped to what the integration needs, optionally locked to your servers' addresses, shown once, rotated without downtime.
The header
Authorization: Bearer zsk_live_…zsk_live_ + 43 base64url characters; shown once at creation; one key = one property. Never in: query string, x-api-key, user-api-key. A request on a key acts as the property owner for that one property and nothing else; there is no way to name another property.
Scopes
A key holds the scopes the owner granted at creation (editable later without rotating). Every route names the one scope it needs; a key without it is 403 SCOPE_MISSING. bookings:payments needs bookings:write. GET /property echoes this key's scopes.
| Scope | Lets the key |
|---|---|
| ari:read | Read availability, rates, restrictions and sync state from our record |
| ari:write | Set availability, rates and restrictions (pushed to every connected channel) |
| bookings:read | Read bookings this key created |
| bookings:write | Create and cancel bookings in the PMS (inventory updates and reaches the channels) |
| bookings:payments | Record a payment on a booking it creates (needs bookings:write) |
The channel-manager scopes need a property with the channel manager on and its local rates and availability set as the source of truth (the owner's support contact flips that). The booking scopes need a property that runs the ZimmerStack PMS. A key may hold both families; most hold one.
Address allowlist
Optional per key: up to 20 IPv4/IPv6 addresses or CIDR ranges. Set it to your servers' egress addresses: a request from anywhere else is 403 IP_NOT_ALLOWED, counts against the address's authentication budget, and is shown to the owner.
A refused request answers 403 IP_NOT_ALLOWED, counts against the address's authentication budget (240 requests and 20 failures a minute per address), and is shown to the owner on the key as “refused from <address>”. The address is the one our edge saw; forwarded-for headers you send are ignored.
A key's life
- Created by the owner, shown once. We store a keyed hash only; nobody at ZimmerStack can read a key back.
- Edited without rotating: the owner can change scopes and the allowlist; your key keeps working.
- Rotated: a new key is minted and the old one keeps answering for 24 hours, then answers
401 API_KEY_REVOKED. Swap at leisure. - Revoked by the owner (or by ZimmerStack support at the owner's request):
401 API_KEY_REVOKEDfrom then on. - Up to five active keys per property, so a staging and a production system never share one.
What a bad key looks like
Anything that is not a live key is 401 API_KEY_INVALID — missing, malformed, unknown, or a known prefix with the wrong key. The answer says no more than that, by design. A revoked or rotated-out key is told so: 401 API_KEY_REVOKED. Twenty refused authentications from one address in a minute and the address is cut off before any lookup.
Idempotency
Writes accept x-idempotency-key (10–64 characters of letters, digits, _ and -). The same key with the same body within 7 days replays the stored answer; the same key with a different body is 409 IDEMPOTENCY_KEY_REUSED. Bookings have a stronger guarantee on top: externalReference is unique per property for ever.
Facts on this page (routes, samples, limits, codes) come from the API's public contract read live, Tue, 20 Oct 2026 13:10:41 GMT.