openapi: 3.0.3
info:
  contact:
    email: xeniaconnect@staysitu.com
    name: Situ Technical Support
  description: Situ's API for seamless integration with Situ's workflow.
  title: Xenia Connect API
  version: 1.0.1
servers:
  - description: Production
    url: https://api-xenia.staysitu.com
  - description: Sandbox
    url: https://api-xenia-cisandbox.staysitu.com
tags:
  - description: >-
      Bookings are the next step in the booking journey after an enquiry has
      been created. Bookings are created when a quote is accepted by the client.
    name: bookings
    x-displayName: Bookings
  - description: >-
      Enquiries are the start point in the booking journey. Providing as much
      information as possible upfront about an enquiry will increase its
      conversion rate and reduce touchpoints. We are constantly looking for what
      we can add to our set of information to make our process easier for
      everybody. If you have any suggestions get in contact!
    name: enquiries
    x-displayName: Enquiries
  - description: >-
      Quotes are the 2nd stage of the booking journey. Quotes are created when a
      specialist has found properties that match the enquiry requirements and
      send shortlisted properties to the client.
    name: quotes
    x-displayName: Quotes
  - description: >-
      Operations that only exist within the sandbox environment. These are not
      available in production. You can use these operations to trigger state
      changes in the sandbox environment to test your webhooks and other
      operations.
    name: sandbox
    x-displayName: Sandbox Operations
  - description: >-
      Manage your webhooks with this set of operations. The maximum limit for
      webhooks per environment is 5. If you need more than this please contact
      us.
    name: webhooks
    x-displayName: Webhook Operations
paths:
  /external-api/v1/enquiries:
    post:
      description: Create a new enquiry for Situ to begin the quoting process on.
      operationId: createEnquiry
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createEnquiryRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/enquiryResponse'
          description: The created enquiry object.
        '400':
          content:
            application/problem+json:
              example:
                detail: Validation failed for one or more fields.
                errors:
                  clientReference:
                    - Client reference must be at least 3 characters.
                  id:
                    - The externalId field is required.
                instance: /external-api/v1/enquiries
                status: 400
                title: One or more validation errors occurred.
                type: VALIDATION_ERROR
              schema:
                $ref: '#/components/schemas/validationProblemDetails'
          description: >-
            Validation errors have occurred, e.g. missing required fields or
            invalid data types.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '500':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object
      summary: Create a new enquiry
      tags:
        - enquiries
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/enquiries/{id}:
    get:
      operationId: getEnquiry
      parameters:
        - description: Can be either the enquiries `xeniaReference` or `externalId`.
          example: R4E2F3A4
          in: path
          name: id
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/enquiryResponse'
          description: The enquiry object
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: >-
                  The requested enquiry was not found, please ensure you are
                  using the correct Xenia reference or your own external ID.
                instance: id
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The enquiry was not found. This may be because the enquiry has been
            deleted or the ID provided is invalid. The provided error status
            will be `RESOURCE_NOT_FOUND`.
      summary: Get an enquiry
      tags:
        - enquiries
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/quotes:
    get:
      description: >-
        Get a paginated list of quotes, optionally filtered by Situ enquiry id
        or the external id provided when calling the create enquiry endpoint.
      operationId: getQuotes
      parameters:
        - description: >-
            Optional cursor used to pull the next or previous page for
            pagination.
          in: query
          name: cursor
          example: >-
            MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDAwfDIwMjQtMDctMDFUMTQ6MzA6MDBafE5leHQ=
          schema:
            nullable: true
            type: string
            default: 'null'
        - description: The maximum number of items to return.
          example: 10
          in: query
          name: pageSize
          schema:
            default: 10
            minimum: 1
            maximum: 100
            type: integer
        - description: >-
            Indicates whether to order the items in ascending or descending
            order.
          in: query
          name: order
          schema:
            $ref: '#/components/schemas/paginationOrder'
        - description: >-
            Used in conjunction with the order parameter and determines which
            field we're ordering by.
          in: query
          name: sort
          schema:
            $ref: '#/components/schemas/quoteListSortField'
        - description: Optionally filter quotes by the xenia enquiry ID.
          in: query
          name: xeniaEnquiryReference
          example: R4E2F3A4
          schema:
            nullable: true
            type: string
            default: 'null'
        - description: Optionally filter quotes by the client supplied external enquiry ID.
          in: query
          name: enquiryExternalId
          example: e234abcef
          schema:
            $ref: '#/components/schemas/enquiryExternalIdFilter'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/quotesResponse'
              example:
                data:
                  - id: 5fa4be11-f6ac-4ba3-9afb-64c52c9420ba
                    xeniaEnquiryReference: R4E2F3A4
                    clientEnquiryReference: CLIENT-REF-123
                    createdAt: '2024-07-01T14:30:00Z'
                    updatedAt: '2024-07-01T15:45:00Z'
                    invalidatedAt: null
                    description: Quote for 3-night stay in London
                    state: ACTIVE
                    bookedQuoteItem:
                      bookingId: BK-2024-123456
                      quoteItemId: 4e67c3eb-912a-4da2-91e9-dba4d8e2437e
                      createdAt: '2024-07-02T09:30:00Z'
                    items:
                      - id: 4e67c3eb-912a-4da2-91e9-dba4d8e2437e
                        booked: true
                        property:
                          propertyName: The Savoy Hotel
                          propertyUrl: https://core.xenia.staysitu.com/properties/789
                          locationMapLink: https://maps.app.goo.gl/ob21JeqFf6rdkLif7
                          overview: A luxurious hotel in the heart of London
                          coordinates:
                            latitude: 51.5074
                            longitude: -0.1278
                          locationOverview: Located in Westminster, near major attractions
                          additionalDetails: 24-hour concierge service, spa facilities
                          termsOfStay: >-
                            Check-in after 3 PM, check-out before 11 AM. No
                            smoking.
                          images:
                            - url: >-
                                https://images.example.com/property/savoy-suite-main.jpg
                              caption: Master bedroom with city view
                              ordering: 1
                              default: true
                            - url: >-
                                https://images.example.com/property/savoy-bathroom.jpg
                              caption: Luxury marble bathroom
                              ordering: 2
                              default: false
                            - url: >-
                                https://images.example.com/property/savoy-living.jpg
                              caption: Spacious living area
                              ordering: 3
                              default: false
                          units:
                            - unitName: Deluxe Suite
                              numberOfBedrooms: 2
                              numberOfBathrooms: 1
                              maxOccupancy: 4
                              unitSize: 85.5
                              images:
                                - url: >-
                                    https://images.example.com/property/deluxe-suite-bedroom.jpg
                                  caption: Deluxe Suite master bedroom
                                  ordering: 1
                                  default: true
                                - url: >-
                                    https://images.example.com/property/deluxe-suite-bathroom.jpg
                                  caption: Deluxe Suite bathroom
                                  ordering: 2
                                  default: false
                              priceBreakdown:
                                currency: GBP
                                wholeStay:
                                  excludingTax: 2100
                                  includingTax: 2500
                                  taxAmount: 400
                                perPeriod:
                                  period: NIGHTLY
                                  amountsExcludingAdditionalCharges:
                                    excludingTaxWithBookingFee: 400
                                    includingTaxWithBookingFee: 440
                              availability:
                                from: '2024-08-15'
                                to: '2024-08-20'
                                nights: 5
                              additionalCharges:
                                - summary: Cleaning fee (per stay)
                                  grossCost: 40
                                  chargeFormat:
                                    chargeFormatType: SPECIFIED_RATE
                                    rate: 40
                                  vat:
                                    vatApplicability: INCLUDED
                                    rate: null
                                  chargeFrequency: ONE_OFF
                                  chargedPerGuest: false
                                  commisionable: true
                                  refundable: false
                              cancellationPolicies:
                                - >-
                                  Free cancellation up to 48 hours before
                                  check-in
                                - 50% refund between 48-24 hours before check-in
                            - unitName: Executive Suite
                              numberOfBedrooms: 3
                              numberOfBathrooms: 2
                              maxOccupancy: 6
                              unitSize: 120
                              images:
                                - url: >-
                                    https://images.example.com/property/executive-suite-living.jpg
                                  caption: Executive Suite living area
                                  ordering: 1
                                  default: true
                                - url: >-
                                    https://images.example.com/property/executive-suite-bedroom.jpg
                                  caption: Executive Suite master bedroom
                                  ordering: 2
                                  default: false
                              priceBreakdown:
                                currency: GBP
                                wholeStay:
                                  excludingTax: 3500
                                  includingTax: 4200
                                  taxAmount: 700
                                perPeriod:
                                  period: NIGHTLY
                                  amountsExcludingAdditionalCharges:
                                    excludingTaxWithBookingFee: 700
                                    includingTaxWithBookingFee: 840
                              availability:
                                from: '2024-08-15'
                                to: '2024-08-20'
                                nights: 5
                              additionalCharges:
                                - summary: Cleaning fee (per stay)
                                  grossCost: 60
                                  chargeFormat:
                                    chargeFormatType: SPECIFIED_RATE
                                    rate: 60
                                  vat:
                                    vatApplicability: INCLUDED
                                    rate: null
                                  chargeFrequency: ONE_OFF
                                  chargedPerGuest: false
                                  commisionable: true
                                  refundable: false
                              cancellationPolicies:
                                - >-
                                  Free cancellation up to 48 hours before
                                  check-in
                                - No refund within 24 hours of check-in
                pagination:
                  next: >-
                    /external-api/v1/quotes?cursor=NWZhNGJlMTEtZjZhYy00YmEzLTlhZmItNjRjNTJjOTQyMGJhfDIwMjQtMDctMDFUMTU6NDU6MDBafE5leHQ=&pageSize=10&order=DESCENDING&sort=createdAt
                  previous: null
          description: Paginated list of quotes.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: >-
                  The requested quote was not found, please ensure you are using
                  the correct Xenia external ID.
                instance: id
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The quote was not found. This may be because the ID provided is
            invalid. The provided error status will be `RESOURCE_NOT_FOUND`.
        '500':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Get a paginated list of quotes
      tags:
        - quotes
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/sandbox/enquiries/{id}/change-state:
    post:
      description: >-
        Change the state of an enquiry in the sandbox environment, triggering
        its relevant event as well. You cannot go back to a previous state. If
        you specify `QUOTED` then it will trigger all eligible states before it,
        so in this example it would be `SHORTLISTING` and then finally `QUOTED`.
        Some states will be exceptions such as `CLOSED` which can happen in any
        of the previous states. This is not available in production.
      operationId: changeEnquiryState
      parameters:
        - description: Can be either the enquiries `xeniaReference` or `externalId`.
          example: R4E2F3A4
          in: path
          name: id
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            example:
              enquiryState: CLOSED
            schema:
              $ref: '#/components/schemas/sandboxEnquiryChangeStateRequest'
        required: true
      responses:
        '204':
          description: Successfully triggered
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: >-
                  The requested enquiry was not found, please ensure you are
                  using the correct Xenia reference or your own external ID.
                instance: id
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The enquiry was not found. This may be because the enquiry has been
            deleted or the ID provided is invalid. The provided error status
            will be `RESOURCE_NOT_FOUND`.
      summary: Change Enquiry State
      tags:
        - sandbox
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/sandbox/enquiries/{id}/trigger-webhook-event:
    post:
      description: >-
        Trigger a webhook event for an enquiry in the sandbox environment. This
        is not available in production.
      operationId: triggerEnquiryWebhookEvent
      parameters:
        - description: Can be either the enquiries `xeniaReference` or `externalId`.
          example: R4E2F3A4
          in: path
          name: id
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            example:
              eventType: ENQUIRY.CREATED
            schema:
              $ref: '#/components/schemas/sandboxEnquiryTriggerWebhookEventRequest'
        required: true
      responses:
        '204':
          description: Successfully changed state
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: >-
                  The requested enquiry was not found, please ensure you are
                  using the correct Xenia reference or your own external ID.
                instance: id
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The enquiry was not found. This may be because the enquiry has been
            deleted or the ID provided is invalid. The provided error status
            will be `RESOURCE_NOT_FOUND`.
      summary: Trigger Enquiry Webhook Event
      tags:
        - sandbox
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/webhooks:
    get:
      description: Get all webhooks for the current environment.
      operationId: listWebhooks
      responses:
        '200':
          content:
            application/json:
              example:
                data:
                  - description: Webhook for new enquiries
                    events:
                      - ENQUIRY.CREATED
                      - ENQUIRY.SHORTLISTING
                      - ENQUIRY.CLOSED
                    id: 123e4567-e89b-12d3-a456-426614174000
                    url: https://example.com/lifecycle-webhook
                  - description: Webhook for assigned specialists
                    events:
                      - ENQUIRY.SPECIALIST_ASSIGNED
                    id: 123e4567-e89b-12d3-a456-426614174001
                    url: https://example.com/assigned-specialists-webhook
              schema:
                $ref: '#/components/schemas/webhooksResponse'
          description: A list of webhooks.
        '400':
          content:
            application/problem+json:
              example:
                detail: The request was malformed.
                status: 400
                title: Malformed Request
                type: MALFORMED_REQUEST
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: The request was malformed, e.g. invalid query parameters.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '500':
          content:
            application/problem+json:
              example:
                detail: An error occurred on the server.
                status: 500
                title: Internal Server Error
                type: INTERNAL_SERVER_ERROR
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Get all webhooks
      tags:
        - webhooks
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
    post:
      description: Create a new webhook for Xenia to send events to.
      operationId: createWebhook
      requestBody:
        content:
          application/json:
            example:
              description: Webhook for new enquiries
              events:
                - ENQUIRY.CREATED
                - ENQUIRY.CLOSED
              url: https://example.com/webhook
            schema:
              $ref: '#/components/schemas/createOrUpdateWebhookRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              example:
                data:
                  description: Webhook for new enquiries
                  events:
                    - ENQUIRY.CREATED
                    - ENQUIRY.CLOSED
                  id: 123e4567-e89b-12d3-a456-426614174000
                  url: https://example.com/webhook
              schema:
                $ref: '#/components/schemas/webhookResponse'
          description: The created webhook object.
        '400':
          content:
            application/problem+json:
              example:
                detail: URL is invalid
                instance: /data/url
                status: 400
                title: Validation Error
                type: VALIDATION_ERROR
              schema:
                $ref: '#/components/schemas/validationProblemDetails'
          description: >-
            Validation errors have occurred, e.g. missing required fields or
            invalid data types.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '500':
          content:
            application/problem+json:
              example:
                detail: An error occurred on the server.
                status: 500
                title: Internal Server Error
                type: INTERNAL_SERVER_ERROR
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Create a new webhook
      tags:
        - webhooks
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/webhooks/{id}:
    delete:
      description: Delete a webhook by ID.
      operationId: deleteWebhook
      parameters:
        - description: The ID of the webhook.
          example: 123e4567-e89b-12d3-a456-426614174000
          in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      responses:
        '204':
          description: No content, the webhook was successfully deleted.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: The webhook was not found.
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The webhook was not found. This may be because the webhook has been
            deleted or the ID provided is invalid. The provided error status
            will be `RESOURCE_NOT_FOUND`.
        '500':
          content:
            application/problem+json:
              example:
                detail: An error occurred on the server.
                status: 500
                title: Internal Server Error
                type: INTERNAL_SERVER_ERROR
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Delete a webhook
      tags:
        - webhooks
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
    get:
      description: Get a webhook by ID.
      operationId: getWebhook
      parameters:
        - description: The ID of the webhook.
          example: 123e4567-e89b-12d3-a456-426614174000
          in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      responses:
        '200':
          content:
            application/json:
              example:
                data:
                  description: Webhook for new enquiries
                  events:
                    - ENQUIRY.CREATED
                    - ENQUIRY.CLOSED
                  id: 123e4567-e89b-12d3-a456-426614174000
                  url: https://example.com/webhook
              schema:
                $ref: '#/components/schemas/webhookResponse'
          description: The webhook object.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: The webhook was not found.
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The webhook was not found. This may be because the webhook has been
            deleted or the ID provided is invalid. The provided error status
            will be `RESOURCE_NOT_FOUND`.
        '500':
          content:
            application/problem+json:
              example:
                detail: An error occurred on the server.
                status: 500
                title: Internal Server Error
                type: INTERNAL_SERVER_ERROR
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Get a webhook
      tags:
        - webhooks
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
    put:
      description: Update an existing webhook.
      operationId: updateWebhook
      parameters:
        - description: The ID of the webhook.
          example: 123e4567-e89b-12d3-a456-426614174000
          in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      requestBody:
        content:
          application/json:
            example:
              description: Webhook for new enquiries
              events:
                - ENQUIRY.CREATED
                - ENQUIRY.CLOSED
              url: https://example.com/webhook
            schema:
              $ref: '#/components/schemas/createOrUpdateWebhookRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              example:
                data:
                  description: Webhook for new enquiries
                  events:
                    - ENQUIRY.CREATED
                    - ENQUIRY.CLOSED
                  id: 123e4567-e89b-12d3-a456-426614174000
                  url: https://example.com/webhook
              schema:
                $ref: '#/components/schemas/webhookResponse'
          description: The updated webhook object.
        '400':
          content:
            application/problem+json:
              example:
                detail: Validation errors occurred within the request body
                errors:
                  url:
                    - The URL must be a valid URI.
                status: 400
                title: Validation Error
                type: VALIDATION_ERROR
              schema:
                $ref: '#/components/schemas/validationProblemDetails'
          description: >-
            Validation errors have occurred, e.g. missing required fields or
            invalid data types.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '404':
          content:
            application/problem+json:
              example:
                detail: The webhook was not found.
                status: 404
                title: Resource Not Found
                type: RESOURCE_NOT_FOUND
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            The webhook was not found. This may be because the webhook has been
            deleted or the ID provided is invalid. The provided error status
            will be `RESOURCE_NOT_FOUND`.
        '500':
          content:
            application/problem+json:
              example:
                detail: An error occurred on the server.
                status: 500
                title: Internal Server Error
                type: INTERNAL_SERVER_ERROR
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Update a webhook
      tags:
        - webhooks
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
  /external-api/v1/webhook-verification-key:
    get:
      description: >-
        Get the public key used to verify webhook signatures. Use this key to
        verify that webhook payloads are authentically from Situ by validating
        the X-Signature header against the webhook body using HMAC-SHA256.
      operationId: getWebhookPublicKey
      responses:
        '200':
          content:
            application/json:
              example:
                data:
                  publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1234...
                  algorithm: HMAC-SHA256
                  keyFormat: base64
              schema:
                $ref: '#/components/schemas/webhookPublicKeyResponse'
          description: The public key for webhook signature verification.
        '401':
          description: >-
            Failed to authenticate the request. This may be because the token is
            invalid or expired.
        '403':
          description: >-
            Failed to authorize the request. This may be because you not have
            the required permissions.
        '500':
          content:
            application/problem+json:
              example:
                detail: An error occurred on the server.
                status: 500
                title: Internal Server Error
                type: INTERNAL_SERVER_ERROR
              schema:
                $ref: '#/components/schemas/problemDetails'
          description: >-
            An error occurred on the server, you may be able to find more detail
            inside the error object.
      summary: Get webhook signature verification public key
      tags:
        - webhooks
      x-allowed-roles:
        - Xenia.ExternalApi.Client
      security:
        - apiKey: []
x-webhooks:
  booking-pending-event:
    post:
      summary: Booking Pending
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        booking is pending confirmation.
      operationId: webhookBookingPendingEvent
      security: []
      tags:
        - bookings
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/bookingWebhookPayload'
            example:
              eventType: BOOKING.PENDING
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-02T10:30:15Z'
              data:
                bookingReference: R4E2F3A4
                createdAt: '2026-01-03T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  booking-partner-confirmation-details-sent-event:
    post:
      summary: Booking Confirmation Details sent to Partner
      description: >-
        This event payload is sent to the eligible registered webhooks when the
        booking confirmation details email is sent to the partner.
      operationId: webhookBookingConfirmationDetailsSentToPartnerEvent
      security: []
      tags:
        - bookings
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/bookingWebhookPayload'
            example:
              eventType: BOOKING.PARTNER_CONFIRMATION_DETAILS_SENT
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-02T11:45:30Z'
              data:
                bookingReference: R4E2F3A4
                createdAt: '2026-01-03T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  booking-client-confirmation-details-sent-event:
    post:
      summary: Booking Confirmation Details sent to Client
      description: >-
        This event payload is sent to the eligible registered webhooks when the
        booking confirmation details email is sent to the client.
      operationId: webhookBookingConfirmationDetailsSentToClientEvent
      security: []
      tags:
        - bookings
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/bookingWebhookPayload'
            example:
              eventType: BOOKING.CLIENT_CONFIRMATION_DETAILS_SENT
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-02T11:45:30Z'
              data:
                bookingReference: R4E2F3A4
                createdAt: '2026-01-03T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  booking-check-in-details-sent-event:
    post:
      summary: Booking Check-In Details Sent
      description: >-
        This event payload is sent to the eligible registered webhooks when
        check-in details are sent for a booking.
      operationId: webhookBookingCheckInDetailsSentEvent
      security: []
      tags:
        - bookings
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/bookingWebhookPayload'
            example:
              eventType: BOOKING.CHECK_IN_DETAILS_SENT
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-15T09:00:00Z'
              data:
                bookingReference: R4E2F3A4
                createdAt: '2026-01-03T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  booking-cancelled-event:
    post:
      summary: Booking Cancelled
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        booking is cancelled.
      operationId: webhookBookingCancelledEvent
      security: []
      tags:
        - bookings
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/bookingWebhookPayload'
            example:
              eventType: BOOKING.CANCELLED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-03T14:20:00Z'
              data:
                bookingReference: R4E2F3A4
                createdAt: '2026-01-03T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  enquiry-created-event:
    post:
      summary: Enquiry Created
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        new enquiry is created.
      operationId: webhookEnquiryCreatedEvent
      security: []
      tags:
        - enquiries
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/enquiryWebhookPayload'
            example:
              eventType: ENQUIRY.CREATED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T15:12:56Z'
              data:
                externalId: e234abcef
                clientReference: example-ref-567abc
                xeniaReference: R4E2F3A4
                createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  enquiry-shortlisting-event:
    post:
      summary: Enquiry Shortlisting
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        specialist starts shortlisting properties for an enquiry.
      operationId: webhookEnquiryShortlistingEvent
      security: []
      tags:
        - enquiries
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/enquiryWebhookPayload'
            example:
              eventType: ENQUIRY.SHORTLISTING
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T15:34:30Z'
              data:
                externalId: e234abcef
                clientReference: example-ref-567abc
                xeniaReference: R4E2F3A4
                createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  enquiry-specialist-assigned-event:
    post:
      summary: Enquiry Specialist Assigned
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        specialist is assigned to an enquiry.
      operationId: webhookEnquirySpecialistAssignedEvent
      security: []
      tags:
        - enquiries
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/enquiryWebhookPayload'
            example:
              eventType: ENQUIRY.SPECIALIST_ASSIGNED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T15:23:00Z'
              data:
                externalId: e234abcef
                clientReference: example-ref-567abc
                xeniaReference: R4E2F3A4
                createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  enquiry-quoted-event:
    post:
      summary: Enquiry Quoted
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        quote is sent for an enquiry.
      operationId: webhookEnquiryQuotedEvent
      security: []
      tags:
        - enquiries
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/enquiryWebhookPayload'
            example:
              eventType: ENQUIRY.QUOTED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T16:15:22Z'
              data:
                externalId: e234abcef
                clientReference: example-ref-567abc
                xeniaReference: R4E2F3A4
                createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  enquiry-closed-event:
    post:
      summary: Enquiry Closed
      description: >-
        This event payload is sent to the eligible registered webhooks when an
        enquiry is closed.
      operationId: webhookEnquiryClosedEvent
      security: []
      tags:
        - enquiries
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/enquiryWebhookPayload'
            example:
              eventType: ENQUIRY.CLOSED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T17:23:41Z'
              data:
                externalId: e234abcef
                clientReference: example-ref-567abc
                xeniaReference: R4E2F3A4
                createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  enquiry-reopened-event:
    post:
      summary: Enquiry Reopened
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        closed enquiry is reopened.
      operationId: webhookEnquiryReopenedEvent
      security: []
      tags:
        - enquiries
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/enquiryWebhookPayload'
            example:
              eventType: ENQUIRY.REOPENED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T18:45:12Z'
              data:
                externalId: e234abcef
                clientReference: example-ref-567abc
                xeniaReference: R4E2F3A4
                createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  quote-created-event:
    post:
      summary: Quote Created
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        new quote is created.
      operationId: webhookQuoteCreatedEvent
      security: []
      tags:
        - quotes
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/quoteWebhookPayload'
            example:
              eventType: QUOTE.CREATED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T15:12:56Z'
              data:
                externalId: QT-2024-005678
                invalidatedAt: null
                createdAt: '2026-01-01T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
  quote-invalidated-event:
    post:
      summary: Quote Invalidated
      description: >-
        This event payload is sent to the eligible registered webhooks when a
        quote is invalidated.
      operationId: webhookQuoteInvalidatedEvent
      security: []
      tags:
        - quotes
      parameters:
        - name: X-Signature
          in: header
          required: true
          description: >-
            HMAC-SHA256 signature of the request body using the webhook secret
            key. Use this to verify the authenticity of the webhook payload.
          schema:
            type: string
            example: dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU=
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/quoteWebhookPayload'
            example:
              eventType: QUOTE.INVALIDATED
              eventId: 123e4567-e89b-12d3-a456-426614174000
              createdAt: '2026-01-01T16:45:30Z'
              data:
                externalId: QT-2024-005678
                invalidatedAt: '2026-01-01T16:45:30Z'
                createdAt: '2026-01-01T15:10:13Z'
                enquiry:
                  externalId: e234abcef
                  clientReference: example-ref-567abc
                  xeniaReference: R4E2F3A4
                  createdAt: '2026-01-01T15:10:13Z'
      responses:
        '204':
          description: >-
            The webhook was successfully received, Xenia will not try to process
            this again.
        '400':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '500':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
        '503':
          description: >-
            The webhook was not received successfully, Xenia will retry this
            webhook up to 5 times.
components:
  schemas:
    bookingReferenceId:
      type: string
      description: Xenia's reference for the booking.
      example: R4E2F3A4
    bookingWebhookPayload:
      type: object
      description: >-
        The event payload sent to the specified webhook URL. You are expected to
        pull the full object from the relevant endpoint.
      properties:
        eventType:
          $ref: '#/components/schemas/webhookEvent'
        eventId:
          type: string
          format: uuid
          description: Unique ID of the event. This can be used as the idempotent key.
          example: 123e4567-e89b-12d3-a456-426614174000
        createdAt:
          type: string
          format: date-time
          description: When the event was created within Xenia's system.
          example: '2026-01-01T15:12:56Z'
        data:
          $ref: '#/components/schemas/bookingWebhookEventData'
    bookingWebhookEventData:
      type: object
      description: The data object for a booking event.
      properties:
        bookingReference:
          $ref: '#/components/schemas/bookingReferenceId'
        createdAt:
          $ref: '#/components/schemas/utcTimestamp'
        enquiry:
          $ref: '#/components/schemas/enquiryWebhookEventData'
      required:
        - bookingReference
        - createdAt
        - enquiry
    webhookEvent:
      description: Supported webhook events.
      enum:
        - ENQUIRY.CREATED
        - ENQUIRY.SPECIALIST_ASSIGNED
        - ENQUIRY.SHORTLISTING
        - ENQUIRY.CLOSED
        - ENQUIRY.REOPENED
        - ENQUIRY.QUOTED
        - QUOTE.CREATED
        - QUOTE.INVALIDATED
        - BOOKING.PENDING
        - BOOKING.CLIENT_CONFIRMATION_DETAILS_SENT
        - BOOKING.PARTNER_CONFIRMATION_DETAILS_SENT
        - BOOKING.CHECK_IN_DETAILS_SENT
        - BOOKING.CANCELLED
      example: ENQUIRY.CREATED
      type: string
    utcTimestamp:
      description: ISO-8601 UTC timestamp. The example is the expected format.
      example: '2026-01-01T15:12:56Z'
      format: date-time
      type: string
    enquiryExternalId:
      description: >-
        The external ID of the enquiry, this is a unique value that can be used
        to retrieve your enquiry via other endpoints where specified.
      example: e234abcef
      maxLength: 255
      minLength: 3
      type: string
    enquiryClientReferenceId:
      description: >-
        The clients reference for the enquiry. This may be the same as the
        external ID depending on your system.
      example: example-ref-567abc
      maxLength: 255
      minLength: 3
      type: string
    enquiryXeniaReferenceId:
      description: Xenia's reference for the enquiry.
      example: R4E2F3A4
      type: string
    enquiryWebhookEventData:
      type: object
      description: The data object for an enquiry event.
      properties:
        externalId:
          $ref: '#/components/schemas/enquiryExternalId'
        clientReference:
          $ref: '#/components/schemas/enquiryClientReferenceId'
        xeniaReference:
          $ref: '#/components/schemas/enquiryXeniaReferenceId'
        createdAt:
          $ref: '#/components/schemas/utcTimestamp'
      required:
        - externalId
        - clientReference
        - xeniaReference
        - createdAt
    enquiryStateClosureReason:
      description: >-
        The reason for the enquiry closure. This is not always available and may
        be null.
      enum:
        - PRICE
        - AVAILABILITY
        - NO_CLIENT_RESPONSE
        - STAY_CANCELLED_OR_POSTPONED
        - BOOKED_ELSEWHERE_COMPETITOR
        - BOOKED_ELSEWHERE_DIFFERENT_PRODUCT
        - DUPLICATE
        - NOT_AN_ENQUIRY
        - STAY_DOES_NOT_MEET_SITU_CRITERIA
        - OTHER
      example: STAY_CANCELLED_OR_POSTPONED
      nullable: true
      type: string
    problemDetails:
      additionalProperties: true
      description: A machine-readable format for specifying errors in HTTP APIs (RFC 7807).
      properties:
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          example: The request could not be understood due to malformed syntax.
          type: string
        instance:
          description: >-
            A URI reference or identifier that describes the specific occurrence
            of the problem.
          example: /api/v1/enquiries/abc
          type: string
        status:
          description: The HTTP status code.
          example: 400
          format: int32
          type: integer
        title:
          description: A short, human-readable summary of the problem type.
          example: Bad Request
          type: string
        type:
          $ref: '#/components/schemas/problemDetailsType'
      required:
        - type
        - title
        - status
      type: object
    problemDetailsType:
      description: The error code as a machine-readable key.
      enum:
        - RESOURCE_NOT_FOUND
        - VALIDATION_ERROR
        - RESOURCE_ALREADY_EXISTS
        - DUPLICATE_CLIENT_REFERENCE
        - GEOCODE_FAILURE
        - MALFORMED_REQUEST
        - INTERNAL_SERVER_ERROR
        - MAX_RESOURCE_COUNT_REACHED
        - SANDBOX_SPECIFIC_ACTION_ERROR
      example: GEOCODE_FAILURE
      type: string
    clientBooker:
      description: Details of the Booker for the enquiry or booking.
      minProperties: 1
      properties:
        contactNumber:
          description: Booker contact number
          example: '+447911992499'
          format: phoneNumber
          maxLength: 50
          nullable: true
          type: string
        email:
          description: Booker email
          example: Jess.Walters@example.com
          maxLength: 200
          pattern: ^[^@;\s]+@[^@.;\s]+(?:\.\w+){1,2}$
          type: string
        familyName:
          description: Booker family name
          example: Walters
          maxLength: 50
          type: string
        givenName:
          description: Booker given name
          example: Jess
          maxLength: 50
          type: string
      required:
        - givenName
        - familyName
        - email
        - contactNumber
      type: object
    errorResponse:
      $ref: '#/components/schemas/problemDetails'
    resourceNotFoundResponse:
      $ref: '#/components/schemas/problemDetails'
    serverErrorResponse:
      $ref: '#/components/schemas/problemDetails'
    badRequestResponse:
      $ref: '#/components/schemas/problemDetails'
    validationErrors:
      additionalProperties:
        items:
          type: string
        type: array
      description: A dictionary containing field-specific validation errors.
      example:
        clientReference:
          - Client reference must be at least 3 characters.
        id:
          - The ID field is required.
      type: object
    validationErrorsResponse:
      $ref: '#/components/schemas/validationProblemDetails'
    validationProblemDetails:
      additionalProperties: true
      description: >-
        A validation error response that extends ProblemDetails with field-level
        errors.
      properties:
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          example: Validation failed for one or more fields.
          type: string
        errors:
          $ref: '#/components/schemas/validationErrors'
        instance:
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          example: /api/v1/enquiries
          type: string
        status:
          description: The HTTP status code.
          example: 400
          format: int32
          type: integer
        title:
          description: A short, human-readable summary of the problem type.
          example: One or more validation errors occurred.
          type: string
        type:
          $ref: '#/components/schemas/problemDetailsType'
      type: object
    pagination:
      description: Pagination navigation details
      properties:
        next:
          description: Link to next page of results
          example: >-
            /v1/enquiries?cursor=MmFhZjkwMjktOWFhYS00OGM0LWFlNDgtZWI1ZDliMWIzOTEyfDIwMjUtMDctMDlUMTQ6MDU6MzYuNzQ0MTUzMCswMDowMA==&isBackwards=false&pageSize=10
          nullable: true
          type: string
        previous:
          description: Link to previous page of results
          example: >-
            /v1/enquiries?cursor=MmFhZjkwMjktOWFhYS00OGM0LWFlNDgtZWI1ZDliMWIzOTEyfDIwMjUtMDctMDlUMTQ6MDU6MzYuNzQ0MTUzMCswMDowMA==&isBackwards=true&pageSize=10
          nullable: true
          type: string
      type: object
    coordinates:
      description: Latitude/Longitude coordinates
      properties:
        latitude:
          description: Latitude of the location.
          example: 51.5074
          format: float
          type: number
        longitude:
          description: Longitude of the location.
          example: -0.1278
          format: float
          type: number
      required:
        - latitude
        - longitude
      type: object
    addressFormatted:
      description: >-
        The formatted address. If this is being used to create an enquiry, as
        much information as possible is desired for reverse-geocoding.
      example: 123 Testing Way, Testham, United Kingdom TE57 2DE
      maxLength: 255
      type: string
    assignedSpecialist:
      description: >-
        The assigned specialist for this resource. If this is `null` then no
        specialist has been assigned yet.
      nullable: true
      properties:
        name:
          description: The name of the user.
          example: Scott Aberdeigh
          type: string
      type: object
    checkInOut:
      description: >-
        The check-in and check-out dates for this enquiry. ISO-8601 date formats
        are accepted.
      properties:
        checkIn:
          example: '2026-02-03'
          format: date
          nullable: true
          type: string
        checkOut:
          example: '2026-03-10'
          format: date
          nullable: true
          type: string
          x-on-or-after: checkIn
      required:
        - checkIn
        - checkOut
      type: object
    createEnquiryLocation:
      description: >-
        There are several methods to provide us with a location. You may either
        provide us with the address, coordinates or Google `place_id`. If you
        provide an address, we will attempt to reverse geocode this to a
        latitude and longitude. If this fails we will return a HTTP 400 with the
        relevant error code.
      properties:
        addressFormatted:
          $ref: '#/components/schemas/addressFormatted'
        coordinates:
          $ref: '#/components/schemas/coordinates'
        googlePlaceId:
          $ref: '#/components/schemas/googlePlaceId'
      type: object
      x-one-of:
        - coordinates
        - googlePlaceId
        - addressFormatted
    createEnquiryRequest:
      properties:
        checkInOut:
          $ref: '#/components/schemas/checkInOut'
        clientReference:
          $ref: '#/components/schemas/enquiryClientReferenceId'
        enquiryLocation:
          $ref: '#/components/schemas/createEnquiryLocation'
        externalId:
          $ref: '#/components/schemas/enquiryExternalId'
        guestNumbers:
          $ref: '#/components/schemas/guestNumbers'
        guestRequirements:
          $ref: '#/components/schemas/enquiryGuestRequirements'
        leadGuest:
          $ref: '#/components/schemas/leadGuestDetails'
        clientBooker:
          $ref: '#/components/schemas/clientBooker'
      required:
        - externalId
        - clientReference
        - enquiryLocation
        - checkInOut
        - guestNumbers
        - leadGuest
        - clientBooker
      type: object
    enquiry:
      properties:
        xeniaReference:
          $ref: '#/components/schemas/enquiryXeniaReferenceId'
        clientReference:
          $ref: '#/components/schemas/enquiryClientReferenceId'
        assignedSpecialist:
          $ref: '#/components/schemas/assignedSpecialist'
        checkInOut:
          $ref: '#/components/schemas/checkInOut'
        enquiryLocation:
          $ref: '#/components/schemas/enquiryLocation'
        enquiryState:
          $ref: '#/components/schemas/enquiryState'
        externalId:
          $ref: '#/components/schemas/enquiryExternalId'
        guestNumbers:
          $ref: '#/components/schemas/guestNumbers'
        guestRequirements:
          $ref: '#/components/schemas/enquiryGuestRequirements'
        leadGuest:
          $ref: '#/components/schemas/leadGuestDetails'
        clientBooker:
          $ref: '#/components/schemas/clientBooker'
        createdAt:
          $ref: '#/components/schemas/utcTimestamp'
      required:
        - externalId
        - clientReference
        - xeniaReference
        - enquiryState
        - enquiryLocation
        - checkInOut
        - guestNumbers
        - leadGuest
        - clientBooker
        - guestRequirements
        - assignedSpecialist
        - createdAt
      type: object
    enquiryAddress:
      description: The enquiries location.
      properties:
        country:
          description: The country of the location.
          example: United Kingdom
          maxLength: 280
          nullable: true
          type: string
        locality:
          description: The area, neighbourhood or city of the location.
          example: Hackney
          maxLength: 280
          nullable: true
          type: string
        postalCode:
          description: The postcode of the location.
          example: BS11 1DJ
          maxLength: 280
          nullable: true
          type: string
        region:
          description: The region of the location.
          example: Somerset
          maxLength: 280
          nullable: true
          type: string
        streetAddress:
          description: Street address of the location.
          example: 123 fake street
          maxLength: 280
          nullable: true
          type: string
      type: object
    enquiryGuestRequirements:
      description: The guest requirements for the enquiry.
      items:
        $ref: '#/components/schemas/enquiryGuestRequirementsItem'
      type: array
    enquiryGuestRequirementsItem:
      description: A set of classified requirements for the enquiry.
      properties:
        text:
          description: The requirements in text format for the chosen type.
          example: >-
            Security guard mandatory in lobby, double locks required on
            apartment door
          maxLength: 10000
          minLength: 3
          type: string
        type:
          $ref: '#/components/schemas/enquiryGuestRequirementsType'
      required:
        - type
        - text
      type: object
    enquiryGuestRequirementsType:
      enum:
        - GENERAL
      example: GENERAL
      description: >-
        The type of guest requirement. For now only `GENERAL` is supported, but
        more specific types will be added in the future.
      type: string
    enquiryLocation:
      properties:
        address:
          $ref: '#/components/schemas/enquiryAddress'
        coordinates:
          $ref: '#/components/schemas/coordinates'
        googlePlaceId:
          $ref: '#/components/schemas/googlePlaceId'
      required:
        - coordinates
        - googlePlaceId
        - address
      type: object
    enquiryResponse:
      description: >-
        The enquiry response, with the enquiry contained within the `data`
        object to preserve the root namespace for future API additions.
      properties:
        data:
          $ref: '#/components/schemas/enquiry'
      required:
        - data
      type: object
    enquiryState:
      description: >-
        Metadata about the enquiry state. This is not always available and may
        be null.
      nullable: true
      properties:
        closureReason:
          $ref: '#/components/schemas/enquiryStateClosureReason'
        state:
          $ref: '#/components/schemas/enquiryStateValue'
      type: object
    enquiryStateValue:
      description: >-
        This is a machine-readable key that can be used to identify the state of
        the enquiry.
      enum:
        - NEW
        - SHORTLISTING
        - QUOTED
        - CLOSED
        - BOOKING_PENDING
        - BOOKING_CONFIRMED
        - BOOKING_CHECK_IN_DETAILS_SENT
        - BOOKING_CANCELLED
      example: CLOSED
      type: string
    googlePlaceId:
      description: The Google Place ID of the location.
      example: ChIJN1t_tDeuEmsRUcIaW_4C0gQ
      maxLength: 255
      type: string
    guestNumbers:
      description: The number of guests in each category.
      properties:
        adults:
          description: The amount of adults (18+ years).
          example: 2
          maximum: 99
          minimum: 1
          type: integer
        children:
          default: 0
          description: The amount of children (1 - 17 years).
          example: 3
          maximum: 99
          type: integer
        infants:
          default: 0
          description: The amount of infants (0 - 1 years).
          example: 1
          maximum: 99
          type: integer
      required:
        - adults
      type: object
    leadGuestDetails:
      description: Details of the lead guest.
      properties:
        contactNumber:
          description: >-
            Lead guest contact number. Must be a valid phone number format,
            including international formats with country codes. Valid characters
            are 0-9, +, -, (, ), and commas. No letters allowed.
          example: '07556677992'
          format: phoneNumber
          maxLength: 50
          nullable: true
          type: string
        email:
          description: >-
            Lead guest email. Must contain exactly one @ symbol, no spaces or
            semicolons, and end with a valid domain (e.g., .com or .co.uk).
          example: Sam.Smith@example.com
          maxLength: 200
          nullable: true
          pattern: ^[^@;\s]+@[^@.;\s]+(?:\.\w+){1,2}$
          type: string
        familyName:
          description: Lead guest family name (surname).
          example: Smith
          maxLength: 50
          nullable: true
          type: string
        givenName:
          description: Lead guest given name (first name).
          example: Sam
          maxLength: 50
          nullable: true
          type: string
      type: object
    enquiryWebhookPayload:
      type: object
      description: >-
        The event payload sent to the specified webhook URL. You are expected to
        pull the full object from the relevant endpoint.
      properties:
        eventType:
          $ref: '#/components/schemas/webhookEvent'
        eventId:
          type: string
          format: uuid
          description: Unique ID of the event. This can be used as the idempotent key.
          example: 123e4567-e89b-12d3-a456-426614174000
        createdAt:
          type: string
          format: date-time
          description: When the event was created within Xenia's system.
          example: '2026-01-01T15:12:56Z'
        data:
          $ref: '#/components/schemas/enquiryWebhookEventData'
    quotesResponse:
      description: Paginated quotes response.
      properties:
        data:
          description: Array of quotes.
          items:
            $ref: '#/components/schemas/quoteResponse'
          type: array
        pagination:
          $ref: '#/components/schemas/pagination'
      required:
        - data
        - pagination
      type: object
    quoteResponse:
      description: Quote details.
      properties:
        id:
          description: The unique identifier of the quote.
          example: QT-2024-005678
          type: string
        xeniaEnquiryReference:
          $ref: '#/components/schemas/enquiryXeniaReferenceId'
        clientEnquiryReference:
          description: The client's reference for the enquiry.
          type: string
          nullable: true
          example: CLIENT-REF-123
        createdAt:
          description: When the quote was created.
          example: '2024-07-01T14:30:00Z'
          format: date-time
          type: string
        updatedAt:
          description: When the quote was last updated.
          example: '2024-07-01T15:45:00Z'
          format: date-time
          type: string
        invalidatedAt:
          description: When the quote was invalidated.
          example: '2024-07-02T10:30:00Z'
          format: date-time
          type: string
          nullable: true
        state:
          $ref: '#/components/schemas/quoteState'
        description:
          type: string
          nullable: true
          description: >-
            The quote description. This is the same data if an email is also
            sent out.
          example: Quote for 3-night stay in London
        items:
          description: The quote items (properties and pricing).
          items:
            $ref: '#/components/schemas/quoteItem'
          type: array
        bookedQuoteItem:
          $ref: '#/components/schemas/bookedQuoteItem'
      required:
        - id
        - xeniaEnquiryReference
        - clientEnquiryReference
        - invalidatedAt
        - bookedQuoteItem
        - state
        - description
        - createdAt
        - updatedAt
        - items
      type: object
    quoteItem:
      description: Individual property option within a quote.
      properties:
        id:
          description: The unique id of the quote option item.
          example: 4e67c3eb-912a-4da2-91e9-dba4d8e2437e
          type: string
        property:
          $ref: '#/components/schemas/property'
        distanceFromEnquiryLocation:
          $ref: '#/components/schemas/distanceFromEnquiryLocation'
        booked:
          description: Indicates whether the quote item is booked.
          type: boolean
          example: false
      required:
        - id
        - property
      type: object
    additionalCharge:
      description: Formatted additional charge information.
      properties:
        summary:
          description: Charge details.
          example: Cleaning fee (per stay)
          type: string
        chargeFormat:
          $ref: '#/components/schemas/chargeFormat'
        vat:
          $ref: '#/components/schemas/vat'
        chargeFrequency:
          $ref: '#/components/schemas/chargeFrequency'
        chargedPerGuest:
          description: Whether the fee is charged per guest.
          type: boolean
          example: true
        commisionable:
          description: Whether the fee is commisionable.
          type: boolean
          example: true
        refundable:
          description: Whether the fee is refundable.
          type: boolean
          example: true
        grossCost:
          description: Formatted total cost including tax.
          example: 40
          type: number
          nullable: true
      required:
        - summary
        - grossCost
      type: object
    chargeFrequency:
      description: Indicates whether this is a percentage or absolute charge.
      type: string
      enum:
        - ONE_OFF
        - NIGHTLY
        - WEEKLY
        - MONTHLY
      example: ONE_OFF
    chargeFormat:
      type: object
      properties:
        chargeFormatType:
          $ref: '#/components/schemas/chargeFormatType'
        rate:
          description: The amount or percentage.
          type: number
          example: 10.5
          nullable: true
    chargeFormatType:
      description: Indicates whether this is a percentage or absolute charge.
      type: string
      enum:
        - PERCENTAGE_OF_NIGHTLY_RATE
        - SPECIFIED_RATE
      example: SPECIFIED_RATE
    vat:
      description: Indicates whether this is a percentage or absolute charge.
      type: object
      properties:
        vatApplicability:
          $ref: '#/components/schemas/vatApplicability'
        rate:
          description: >-
            The VAT rate percentage - only included if type is 'Included' or
            'Not Included'.
          type: number
          nullable: true
          example: 20
    vatApplicability:
      description: Indicates whether this is a percentage or absolute charge.
      type: string
      enum:
        - NOT_APPLICABLE
        - NOT_INCLUDED
        - INCLUDED
      example: INCLUDED
    availability:
      description: >-
        The availability window for a quote item. ISO-8601 date formats are
        used.
      nullable: true
      properties:
        from:
          description: Start date of availability.
          example: '2024-08-15'
          format: date
          type: string
        to:
          description: End date of availability.
          example: '2024-08-20'
          format: date
          type: string
        nights:
          description: Number of nights available.
          example: 5
          type: integer
      required:
        - from
        - to
        - nights
      type: object
    property:
      description: Property details for the quote item.
      type: object
      properties:
        propertyName:
          description: The name of the property.
          example: The Savoy Hotel
          type: string
        propertyUrl:
          description: Link to building.
          example: https://core.xenia.staysitu.com/properties/789
          format: uri
          type: string
          pattern: ^https:\/\/\S+$
        locationMapLink:
          description: Link to google maps.
          example: https://maps.app.goo.gl/ob21JeqFf6rdkLif7
          format: uri
          maxLength: 1000
          pattern: ^https:\/\/\S+$
          type: string
        overview:
          description: Overview of the property.
          example: A luxurious hotel in the heart of London
          nullable: true
          type: string
        coordinates:
          $ref: '#/components/schemas/coordinates'
        locationOverview:
          description: Overview of the property location.
          example: Located in Westminster, near major attractions
          nullable: true
          type: string
        additionalDetails:
          description: Additional details about the property.
          example: 24-hour concierge service, spa facilities
          nullable: true
          type: string
        termsOfStay:
          description: Terms and conditions for the stay.
          example: Check-in after 3 PM, check-out before 11 AM. No smoking.
          nullable: true
          type: string
        images:
          description: Array of property images.
          type: array
          items:
            $ref: '#/components/schemas/image'
        units:
          description: Array of unit details for the property.
          type: array
          items:
            $ref: '#/components/schemas/unit'
        address:
          $ref: '#/components/schemas/address'
        features:
          description: Array of property features.
          type: array
          items:
            $ref: '#/components/schemas/feature'
      required:
        - propertyName
        - propertyUrl
        - locationMapLink
    paginationOrder:
      description: >-
        Indicates the direction to travel from the cursor, or beginning or end
        if no cursor specified.
      type: string
      enum:
        - desc
        - asc
      example: desc
      default: desc
    quoteListSortField:
      description: Whether we're sorting by created or updated.
      type: string
      enum:
        - createdAt
        - updatedAt
      example: createdAt
      default: createdAt
    priceBreakdown:
      description: Price breakdown for the quote item.
      type: object
      properties:
        currency:
          description: The currency of the price breakdown.
          example: GBP
          type: string
        wholeStay:
          $ref: '#/components/schemas/wholeStayCost'
        perPeriod:
          $ref: '#/components/schemas/perPeriodCost'
      required:
        - currency
        - wholeStay
        - perPeriod
    wholeStayCost:
      description: The whole stay cost in the specified currency.
      type: object
      properties:
        excludingTax:
          description: The whole stay cost excluding tax.
          example: 2100
          type: number
          format: currency
        includingTax:
          description: The whole stay cost including tax.
          example: 2500
          type: number
          format: currency
        taxAmount:
          description: The tax amount applied to the whole stay cost.
          example: 400
          type: number
          format: currency
      required:
        - excludingTax
        - includingTax
        - taxAmount
    perPeriodCost:
      description: Per period cost breakdown.
      type: object
      properties:
        period:
          $ref: '#/components/schemas/pricingPeriod'
        amountsExcludingAdditionalCharges:
          $ref: '#/components/schemas/perPeriodAmounts'
      required:
        - period
        - amountsExcludingAdditionalCharges
    pricingPeriod:
      description: The pricing period type.
      type: string
      enum:
        - NIGHTLY
        - DAILY
      example: NIGHTLY
    perPeriodAmounts:
      description: Per period amounts excluding additional charges.
      type: object
      properties:
        excludingTaxWithBookingFee:
          description: >-
            Period cost excluding additional charges and tax, but including
            booking fees.
          example: 400
          type: number
          format: currency
        includingTaxWithBookingFee:
          description: >-
            Period cost including tax and booking fees, but excluding additional
            charges.
          example: 440
          type: number
          format: currency
      required:
        - excludingTaxWithBookingFee
        - includingTaxWithBookingFee
    image:
      description: Property image information.
      type: object
      properties:
        url:
          description: Full URL of the image.
          example: https://images.example.com/property/savoy-suite-main.jpg
          format: uri
          type: string
        caption:
          description: Caption or description of the image.
          example: Master bedroom with city view
          nullable: true
          type: string
        ordering:
          description: Display order of the image.
          example: 1
          type: integer
        default:
          description: Whether this is the default/primary image.
          example: true
          type: boolean
      required:
        - url
        - ordering
        - default
    unit:
      description: Unit details within a property.
      type: object
      properties:
        unitName:
          description: The name of the unit.
          example: Deluxe Suite
          type: string
        numberOfBedrooms:
          description: Number of bedrooms in the unit.
          example: 2
          type: integer
        numberOfBathrooms:
          description: Number of bathrooms in the unit.
          example: 1
          type: integer
        maxOccupancy:
          description: Maximum occupancy for the unit.
          example: 4
          type: integer
        unitSize:
          description: Size of the unit in square meters.
          example: 85.5
          type: number
        images:
          description: Array of property images.
          type: array
          items:
            $ref: '#/components/schemas/image'
        features:
          description: Array of unit features.
          type: array
          items:
            $ref: '#/components/schemas/feature'
        priceBreakdown:
          $ref: '#/components/schemas/priceBreakdown'
        availability:
          $ref: '#/components/schemas/availability'
        additionalCharges:
          description: Additional charges.
          items:
            $ref: '#/components/schemas/additionalCharge'
          type: array
        cancellationPolicies:
          description: Array of cancellation policy texts.
          type: array
          items:
            type: string
          example:
            - Free cancellation up to 48 hours before check-in
            - 50% refund between 48-24 hours before check-in
            - No refund within 24 hours of check-in
        notes:
          description: Client facing notes made by accommodation specialist.
          example: Special amenities included
          type: string
      required:
        - unitName
        - numberOfBedrooms
        - numberOfBathrooms
        - maxOccupancy
        - unitSize
    address:
      description: Address information.
      type: object
      properties:
        line1:
          description: First line of the address.
          example: 123 Main Street
          type: string
        line2:
          description: Second line of the address.
          example: Apartment 4B
          nullable: true
          type: string
        townCity:
          description: Town or city.
          example: London
          type: string
        region:
          description: Region or state.
          example: Greater London
          nullable: true
          type: string
        countryCode:
          description: ISO 3166-1 alpha-2 country code.
          example: GB
          type: string
        country:
          description: Country name.
          example: United Kingdom
          type: string
        postcode:
          description: Postal code.
          example: SW1A 1AA
          nullable: true
          type: string
      required:
        - line1
        - townCity
        - countryCode
        - country
    feature:
      description: Property or unit feature.
      type: object
      properties:
        key:
          description: Feature identifier key.
          example: FACILITIES_INTERNET_SUPER_FAST_WIFI
          type: string
        description:
          description: Human-readable feature description.
          example: Internet Connection - Superfast Wi-Fi
          type: string
        category:
          description: Feature category.
          example: Facilities
          type: string
        subCategory:
          description: Feature sub-category.
          example: Internet
          type: string
        availability:
          $ref: '#/components/schemas/featureAvailability'
        measurableUnitValue:
          description: Value for measurable features (e.g., speed, size)
          example: 100 Mbps
          nullable: true
          type: string
      required:
        - key
        - description
        - category
        - subCategory
        - availability
    featureAvailability:
      description: Availability status of the feature.
      type: string
      enum:
        - IMPLICIT
        - SUPPLIED
        - ON_REQUEST
        - CONSIDERED
        - NOT_AVAILABLE
      example: IMPLICIT
    enquiryExternalIdFilter:
      description: >-
        The external ID of the enquiry, this is a unique value that can be used
        to retrieve your enquiry via other endpoints where specified.
      example: e234abcef
      maxLength: 255
      minLength: 3
      type: string
      nullable: true
      default: 'null'
    quoteState:
      description: >-
        The current state of the quote. An active quote can be booked, an
        invalidated quote cannot be booked. If a new quote is sent out, all
        existing quotes will become invalidated.
      type: string
      enum:
        - ACTIVE
        - INVALIDATED
      example: ACTIVE
    quoteWebhookPayload:
      type: object
      description: >-
        The event payload sent to the specified webhook URL. You are expected to
        pull the full object from the relevant endpoint.
      properties:
        eventType:
          $ref: '#/components/schemas/webhookEvent'
        eventId:
          type: string
          format: uuid
          description: Unique ID of the event. This can be used as the idempotent key.
          example: 123e4567-e89b-12d3-a456-426614174000
        createdAt:
          type: string
          format: date-time
          description: When the event was created within Xenia's system.
          example: '2026-01-01T15:12:56Z'
        data:
          $ref: '#/components/schemas/quoteWebhookEventData'
    quoteWebhookEventData:
      type: object
      description: The data object for a booking event.
      properties:
        externalId:
          description: The unique identifier of the quote.
          example: QT-2024-005678
          type: string
        createdAt:
          $ref: '#/components/schemas/utcTimestamp'
        invalidatedAt:
          type: string
          format: date-time
          description: When the quote was invalidated.
          example: '2026-01-01T16:45:30Z'
          nullable: true
        enquiry:
          $ref: '#/components/schemas/enquiryWebhookEventData'
      required:
        - externalId
        - createdAt
        - enquiry
        - invalidatedAt
    distanceFromEnquiryLocation:
      description: Distance information from the search location.
      type: object
      nullable: true
      properties:
        value:
          description: The distance value.
          type: number
          format: decimal
          example: 12.5
        unit:
          $ref: '#/components/schemas/distanceUnit'
      required:
        - value
        - unit
    distanceUnit:
      description: The unit of measurement for distance.
      type: string
      enum:
        - KILOMETERS
      example: KILOMETERS
    bookedQuoteItem:
      description: >-
        Information about the quote item that selected for booking. Null if
        booking is not yet confirmed.
      type: object
      nullable: true
      properties:
        bookingId:
          description: The unique identifier of the booking.
          type: string
          example: BK-2024-123456
        quoteItemId:
          description: The unique identifier of the quote item that was booked.
          type: string
          example: 4e67c3eb-912a-4da2-91e9-dba4d8e2437e
        createdAt:
          description: When the booking was created.
          type: string
          format: date-time
          example: '2024-07-02T09:30:00Z'
      required:
        - bookingId
        - quoteItemId
        - createdAt
    sandboxEnquiryChangeStateRequest:
      properties:
        closureReason:
          $ref: '#/components/schemas/enquiryStateClosureReason'
        enquiryState:
          $ref: '#/components/schemas/sandboxEnquiryStateValueUpdate'
      required:
        - enquiryState
      type: object
    sandboxEnquiryStateValueUpdate:
      description: >-
        The new state for the enquiry. You cannot go "back" with states, only
        progress them forward. This is not available in production.
      enum:
        - SHORTLISTING
        - QUOTED
        - CLOSED
      example: SHORTLISTING
      type: string
    sandboxEnquiryTriggerWebhookEventRequest:
      properties:
        eventType:
          $ref: '#/components/schemas/webhookEvent'
      required:
        - eventType
      type: object
    createOrUpdateWebhookRequest:
      properties:
        description:
          description: >-
            A description of the webhook. This is for your own reference and
            will not be used by Situ.
          example: Webhook for new enquiries
          type: string
        events:
          description: >-
            The events to subscribe to. This is a list of events that will
            trigger the webhook. You may subscribe to multiple events. If left
            empty, all events will be sent.
          items:
            $ref: '#/components/schemas/webhookEvent'
          type: array
        url:
          description: >-
            The URL to send the webhook to. Xenia will send a POST request to
            this URL with the event data in the body. The URL must be unique.
          example: https://example.com/webhook
          format: uri
          type: string
      required:
        - url
        - description
      type: object
    webhookObject:
      properties:
        description:
          description: >-
            A description of the webhook. This is for your own reference and
            will not be used by Situ.
          example: Webhook for new enquiries
          type: string
        events:
          description: >-
            The events to subscribe to. This is a list of events that will
            trigger the webhook. You may subscribe to multiple events. If left
            empty, all events will be sent.
          items:
            $ref: '#/components/schemas/webhookEvent'
          type: array
        id:
          description: >-
            The ID of the webhook. This is a unique value that can be used to
            retrieve your webhook via other endpoints where specified.
          example: 123e4567-e89b-12d3-a456-426614174000
          format: uuid
          type: string
        url:
          description: >-
            The URL to send the webhook to. Xenia will send a POST request to
            this URL with the event data in the body. The URL must be unique for
            each webhook.
          example: https://example.com/webhook
          format: uri
          type: string
      required:
        - url
        - description
      type: object
    webhookResponse:
      description: The webhook response wrapped in a data object.
      properties:
        data:
          $ref: '#/components/schemas/webhookObject'
      type: object
    webhooksResponse:
      description: The webhook response wrapped in a data object.
      properties:
        data:
          description: A list of webhooks
          items:
            $ref: '#/components/schemas/webhookObject'
          type: array
      type: object
    webhookPublicKeyObject:
      description: The public key object for webhook signature verification.
      properties:
        publicKey:
          description: The public key in base64 format used to verify webhook signatures.
          example: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1234...
          type: string
        algorithm:
          description: The algorithm used for signature generation.
          example: HMAC-SHA256
          type: string
        keyFormat:
          description: The format of the public key.
          example: base64
          type: string
      required:
        - publicKey
        - algorithm
        - keyFormat
      type: object
    webhookPublicKeyResponse:
      description: The public key response for webhook signature verification.
      properties:
        data:
          $ref: '#/components/schemas/webhookPublicKeyObject'
      required:
        - data
      type: object
  securitySchemes:
    apiKey:
      in: header
      name: X-Api-Key
      type: apiKey
