Keeping a calendar in sync

A flow that avoids double bookings: events, a safety sweep and the iCal alternative.

In CesiSync the network is the single source of truth for dates: the database refuses to store two overlapping records for one property. If you still keep a copy in your own system, follow these three steps.

  1. At the start, pull the next 12-18 months with GET /v1/properties/{id}/calendar for every subscribed property.
  2. Then stay current with webhooks: apply the closed and opened ranges of calendar.updated events to your copy.
  3. As a safety net, once a night, or whenever you see a gap in property_seq, pull the calendar again and compare.

Right before telling a customer "available", ask GET /v1/properties/{id}/availability for the latest state. When you send the reservation, the database has the last word: on a clash you get 409; two records are never created.

Hold flow

To hold the dates while the guest pays, use POST /v1/holds. Send your own hold / request number as holdRef (required). The time is the hold period the owner set (for example 15 minutes, 1 hour, 2 days); ask for less with holdMinutes. The dates close for everyone.

  1. When the payment is complete call POST /v1/holds/{id}/confirm and send your own reservation number as externalRef (required). The hold becomes a reservation; the calendar stays closed.
  2. If the guest walks away, DELETE /v1/holds/{id}: the dates reopen.
  3. If time runs out CesiSync reopens the dates by itself (within a few seconds of the end), you get the hold.expired webhook and the reservation becomes EXPIRED.

Asking for more time

If the payment is a little late, ask for more time with POST /v1/holds/{id}/extend (without minutes you get the owner's full period). The extension cannot exceed the owner's limit (400 extension_too_long); a hold can be extended only in its last five minutes (409 extension_too_early) and at most three times, after which you place a new one. If another agency is queued for the same dates you get 409 queue_waiting: the dates then pass to the next in line when the hold ends. The result is in the response (holdExpiresAt) and in the hold.extended event.

Waiting for the answer: webhook or polling

  • Webhook: listen to hold.confirmed, hold.extended and hold.expired; if a screen of yours is waiting, let your server push the event to the user (WebSocket/SSE).
  • Polling: if you would rather not set up webhooks, call GET /v1/holds/{id} every 5 seconds (status and holdExpiresAt). Using both is the safest: the webhook is fast, polling catches what was missed.

The queue (waitlist)

If the dates you want are on another agency's hold, queue with POST /v1/waitlist (with holdRef). When the dates free up the first in line gets waitlist.available and for five minutes (priorityUntil) only that agency can hold them; if it does not, the next one is told. If the dates are already free you get 409 dates_available: just place the hold. See your queue with GET /v1/waitlist, leave it with DELETE /v1/waitlist/{id}.

Reading with iCal

For software that cannot use the API or webhooks every subscription has an iCal address of its own (GET /v1/properties/{id}/calendar.ics, or in the panel under My subscriptions). It lists closed nights only, with no names or details. When the subscription ends the address stops working.

iCal clients poll every hour or so, which alone does not prevent double bookings. Confirm availability through the API before sending a reservation.