Start
Quickstart
A key from the owner, one request, and the answer that tells you it landed. Ten minutes.
- 1
Get a key from the property owner
The owner creates it in Admin → Developers → API keys (or Channels → Integrations) and picks its scopes: the channel-manager pair for a PMS, the booking pair for a booking engine. Ask them to add your servers' public addresses to the key's allowlist. The key is shown once; it starts withzsk_live_. - 2
Ask who you are
GET /propertyworks for every key and echoes its scopes and the products the property runs.GET /cataloggives the numeric room-type and rate-plan ids every write uses. Never guess an id. - 3
Send one write
A PMS pushes an availability range (PUT /availability) and pollsGET /sync. A booking engine posts one booking (POST /bookings) and gets 201 with the PMS reference.
Who am I?
curl "https://api.zimmerstack.com/api/v1/connect-api/v1/property" \
-H "Authorization: Bearer $ZIMMERSTACK_CONNECT_KEY"
# → 200 { "id": 61, "name": "…", "timezone": "Asia/Kolkata", "currency": "INR",
# "scopes": ["bookings:read", "bookings:write"], "products": { "channelManager": true, "pms": true }, … }A booking engine: post one booking
One entry in rooms per room. You price the stay; send the nightly rate you charged. externalReference is your reservation id and makes retries safe: the same value again returns the same booking with 200.
curl -X POST "https://api.zimmerstack.com/api/v1/connect-api/v1/bookings" \
-H "Authorization: Bearer $ZIMMERSTACK_CONNECT_KEY" \
-H "Content-Type: application/json" \
-d '{"externalReference":"WEB-2026-000123","checkIn":"2026-12-20","checkOut":"2026-12-23","currency":"INR","guest":{"name":"Asha Verma","phone":"+919876543210","email":"asha@example.com","notes":"Late arrival, after 22:00"},"rooms":[{"roomTypeId":412,"ratePlanId":901,"adults":2,"children":1,"nightlyRate":"4500.00"},{"roomTypeId":412,"ratePlanId":901,"adults":2,"nightlyRate":"4500.00"}],"payment":{"amount":"9000.00","method":"ONLINE","reference":"pay_QwErTy123"},"notes":"Promo WINTER10 applied on the website"}'
# → 201 { "bookingId": 48213, "reference": "SB-7KQ2MX9D", "status": "UPCOMING",
# "inventory": { "eventRecorded": true, "channelManager": true, "pushedBy": "inventory-drain" }, … }{
"externalReference": "WEB-2026-000123",
"checkIn": "2026-12-20",
"checkOut": "2026-12-23",
"currency": "INR",
"guest": {
"name": "Asha Verma",
"phone": "+919876543210",
"email": "asha@example.com",
"notes": "Late arrival, after 22:00"
},
"rooms": [
{
"roomTypeId": 412,
"ratePlanId": 901,
"adults": 2,
"children": 1,
"nightlyRate": "4500.00"
},
{
"roomTypeId": 412,
"ratePlanId": 901,
"adults": 2,
"nightlyRate": "4500.00"
}
],
"payment": {
"amount": "9000.00",
"method": "ONLINE",
"reference": "pay_QwErTy123"
},
"notes": "Promo WINTER10 applied on the website"
}A PMS: push an availability range
curl -X PUT "https://api.zimmerstack.com/api/v1/connect-api/v1/availability" \
-H "Authorization: Bearer $ZIMMERSTACK_CONNECT_KEY" \
-H "Content-Type: application/json" \
-H "x-idempotency-key: $(uuidgen | tr -d -)" \
-d '{"updates":[{"roomTypeId":412,"dateFrom":"2026-11-01","dateTo":"2026-11-30","available":5},{"roomTypeId":412,"dateFrom":"2026-11-14","dateTo":"2026-11-14","available":2}]}'
# → 202 { "batchId": "…", "acceptedCells": 30, "noopCells": 0, "poll": "…/batches/…" }
curl "https://api.zimmerstack.com/api/v1/connect-api/v1/sync" -H "Authorization: Bearer $ZIMMERSTACK_CONNECT_KEY"
# → { "inventory": { "state": "IN_SYNC", … }, "rates": { "dirtyCells": 0, … } }Node, no SDK
const BASE = "https://api.zimmerstack.com/api/v1/connect-api/v1";
const KEY = process.env.ZIMMERSTACK_CONNECT_KEY;
async function call(method, path, body) {
const res = await fetch(BASE + path, {
method,
headers: { authorization: `Bearer ${KEY}`, "content-type": "application/json" },
body: body === undefined ? undefined : JSON.stringify(body),
});
if (res.status === 429) {
const wait = Number(res.headers.get("retry-after") ?? "5");
await new Promise((r) => setTimeout(r, wait * 1000));
return call(method, path, body); // the same request, after Retry-After
}
const json = await res.json();
if (!res.ok) throw new Error(`${res.status} ${json.data?.code}: ${json.message}`);
return json.data;
}
const property = await call("GET", "/property");
const booking = await call("POST", "/bookings", {/* see the Bookings page */});Facts on this page (routes, samples, limits, codes) come from the API's public contract read live, Tue, 20 Oct 2026 13:10:40 GMT.