ChatBedsDevelopers
Guides

Keep in sync

Keep your copy of a hotel's bookings right, using webhooks for speed and a daily check for certainty.

If you keep your own copy of bookings (for a guest app, a channel manager, a CRM or accounting), you need it to match ChatBeds. Bookings change from everywhere: the front desk, WhatsApp, the hotel's booking page and other partners. Use webhooks to hear about changes within seconds, and a daily check to catch anything a webhook missed.

Scopes you need: reservations:read (needed for webhooks too).

1. Take webhooks

Set your webhook address (see Webhooks) and handle the three events:

sync.js
async function handle(event) {
  if (await seen(event.id)) return;            // a repeat delivery
  const incoming = event.data.reservation;
  const mine = await db.reservations.get(incoming.id);

  // Deliveries can arrive out of order: keep the newest.
  if (mine && mine.updated_at >= incoming.updated_at) return markSeen(event.id);

  await db.reservations.upsert(incoming);       // created, modified and cancelled alike
  await markSeen(event.id);
}

The webhook carries the whole booking, so you rarely need to call back. Check status, not just the event name: a no-show comes as reservation.cancelled with status: "no_show".

Answer fast

Verify the signature, put the event on a queue, and answer 204 at once. Do the database work from the queue.

2. Check daily

Webhooks are retried for about two days, but if your server was down longer, or a bug dropped events, your copy drifts. Once a day, for each hotel, compare the coming days against ChatBeds.

reservation.search finds bookings by exact arrival or departure date. Walk the dates you care about:

nightly.py
from datetime import date, timedelta

def nightly_check(api, property_id: str, days: int = 30) -> None:
    today = date.today()
    for n in range(days):
        day = (today + timedelta(days=n)).isoformat()
        theirs = api.get(f"/properties/{property_id}/reservations",
                         params={"arrival": day, "limit": 100})["reservations"]
        for r in theirs:
            mine = db.reservations.get(r["id"])
            if mine is None or mine["updated_at"] < r["updated_at"]:
                db.reservations.upsert(r)
        # Anything you hold for that arrival day that ChatBeds doesn't: fetch it by id.
        for missing in db.reservations.arriving(property_id, day, exclude=[r["id"] for r in theirs]):
            db.reservations.upsert(api.get(f"/reservations/{missing['id']}")["reservation"])

Thirty days is 30 calls per hotel, well inside the rate limit. Spread hotels across the night rather than starting them all at once.

One page per day

limit is at most 100. If a day returns exactly 100, narrow it with status (one call per status) so nothing is cut off.

3. Your own bookings

For bookings you made, you already have ChatBeds' id from the create call. Keep it next to your own ID, and search by external_ref if you ever lose it.

When a hotel disconnects

When a hotel disconnects your app, your tokens stop working (401 on calls, invalid_grant on refresh) and webhooks stop. Mark the connection as ended, keep or delete the data under your privacy terms, and stop the nightly check for that hotel.

Building something?

On this page