Skip to content

Webhooks overview

Webhooks push events to your server in real time, so you do not have to poll. When something happens in a restaurant — a reservation is created, a guest is updated, feedback comes in — we send an HTTP POST to a URL you control with a JSON event describing what happened.

The API is in beta. Self-serve endpoint management from the back office (URL, event selection, signing secret, and a delivery log with manual replay) is on the roadmap but not available yet. For now, webhook endpoints are provisioned on request: the Service team registers your endpoint URL and the events you want, and returns a signing secret (whsec_…) used to verify signatures.

Each endpoint is pinned to an API version at creation, so the payload shape you receive stays stable.

Every delivery is a JSON object with this envelope:

{
"id": "evt_1K8xQ2m4Vd0pErJ7sN1aZ9bQ",
"object": "event",
"type": "reservation.updated",
"created": "2026-06-27T17:30:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": { "object": "reservation", "id": "resv_…" },
"previous_attributes": { "party_size": 2 }
}
}
FieldDescription
idUnique event id (evt_…). Use this to deduplicate (see below).
objectAlways "event".
typeThe event type, e.g. reservation.updated. See the event catalog.
createdWhen the event was emitted — ISO-8601 in UTC (a Z suffix). See the timezone note below.
livemodeAlways true for real events.
api_versionThe version the payload is rendered in (the endpoint’s pinned version).
data.objectA full snapshot of the affected resource, in the same shape as the API.
data.previous_attributesOnly on reservation.updated — a map of the changed fields to their previous values. Omitted on every other event type.

Return a 2xx status code quickly (ideally within a few seconds) to acknowledge receipt. Do the real work asynchronously. Any non-2xx response, a timeout, or a connection error is treated as a failed delivery and will be retried.

Delivery is at-least-once. The same event may be delivered more than once (for example, if your server is slow to acknowledge and we retry, or after a transient network error). Deduplicate on the event id (evt_…): record the ids you have processed and ignore repeats. Make your handler idempotent.

Events are not guaranteed to arrive in the order they occurred. For example, you might receive reservation.seated before reservation.confirmed. Do not assume order. When a decision depends on current state, treat the event as a hint and fetch the latest resource from the API, or reconcile using each resource’s updated_at.

If a delivery fails, we retry with exponential backoff over roughly 3 days. If every attempt fails for that whole window (the endpoint stays unreachable or keeps returning errors), the endpoint is automatically disabled and an alert is raised. You will need to fix the endpoint and have it re-enabled. To recover events missed while an endpoint was down, re-fetch with updated_since.

Imported reservations don’t emit webhooks

Section titled “Imported reservations don’t emit webhooks”