openapi: 3.1.0 info: title: Capitable Public API version: 1.0.0 description: > Capitable integration API. API keys are created and managed in the api.capitable.fr/console. Each key is restricted to selected restaurants and scopes. servers: - url: https://api.capitable.fr/v1 security: - CapitableApiKey: [] tags: - name: Restaurants description: Restaurant profiles and access. - name: Booking settings description: Online booking configuration. - name: Schedules description: Booking schedules and time-slot rules. - name: Exceptions description: Exceptional closures. - name: Availability description: Available booking slots. - name: Reservations description: Reservations, booking requests, and their status. paths: /restaurants: get: tags: [Restaurants] operationId: listRestaurants summary: List accessible restaurants x-required-scopes: [restaurants:read] responses: "200": description: Restaurants accessible to this integration content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: type: array items: $ref: "#/components/schemas/Restaurant" "401": $ref: "#/components/responses/Unauthorized" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}: parameters: - $ref: "#/components/parameters/RestaurantId" get: tags: [Restaurants] operationId: getRestaurant summary: Get a restaurant x-required-scopes: [restaurants:read] responses: "200": description: Restaurant content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Restaurant" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": $ref: "#/components/responses/RateLimited" patch: tags: [Restaurants] operationId: updateRestaurant summary: Update a restaurant profile description: The slug is read-only. The request body accepts only the fields listed below. x-required-scopes: [restaurants:update] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RestaurantPatch" responses: "200": description: Restaurant profile updated content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Restaurant" "422": $ref: "#/components/responses/ValidationError" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/booking-settings: parameters: - $ref: "#/components/parameters/RestaurantId" get: tags: [Booking settings] operationId: getBookingSettings summary: Get online booking settings x-required-scopes: [booking_settings:read] responses: "200": description: Booking settings content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingSettings" "429": $ref: "#/components/responses/RateLimited" patch: tags: [Booking settings] operationId: updateBookingSettings summary: Enable or disable online bookings x-required-scopes: [booking_settings:update] requestBody: required: true content: application/json: schema: type: object required: [public_booking_enabled] properties: public_booking_enabled: type: boolean responses: "200": description: Booking settings updated content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingSettings" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/booking-schedules: parameters: - $ref: "#/components/parameters/RestaurantId" get: tags: [Schedules] operationId: listBookingSchedules summary: List booking schedules description: Includes the default schedule and dated or seasonal schedules. x-required-scopes: [booking_schedules:read] responses: "200": description: Schedules and their rules content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: type: array items: $ref: "#/components/schemas/BookingSchedule" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": $ref: "#/components/responses/RateLimited" post: tags: [Schedules] operationId: createBookingSchedule summary: Create a dated or seasonal schedule x-required-scopes: [booking_schedules:write] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BookingScheduleCreate" responses: "201": description: Schedule created content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingSchedule" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "422": $ref: "#/components/responses/ValidationError" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/booking-schedules/{scheduleId}: parameters: - $ref: "#/components/parameters/RestaurantId" - name: scheduleId in: path required: true schema: type: string description: Schedule identifier; `default` refers to the regular schedule. get: tags: [Schedules] operationId: getBookingSchedule summary: Get a schedule and its rules x-required-scopes: [booking_schedules:read] responses: "200": description: Schedule and its rules content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingSchedule" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": $ref: "#/components/responses/RateLimited" patch: tags: [Schedules] operationId: updateBookingSchedule summary: Update a seasonal schedule description: The default schedule is read-only. Only fields included in the request are updated. x-required-scopes: [booking_schedules:write] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BookingSchedulePatch" responses: "200": description: Schedule updated content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingSchedule" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "422": $ref: "#/components/responses/ValidationError" "429": $ref: "#/components/responses/RateLimited" delete: tags: [Schedules] operationId: deleteBookingSchedule summary: Deactivate a seasonal schedule description: The schedule is kept in the database and can be reactivated with PATCH. The default schedule cannot be deactivated. x-required-scopes: [booking_schedules:write] responses: "204": description: Schedule deactivated "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/booking-schedules/{scheduleId}/rules: parameters: - $ref: "#/components/parameters/RestaurantId" - name: scheduleId in: path required: true schema: type: string post: tags: [Schedules] operationId: createBookingScheduleRule summary: Add a rule to a schedule x-required-scopes: [booking_schedules:write] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BookingRuleCreate" responses: "201": description: Rule created content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingRule" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "422": $ref: "#/components/responses/ValidationError" "429": $ref: "#/components/responses/RateLimited" /booking-schedule-rules/{ruleId}: parameters: - name: ruleId in: path required: true schema: type: string patch: tags: [Schedules] operationId: updateBookingScheduleRule summary: Update a rule x-required-scopes: [booking_schedules:write] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BookingRulePatch" responses: "200": description: Rule updated content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/BookingRule" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "422": $ref: "#/components/responses/ValidationError" "429": $ref: "#/components/responses/RateLimited" delete: tags: [Schedules] operationId: deleteBookingScheduleRule summary: Deactivate a rule description: The rule is kept in the database and can be reactivated with PATCH. x-required-scopes: [booking_schedules:write] responses: "204": description: Rule deactivated "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/exceptions: parameters: - $ref: "#/components/parameters/RestaurantId" get: tags: [Exceptions] operationId: listRestaurantExceptions summary: List exceptional closures x-required-scopes: [exceptions:read] responses: "200": description: Restaurant closure exceptions content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: type: array items: $ref: "#/components/schemas/ClosureException" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": $ref: "#/components/responses/RateLimited" post: tags: [Exceptions] operationId: createRestaurantException summary: Create an exceptional closure x-required-scopes: [exceptions:write] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ClosureExceptionCreate" responses: "201": description: Closure created content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/ClosureException" "429": $ref: "#/components/responses/RateLimited" /exceptions/{exceptionId}: parameters: - name: exceptionId in: path required: true schema: type: string patch: tags: [Exceptions] operationId: updateRestaurantException summary: Update a closure x-required-scopes: [exceptions:write] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ClosureExceptionPatch" responses: "200": description: Closure updated content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/ClosureException" "429": $ref: "#/components/responses/RateLimited" delete: tags: [Exceptions] operationId: deleteRestaurantException summary: Deactivate a closure x-required-scopes: [exceptions:write] responses: "204": description: Closure deactivated "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/availability: get: tags: [Availability] operationId: getAvailability summary: Get availability x-required-scopes: [availability:read] parameters: - $ref: "#/components/parameters/RestaurantId" - name: date in: query required: true description: The restaurant's local date, in YYYY-MM-DD format. schema: type: string format: date - name: covers in: query required: true schema: type: integer minimum: 1 maximum: 30 responses: "200": description: Available time slots content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: type: array items: $ref: "#/components/schemas/AvailabilitySlot" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "422": $ref: "#/components/responses/ValidationError" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/reservations: parameters: - $ref: "#/components/parameters/RestaurantId" get: tags: [Reservations] operationId: listReservations summary: List reservations x-required-scopes: [reservations:read] parameters: - name: from in: query schema: type: string format: date-time - name: to in: query schema: type: string format: date-time - name: status in: query schema: $ref: "#/components/schemas/ReservationStatus" - name: updated_since in: query schema: type: string format: date-time - name: limit in: query schema: type: integer default: 50 minimum: 1 maximum: 100 - name: offset in: query schema: type: integer default: 0 minimum: 0 responses: "200": description: Reservation page content: application/json: schema: $ref: "#/components/schemas/ReservationPage" "429": $ref: "#/components/responses/RateLimited" post: tags: [Reservations] operationId: createReservation summary: Create a reservation for the restaurant description: > Creates a confirmed reservation using Capitable's staff booking flow. The origin is set to the integration associated with the API key. x-required-scopes: [reservations:create] parameters: - $ref: "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ReservationCreate" responses: "201": description: Reservation created content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "409": $ref: "#/components/responses/Conflict" "429": $ref: "#/components/responses/RateLimited" /restaurants/{restaurantId}/booking-requests: parameters: - $ref: "#/components/parameters/RestaurantId" post: tags: [Reservations] operationId: createBookingRequest summary: Create a booking request from a custom form description: > Follows the online booking rules and the restaurant's confirmation mode. This endpoint also requires an API key. x-required-scopes: [booking_requests:create] parameters: - $ref: "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BookingRequestCreate" responses: "201": description: Booking request created content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "405": description: The request method is not allowed headers: Allow: schema: type: string const: POST content: application/json: schema: type: object required: [success, error] properties: success: type: boolean const: false error: type: object required: [code, message] properties: code: type: string const: METHOD_NOT_ALLOWED message: type: string "409": $ref: "#/components/responses/Conflict" "429": $ref: "#/components/responses/RateLimited" /reservations/{reservationId}: parameters: - name: reservationId in: path required: true schema: type: string get: tags: [Reservations] operationId: getReservation summary: Get a reservation x-required-scopes: [reservations:read] responses: "200": description: Reservation content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "405": description: The request method is not allowed headers: Allow: schema: type: string const: GET, PATCH "429": $ref: "#/components/responses/RateLimited" patch: tags: [Reservations] operationId: updateReservation summary: Update a reservation description: The status, origin, and service cannot be changed through this endpoint. x-required-scopes: [reservations:update] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ReservationPatch" responses: "200": description: Reservation updated content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "405": description: The request method is not allowed headers: Allow: schema: type: string const: GET, PATCH "409": $ref: "#/components/responses/Conflict" "422": description: The request body is invalid "429": $ref: "#/components/responses/RateLimited" /reservations/{reservationId}/confirm: parameters: - name: reservationId in: path required: true schema: type: string post: tags: [Reservations] operationId: confirmReservation summary: Confirm a pending reservation x-required-scopes: [reservations:confirm] responses: "200": description: Reservation confirmed content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "405": description: The request method is not allowed headers: Allow: schema: type: string const: POST "409": $ref: "#/components/responses/Conflict" "429": $ref: "#/components/responses/RateLimited" /reservations/{reservationId}/cancel: parameters: - name: reservationId in: path required: true schema: type: string post: tags: [Reservations] operationId: cancelReservation summary: Cancel a reservation x-required-scopes: [reservations:cancel] responses: "200": description: Reservation cancelled content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "405": description: The request method is not allowed headers: Allow: schema: type: string const: POST "409": $ref: "#/components/responses/Conflict" "429": $ref: "#/components/responses/RateLimited" /reservations/{reservationId}/mark-no-show: parameters: - name: reservationId in: path required: true schema: type: string post: tags: [Reservations] operationId: markReservationNoShow summary: Mark a reservation as a no-show x-required-scopes: [reservations:no_show:write] responses: "200": description: Reservation marked as no-show content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "405": description: The request method is not allowed headers: Allow: schema: type: string const: POST "409": $ref: "#/components/responses/Conflict" "429": $ref: "#/components/responses/RateLimited" /reservations/{reservationId}/clear-no-show: parameters: - name: reservationId in: path required: true schema: type: string post: tags: [Reservations] operationId: clearReservationNoShow summary: Clear a no-show mark x-required-scopes: [reservations:no_show:write] responses: "200": description: No-show mark cleared content: application/json: schema: type: object required: [success, data] properties: success: type: boolean const: true data: $ref: "#/components/schemas/Reservation" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "405": description: The request method is not allowed headers: Allow: schema: type: string const: POST "409": $ref: "#/components/responses/Conflict" "429": $ref: "#/components/responses/RateLimited" components: securitySchemes: CapitableApiKey: type: http scheme: bearer bearerFormat: Capitable API key parameters: RestaurantId: name: restaurantId in: path required: true schema: type: string IdempotencyKey: name: Idempotency-Key in: header required: false description: A unique client-provided key used to prevent duplicate creations when retrying a request. schema: type: string maxLength: 255 responses: Unauthorized: description: API key is missing, invalid, or revoked. Forbidden: description: The key is valid, but its scope is insufficient or the restaurant is not authorized. NotFound: description: Resource not found. Conflict: description: Business conflict, such as a full time slot or an incompatible state. ValidationError: description: Invalid data. RateLimited: description: The rate limit of 5 requests per second has been exceeded. headers: Retry-After: schema: type: integer description: Number of seconds to wait before retrying. content: application/json: schema: type: object required: [success, error] properties: success: type: boolean const: false error: type: object required: [code, message] properties: code: type: string const: RATE_LIMITED message: type: string schemas: Restaurant: type: object properties: id: type: string name: type: string description: Internal name. display_name: type: string slug: type: string readOnly: true phone: type: [string, "null"] address: type: [string, "null"] google_maps_url: type: [string, "null"] public_booking_enabled: type: boolean timezone: type: string example: Europe/Paris readOnly: true RestaurantPatch: type: object minProperties: 1 properties: name: type: string maxLength: 150 display_name: type: string maxLength: 150 phone: type: [string, "null"] address: type: [string, "null"] google_maps_url: type: [string, "null"] BookingSettings: type: object properties: public_booking_enabled: type: boolean BookingSchedule: type: object properties: id: type: string description: Opaque identifier; `default` refers to the regular schedule. name: type: string public_name: type: [string, "null"] icon: type: [string, "null"] valid_from: type: [string, "null"] format: date valid_until: type: [string, "null"] format: date is_active: type: boolean sort_order: type: integer rules: type: array items: $ref: "#/components/schemas/BookingRule" BookingScheduleCreate: type: object required: [name] properties: name: type: string maxLength: 100 public_name: type: [string, "null"] icon: type: [string, "null"] valid_from: type: [string, "null"] format: date valid_until: type: [string, "null"] format: date is_active: type: boolean default: true sort_order: type: integer BookingSchedulePatch: type: object minProperties: 1 properties: name: type: string maxLength: 100 public_name: type: [string, "null"] maxLength: 100 icon: type: [string, "null"] maxLength: 50 valid_from: type: [string, "null"] format: date valid_until: type: [string, "null"] format: date is_active: type: boolean sort_order: type: integer minimum: 0 BookingRule: type: object properties: id: type: string weekday: type: integer minimum: 1 maximum: 7 description: ISO weekday, 1 = Monday and 7 = Sunday. service: type: string start_time: type: string format: time end_time: type: string format: time slot_step_minutes: type: integer minimum: 1 booking_duration_minutes: type: integer minimum: 1 capacity_max: type: integer minimum: 1 is_active: type: boolean BookingRuleCreate: type: object required: - weekday - start_time - end_time - slot_step_minutes - booking_duration_minutes - capacity_max properties: weekday: type: integer minimum: 1 maximum: 7 service: type: string maxLength: 100 start_time: type: string format: time end_time: type: string format: time slot_step_minutes: type: integer minimum: 1 booking_duration_minutes: type: integer minimum: 1 capacity_max: type: integer minimum: 1 is_active: type: boolean default: true BookingRulePatch: type: object minProperties: 1 properties: weekday: type: integer minimum: 1 maximum: 7 service: type: string maxLength: 100 start_time: type: string format: time end_time: type: string format: time slot_step_minutes: type: integer minimum: 1 booking_duration_minutes: type: integer minimum: 1 capacity_max: type: integer minimum: 1 is_active: type: boolean ClosureException: type: object properties: id: type: string type: type: string const: closure start_at: type: string format: date-time end_at: type: string format: date-time reason: type: [string, "null"] is_active: type: boolean ClosureExceptionCreate: type: object additionalProperties: false required: [start_at, end_at] properties: start_at: type: string format: date-time end_at: type: string format: date-time reason: type: [string, "null"] maxLength: 255 ClosureExceptionPatch: type: object additionalProperties: false minProperties: 1 properties: start_at: type: string format: date-time end_at: type: string format: date-time reason: type: [string, "null"] maxLength: 255 is_active: type: boolean AvailabilitySlot: type: object required: [booking_slot_rule_id, start_at, service, available] properties: booking_slot_rule_id: type: string pattern: '^[1-9][0-9]{0,19}$' description: Identifier to submit when creating a booking request. start_at: type: string format: date-time service: type: string available: type: boolean const: true ReservationStatus: type: string enum: [pending, confirmed, cancelled, expired] Reservation: type: object properties: id: type: string restaurant_id: type: string origin: type: string description: Name of the integration that created the reservation, or the legacy origin `web`, `App`, or `walk_in`. booking_language: type: [string, "null"] booking_at: type: string format: date-time service: type: string readOnly: true covers: type: integer customer_name: type: [string, "null"] customer_email: type: [string, "null"] description: Returned only when the integration has permission to read contact details. customer_phone: type: [string, "null"] description: Returned only when the integration has permission to read contact details. customer_notes: type: [string, "null"] status: $ref: "#/components/schemas/ReservationStatus" fulfillment_status: type: [string, "null"] enum: [upcoming, no_show, null] confirmed_at: type: [string, "null"] format: date-time created_at: type: string format: date-time updated_at: type: string format: date-time ReservationCreate: type: object required: [booking_at, covers, customer_name] properties: booking_at: type: string format: date-time description: ISO 8601 with a required UTC offset, in the restaurant's time zone. covers: type: integer minimum: 1 maximum: 200 customer_name: type: string maxLength: 150 customer_email: type: [string, "null"] format: email customer_phone: type: [string, "null"] maxLength: 30 customer_notes: type: [string, "null"] maxLength: 1000 BookingRequestCreate: type: object additionalProperties: false required: [booking_at, booking_slot_rule_id, covers, customer_name, customer_email] properties: booking_at: type: string format: date-time description: ISO 8601 date-time with a required UTC offset; seconds must be 00. booking_slot_rule_id: type: string pattern: '^[1-9][0-9]{0,19}$' description: Identifier returned by the availability endpoint. covers: type: integer minimum: 1 maximum: 30 customer_name: type: string minLength: 1 maxLength: 150 customer_email: type: string format: email maxLength: 190 customer_phone: type: [string, "null"] maxLength: 30 description: Required when the restaurant requires a customer phone number. customer_notes: type: [string, "null"] maxLength: 1000 booking_language: type: string enum: [fr, en, es, it, de, nl, pt, zh, ja] default: fr ReservationPatch: type: object additionalProperties: false minProperties: 1 properties: booking_at: type: string format: date-time covers: type: integer minimum: 1 maximum: 200 customer_name: type: string maxLength: 150 customer_email: type: [string, "null"] format: email customer_phone: type: [string, "null"] maxLength: 30 customer_notes: type: [string, "null"] maxLength: 1000 ReservationPage: type: object required: [success, data, pagination] properties: success: type: boolean const: true data: type: array items: $ref: "#/components/schemas/Reservation" pagination: type: object properties: limit: type: integer offset: type: integer total: type: integer WebhookEvent: type: object required: [id, type, occurred_at, restaurant_id, reservation_id] properties: id: type: string type: type: string enum: - reservation.created - reservation.updated - reservation.confirmed - reservation.cancelled - reservation.expired - reservation.no_show_marked - reservation.no_show_cleared occurred_at: type: string format: date-time restaurant_id: type: string reservation_id: type: string data: $ref: "#/components/schemas/Reservation"