openapi: 3.0.3
info:
  title: Handling Webhook Events API
  description: >
    Webhook API specification for receiving booking change notifications from
    The Bookings Group system.

    Distributors must implement this endpoint to receive real-time notifications
    about booking updates.
  version: 1.2.0
  contact:
    name: Bookable
    url: https://www.bookabletech.com
    email: hello@bookabletech.com
  license:
    name: Proprietary
servers:
  - url: https://your-distributor-domain.com
    description: Distributor webhook endpoint
paths:
  /:
    post:
      summary: Receive booking change notifications
      description: >
        Endpoint that distributors must implement to receive booking change
        notifications.

        The Bookings Group system will send HTTP POST requests to this endpoint
        whenever

        a booking is created, updated, or cancelled.
      operationId: receiveBookingNotification
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingNotification'
      responses:
        '204':
          description: Notification received and will be processed
        '400':
          description: Bad request - invalid payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error: Invalid booking data format
                message: Required field 'booking.id' is missing
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - apiKey: []
components:
  schemas:
    BookingNotification:
      type: object
      required:
        - eventType
        - timestamp
      properties:
        eventType:
          type: string
          enum:
            - booking.updated
          description: Type of event that triggered the notification
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the event occurred
        bookings:
          type: array
          items:
            $ref: '#/components/schemas/Booking'
          description: Booking data (present when eventType is booking.*)
    Booking:
      type: object
      required:
        - id
        - compositeId
        - date
        - time
        - partySize
        - status
        - reference
        - firstName
        - lastName
        - email
        - phone
        - duration
        - notes
        - createdDate
        - lastUpdate
      properties:
        id:
          type: string
          description: A globally unique identifier for the reservation
          example: 29|X9|275cc44dd2e2496fba44857c9257443a|B
        compositeId:
          type: string
          description: A globally unique identifier for the venue/product
          example: >-
            29|X9|275cc44dd2e2496fba44857c9257443a|d99128c546b34b619c4477b712869f2b
        date:
          type: string
          format: date
          description: The date of the reservation (YYYY-MM-DD)
          example: '2025-06-25'
        time:
          type: string
          format: time
          description: The time of the reservation (HH:MM:SS)
          example: '19:30:00'
        partySize:
          type: integer
          minimum: 1
          maximum: 50
          description: Number of guests for the reservation
          example: 4
        status:
          $ref: '#/components/schemas/BookingStatusEnum'
          description: Current status of the reservation
        reference:
          type: string
          maxLength: 100
          description: Reference code for the reservation
          example: REF-20250617-001
        firstName:
          type: string
          maxLength: 100
          description: Guest's first name
          example: John
        lastName:
          type: string
          maxLength: 100
          description: Guest's last name
          example: Doe
        email:
          type: string
          format: email
          maxLength: 255
          description: Email address of the guest
          example: john.doe@example.com
        phone:
          type: string
          maxLength: 50
          description: Phone number of the guest
          example: '+1234567890'
        company:
          type: string
          maxLength: 200
          nullable: true
          description: Company name if the reservation is business-related
          example: Acme Corp
        location:
          $ref: '#/components/schemas/LocationDto'
          nullable: true
          description: Location details for the reservation
        duration:
          type: integer
          minimum: 15
          maximum: 1440
          description: Duration of the reservation in minutes
          example: 120
        productType:
          type: string
          maxLength: 100
          nullable: true
          description: Type of product or service reserved
          example: dinner
        notes:
          type: string
          maxLength: 1000
          description: Additional notes for the reservation
          example: Window table preferred
        source:
          type: string
          description: the distributor source make the booking
          example: MyDistributor
        createdDate:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the reservation was created
          example: '2025-06-17T09:15:00Z'
        lastUpdate:
          type: string
          format: date-time
          description: ISO 8601 timestamp of the last reservation update
          example: '2025-06-17T10:30:00Z'
        preorders:
          type: array
          description: List of preordered packages for the booking.
          items:
            type: object
            properties:
              packageId:
                type: string
                description: Unique identifier for the preordered package.
              name:
                type: string
                description: Package name
                example: '*Pan roasted Padron peppers (V)'
              description:
                type: string
                description: Detailed package description
                example: >-
                  5 items per guest: Salmon & celeriac on rye, Buttermilk fries
                  chicken...
              type:
                type: string
                description: Main package type
                example: food
              quantity:
                type: integer
                description: Quantity of the preordered package.
              price:
                type: number
                format: float
                description: Package price
                example: 5.57
            required:
              - packageId
              - quantity
        preorderMenus:
          type: array
          description: List of preordered menus for the booking.
          items:
            type: object
            properties:
              menuId:
                type: string
                description: Unique identifier for the preordered menu.
            required:
              - menuId
    LocationDto:
      type: object
      properties:
        address:
          type: string
          maxLength: 200
          description: Street address
          example: 123 Main Street
        city:
          type: string
          maxLength: 100
          description: City name
          example: New York
        state:
          type: string
          maxLength: 100
          description: State or province
          example: NY
        country:
          type: string
          maxLength: 100
          description: Country name
          example: US
        postalCode:
          type: string
          maxLength: 20
          description: Postal or ZIP code
          example: '10001'
    BookingStatusEnum:
      type: string
      enum:
        - pending
        - confirmed
        - cancelled
        - completed
        - no_show
      description: Current status of the reservation
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Error code or short description
          example: validation_error
        message:
          type: string
          description: Detailed error message
          example: Required field 'booking.id' is missing
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authentication
  examples:
    BookingCreatedNotification:
      summary: Booking Created Event
      value:
        eventType: booking.created
        timestamp: '2025-06-17T10:30:00Z'
        booking:
          id: 12345678-1234-1234-1234-123456789012
          venueId: 87654321-4321-4321-4321-210987654321
          date: '2025-06-25'
          time: '19:30:00'
          partySize: 4
          status: confirmed
          reference: REF-20250617-001
          firstName: John
          lastName: Doe
          email: john.doe@example.com
          phone: '+1234567890'
          company: null
          location: null
          duration: 120
          productType: dinner
          notes: No special requirements
          createdDate: '2025-06-17T10:30:00Z'
          lastUpdate: '2025-06-17T10:30:00Z'
    BookingUpdatedNotification:
      summary: Booking Updated Event
      value:
        eventType: booking.updated
        timestamp: '2025-06-17T11:45:00Z'
        booking:
          id: 12345678-1234-1234-1234-123456789012
          venueId: 87654321-4321-4321-4321-210987654321
          date: '2025-06-25'
          time: '21:30:00'
          partySize: 6
          status: confirmed
          reference: REF-20250617-001
          firstName: John
          lastName: Doe
          email: john.doe@example.com
          phone: '+1234567890'
          company: null
          location: null
          duration: 120
          productType: dinner
          notes: Cancelled by customer
          createdDate: '2025-06-17T10:30:00Z'
          lastUpdate: '2025-06-17T11:45:00Z'
