Skip to content

Event catalog

These are the event types you can subscribe to. Each event uses the standard envelope; the examples below show the full envelope with a representative data.object.

Handle unknown event types gracefully — new types may be added over time.

EventWhen it fires
reservation.createdA reservation is created — its status is confirmed (auto-confirmed) or pending (awaiting approval).
reservation.confirmedA pending reservation is later approved. Auto-confirmed reservations do not fire this.
reservation.declinedA pending reservation is declined.
reservation.updatedA reservation’s details change (party size, date, notes, …).
reservation.partially_seatedSome, but not all, of the party has been seated.
reservation.seatedThe party has been seated.
reservation.completedThe reservation has finished (the party has left).
reservation.cancelledThe reservation is cancelled.
reservation.no_showThe party did not arrive.
guest.createdA guest record is created.
guest.updatedA guest’s details change.
guest.deletedA guest is deleted (e.g. data-protection erasure).
feedback.receivedA guest submits feedback after a visit.

The data.object of every reservation event is a full reservation, in the same shape as the API reference returns — the complete resource snapshot, not a diff.

Only reservation.updated carries data.previous_attributes; the other reservation events omit it. When present, previous_attributes contains only the changed fields among party_size, service_date, guest_notes, internal_notes, and guest (the previous guest as a bare gst_ id). Time changes are reflected in the snapshot’s starts_at / ends_at, not in previous_attributes.

A reservation is created (via the widget, the back office, an integration, etc.). This fires for every new reservation — check data.object.status to tell them apart: confirmed means it was auto-confirmed at creation (no approval step; typical for back-office and default bookings), while pending means it needs approval and will later emit reservation.confirmed or reservation.declined.

{
"id": "evt_1K8xQ2m4Vd0pErJ7sN1aZ9bQ",
"object": "event",
"type": "reservation.created",
"created": "2026-06-20T09:04:18Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "pending",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 4,
"actual_party_size": null,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-20T11:04:18+02:00"
}
}
}

A pending reservation is approved — the manual-approval flow. This fires only for reservations created as pending; an auto-confirmed reservation never emits reservation.confirmed — it arrives once, as reservation.created with status: "confirmed".

{
"id": "evt_2M9yR3n5We1qFsK8tO2bA0cR",
"object": "event",
"type": "reservation.confirmed",
"created": "2026-06-20T09:30:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "confirmed",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 4,
"actual_party_size": null,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-20T11:30:00+02:00"
}
}
}

A pending reservation is declined.

{
"id": "evt_3N0zS4o6Xf2rGtL9uP3cB1dS",
"object": "event",
"type": "reservation.declined",
"created": "2026-06-20T09:31:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "cancelled",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 4,
"actual_party_size": null,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-20T11:31:00+02:00"
}
}
}

A reservation’s details change — for example party size or notes. previous_attributes lists the changed fields and their previous values (here, the party size grew from 4 to 6 and the guest note changed).

{
"id": "evt_4O1aT5p7Yg3sHuM0vQ4dC2eT",
"object": "event",
"type": "reservation.updated",
"created": "2026-06-25T07:12:55Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "confirmed",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 6,
"actual_party_size": null,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table; celebrating an anniversary",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-25T09:12:55+02:00"
},
"previous_attributes": {
"party_size": 4,
"guest_notes": "Window table if possible"
}
}
}

Some, but not all, of the party has been seated.

{
"id": "evt_5P2bU6q8Zh4tIvN1wR5eD3fU",
"object": "event",
"type": "reservation.partially_seated",
"created": "2026-06-27T18:05:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "partially_seated",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 6,
"actual_party_size": 4,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [
{
"object": "table",
"id": "tbl_QpZ2",
"name": "12",
"min_capacity": 2,
"max_capacity": 6,
"section": {
"object": "section",
"id": "sec_Lm8",
"name": "Main room",
"area_type": "indoor"
}
}
],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-27T20:05:00+02:00"
}
}
}

The party has been seated.

{
"id": "evt_6Q3cV7r9Ai5uJwO2xS6fE4gV",
"object": "event",
"type": "reservation.seated",
"created": "2026-06-27T18:08:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "seated",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 6,
"actual_party_size": 6,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [
{
"object": "table",
"id": "tbl_QpZ2",
"name": "12",
"min_capacity": 2,
"max_capacity": 6,
"section": {
"object": "section",
"id": "sec_Lm8",
"name": "Main room",
"area_type": "indoor"
}
}
],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-27T20:08:00+02:00"
}
}
}

The reservation has finished — the party has left.

{
"id": "evt_7R4dW8s0Bj6vKxP3yT7gF5hW",
"object": "event",
"type": "reservation.completed",
"created": "2026-06-27T20:15:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "completed",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 6,
"actual_party_size": 6,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-27T22:15:00+02:00"
}
}
}

The reservation is cancelled.

{
"id": "evt_8S5eX9t1Ck7wLyQ4zU8hG6iX",
"object": "event",
"type": "reservation.cancelled",
"created": "2026-06-26T16:00:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "cancelled",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 6,
"actual_party_size": null,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-26T18:00:00+02:00"
}
}
}

The party did not arrive.

{
"id": "evt_9T6fY0u2Dl8xMzR5aV9iH7jY",
"object": "event",
"type": "reservation.no_show",
"created": "2026-06-27T18:45:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "reservation",
"id": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ",
"status": "no_show",
"source": "widget",
"booking_channel": "website_widget",
"party_size": 6,
"actual_party_size": null,
"service_date": "2026-06-27",
"starts_at": "2026-06-27T20:00:00+02:00",
"ends_at": "2026-06-27T22:00:00+02:00",
"guest_notes": "Window table if possible",
"internal_notes": null,
"guest": "gst_3Td9Lp0WqZ",
"tables": [],
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-27T20:45:00+02:00"
}
}
}

The data.object of a guest event is a full guest, in the same shape as the API reference returns. Guest events do not carry previous_attributes — compare against your own stored copy if you need a diff.

A guest record is created.

{
"id": "evt_A1bC2dE3fG4hI5jK6lM7nO8p",
"object": "event",
"type": "guest.created",
"created": "2026-06-20T09:04:18Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "guest",
"id": "gst_3Td9Lp0WqZ",
"first_name": "Marie",
"last_name": "Dupont",
"email": "[email protected]",
"phone": "+33612345678",
"notes": null,
"blacklisted": false,
"blacklist_reason": null,
"dietary_preferences": [],
"allergies": [],
"birthday": null,
"anniversary": null,
"vip": false,
"language": "fr",
"source": "widget",
"marketing_email_consent": true,
"marketing_email_consent_at": "2026-06-20T11:04:18+02:00",
"marketing_sms_consent": false,
"marketing_sms_consent_at": null,
"visit_count": 0,
"no_show_count": 0,
"cancellation_count": 0,
"first_visit_at": null,
"last_visit_at": null,
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-20T11:04:18+02:00"
}
}
}

A guest’s details change. (Visit statistics alone do not trigger this event — see Pagination.)

{
"id": "evt_B2cD3eF4gH5iJ6kL7mN8oP9q",
"object": "event",
"type": "guest.updated",
"created": "2026-06-28T08:00:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "guest",
"id": "gst_3Td9Lp0WqZ",
"first_name": "Marie",
"last_name": "Dupont",
"email": "[email protected]",
"phone": "+33612345678",
"notes": null,
"blacklisted": false,
"blacklist_reason": null,
"dietary_preferences": ["vegetarian"],
"allergies": [],
"birthday": null,
"anniversary": null,
"vip": true,
"language": "fr",
"source": "widget",
"marketing_email_consent": true,
"marketing_email_consent_at": "2026-06-20T11:04:18+02:00",
"marketing_sms_consent": false,
"marketing_sms_consent_at": null,
"visit_count": 3,
"no_show_count": 0,
"cancellation_count": 0,
"first_visit_at": "2026-06-21T21:00:00+02:00",
"last_visit_at": "2026-06-27T20:00:00+02:00",
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-28T10:00:00+02:00"
}
}
}

A guest is deleted (for example, a data-protection erasure request). The data.object is a final snapshot of the full guest (the same shape as any other guest payload); the guest is no longer retrievable from the API afterwards.

{
"id": "evt_C3dE4fG5hI6jK7lM8nO9pQ0r",
"object": "event",
"type": "guest.deleted",
"created": "2026-06-29T07:00:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "guest",
"id": "gst_3Td9Lp0WqZ",
"first_name": "Marie",
"last_name": "Dupont",
"email": "[email protected]",
"phone": "+33612345678",
"notes": null,
"blacklisted": false,
"blacklist_reason": null,
"dietary_preferences": ["vegetarian"],
"allergies": [],
"birthday": null,
"anniversary": null,
"vip": true,
"language": "fr",
"source": "widget",
"marketing_email_consent": true,
"marketing_email_consent_at": "2026-06-20T11:04:18+02:00",
"marketing_sms_consent": false,
"marketing_sms_consent_at": null,
"visit_count": 3,
"no_show_count": 0,
"cancellation_count": 0,
"first_visit_at": "2026-06-21T21:00:00+02:00",
"last_visit_at": "2026-06-27T20:00:00+02:00",
"created_at": "2026-06-20T11:04:18+02:00",
"updated_at": "2026-06-28T10:00:00+02:00"
}
}
}

A guest submits feedback after a visit. The data.object is an embedded feedback value-object (it is not a retrievable API resource) carrying the ratings and comment, plus bare-id references to the guest and the reservation it relates to.

{
"id": "evt_D4eF5gH6iJ7kL8mN9oP0qR1s",
"object": "event",
"type": "feedback.received",
"created": "2026-06-28T11:20:00Z",
"livemode": true,
"api_version": "2026-06-27",
"data": {
"object": {
"object": "feedback",
"id": "fb_7hn2qp",
"overall_rating": 5,
"food_rating": 5,
"service_rating": 4,
"comment": "Lovely evening, great service.",
"responded_at": "2026-06-28T13:20:00+02:00",
"guest": "gst_3Td9Lp0WqZ",
"reservation": "resv_8xKQ2m4Vd0pErJ7sN1aZ9bQ"
}
}
}

The overall_rating, food_rating, service_rating, and comment fields may each be null when the guest did not provide them. Use this event to invite guests to leave a review, route feedback to the right team, or sync ratings into your own tools.