openapi: 3.0.3
info:
  title: TMS Gateway API
  version: 1.0.0-SNAPSHOT
  description: >
    API for registering operators and managing their TMS credentials. Once
    configured, operators and their venues become available for booking
    operations via the Bookings API.


    This API provides endpoints to:

    - Register, retrieve, update, and deregister operators

    - Manage TMS credentials for each operator


    **Supported TMS Systems:**

    - **Collins (CO)** - BearerToken authentication

    - **SevenRooms (SR)** - ClientCredentials authentication

    - **Zonal (ZO)** - BaseAuth authentication


    **Authentication Fields by TMS Type:**


    | TMS | Auth Type | Required Fields |

    |-----|-----------|-----------------|

    | Collins (CO) | BearerToken | `bearer`, `externalOperatorId` |

    | SevenRooms (SR) | ClientCredentials | `clientId`, `secretId` |

    | Zonal (ZO) | BaseAuth | `clientId`, `secretId` |
servers:
  - url: https://api.bookabletech.com
    description: Production
  - url: https://api-sandbox.bookabletech.com
    description: Sandbox
tags:
  - name: operators
    description: >
      Operators are the hospitality businesses (e.g. Stonegate, Nightcap, Big
      Table Group) whose venues you want to make bookable through your
      integration. Registering an operator is the first step before connecting
      any TMS credentials.
  - name: operator-tms-credentials
    description: >
      Credentials connect a registered operator to their TMS. Each credential
      set tells Bookable how to authenticate with a specific TMS on the
      operator's behalf — unlocking real-time availability and booking
      capability for that operator's venues.

      An operator may hold credentials for multiple TMS systems (e.g. Collins
      for some venues, SevenRooms for others).
paths:
  /operators:
    get:
      tags:
        - operators
      summary: List all operators
      description: Retrieve a list of all operators in the system.
      operationId: listOperators
      responses:
        '200':
          description: List of operators successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperatorList'
              example:
                - id: 1
                  businessName: Acme Restaurant Group
                  createdAt: '2025-01-10T08:00:00Z'
                  updatedAt: '2025-02-15T10:30:00Z'
                - id: 2
                  businessName: Downtown Dining Co.
                  createdAt: '2025-01-12T09:30:00Z'
                  updatedAt: '2025-01-12T09:30:00Z'
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
        - Production:
            - venue-group:read
        - Sandbox:
            - venue-group:read
    post:
      tags:
        - operators
      summary: Create a new operator
      description: Create a new operator with the provided details.
      operationId: createOperator
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperatorRequest'
            example:
              businessName: New Restaurant Group
              partnerSource: Partner Trading Name
      responses:
        '201':
          description: Operator successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Operator'
              example:
                id: 3
                businessName: New Restaurant Group
                createdAt: '2025-02-20T14:00:00Z'
                updatedAt: '2025-02-20T14:00:00Z'
        '400':
          description: Invalid request data
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
        - Production:
            - venue-group:create
        - Sandbox:
            - venue-group:create
  /operators/{operatorId}:
    get:
      tags:
        - operators
      summary: Get a specific operator
      description: Retrieve the details of a specific operator by its ID.
      operationId: getOperator
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
      responses:
        '200':
          description: Operator successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Operator'
              example:
                id: 1
                businessName: Acme Restaurant Group
                createdAt: '2025-01-10T08:00:00Z'
                updatedAt: '2025-02-15T10:30:00Z'
        '401':
          description: Unauthorized
        '404':
          description: Operator not found
        '500':
          description: Internal server error
      security:
        - Production:
            - venue-group:read
        - Sandbox:
            - venue-group:read
    put:
      tags:
        - operators
      summary: Update an operator
      description: Update the details of an existing operator.
      operationId: updateOperator
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperatorUpdateRequest'
            example:
              businessName: Updated Restaurant Group Name
      responses:
        '200':
          description: Operator successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Operator'
              example:
                id: 1
                businessName: Updated Restaurant Group Name
                createdAt: '2025-01-10T08:00:00Z'
                updatedAt: '2025-02-20T15:45:00Z'
        '400':
          description: Invalid request data
        '401':
          description: Unauthorized
        '404':
          description: Operator not found
        '500':
          description: Internal server error
      security:
        - Production:
            - venue-group:update
        - Sandbox:
            - venue-group:update
    delete:
      tags:
        - operators
      summary: Delete an operator
      description: Remove an operator from the system.
      operationId: deleteOperator
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
      responses:
        '204':
          description: Operator successfully deleted
        '401':
          description: Unauthorized
        '404':
          description: Operator not found
        '500':
          description: Internal server error
      security:
        - Production:
            - venue-group:delete
        - Sandbox:
            - venue-group:delete
  /operators/{operatorId}/tms-credentials:
    get:
      tags:
        - operator-tms-credentials
      summary: List TMS credentials for an operator
      description: Retrieve all TMS credentials associated with a specific operator.
      operationId: listOperatorTmsCredentialss
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
      responses:
        '200':
          description: List of TMS credentials successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperatorTmsCredentialsList'
              example:
                - operatorId: 1
                  tmsId: 1
                  tmsName: Collins
                  tmsSlug: CO
                  active: true
                  createdAt: '2025-01-15T10:30:00Z'
                  updatedAt: '2025-02-10T14:20:00Z'
                - operatorId: 1
                  tmsId: 2
                  tmsName: SevenRooms
                  tmsSlug: SR
                  active: true
                  createdAt: '2025-01-20T09:15:00Z'
                  updatedAt: '2025-01-20T09:15:00Z'
        '404':
          description: Operator not found
      security:
        - Production:
            - venue-group:read
        - Sandbox:
            - venue-group:read
    post:
      tags:
        - operator-tms-credentials
      summary: Create TMS credentials for an operator
      description: >-
        Create a new TMS credentials to link a table management system to an
        operator with the necessary credentials.
      operationId: createOperatorTmsCredentials
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperatorTmsCredentialsRequest'
            example:
              tmsSlug: CO
              clientId: 44966392-f2d4-4929-8c9a-e87a0e7dc856
              secretId: LjjXs5$3M%Btx@tt
              bearer: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
              externalOperatorId: 514ada610df690b6770000fd
              active: true
      responses:
        '201':
          description: TMS credentials successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperatorTmsCredentials'
              example:
                operatorId: 1
                tmsId: 1
                tmsName: Collins
                tmsSlug: CO
                clientId: null
                secretId: null
                bearer: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
                externalOperatorId: 514ada610df690b6770000fd
                active: true
                createdAt: '2025-02-19T10:30:00Z'
                updatedAt: '2025-02-19T10:30:00Z'
        '400':
          description: Invalid request data
        '404':
          description: Operator or TMS not found
        '409':
          description: TMS credentials already exists for this operator
      security:
        - Production:
            - venue-group:update
        - Sandbox:
            - venue-group:update
  /operators/{operatorId}/tms-credentials/{tmsId}:
    get:
      tags:
        - operator-tms-credentials
      summary: Get a specific TMS credentials
      description: >-
        Retrieve the details of a specific TMS credentials for an operator,
        including credentials and settings.
      operationId: getOperatorTmsCredentials
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
        - name: tmsId
          in: path
          required: true
          description: The unique identifier of the TMS
          schema:
            type: integer
            example: 1
      responses:
        '200':
          description: TMS credentials successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperatorTmsCredentials'
              example:
                operatorId: 1
                tmsId: 1
                tmsName: Collins
                tmsSlug: CO
                clientId: null
                secretId: null
                bearer: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
                externalOperatorId: 514ada610df690b6770000fd
                active: true
                createdAt: '2025-01-15T10:30:00Z'
                updatedAt: '2025-02-10T14:20:00Z'
        '404':
          description: Operator or TMS credentials not found
      security:
        - Production:
            - venue-group:update
        - Sandbox:
            - venue-group:update
    put:
      tags:
        - operator-tms-credentials
      summary: Update TMS credentials
      description: >-
        Update the credentials and settings of an existing TMS credentials for
        an operator.
      operationId: updateOperatorTmsCredentials
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
        - name: tmsId
          in: path
          required: true
          description: The unique identifier of the TMS
          schema:
            type: integer
            example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperatorTmsCredentialsUpdateRequest'
            example:
              clientId: 44966392-f2d4-4929-8c9a-e87a0e7dc856
              secretId: LjjXs5$3M%Btx@tt
              bearer: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
              externalOperatorId: 514ada610df690b6770000fd
              active: true
      responses:
        '200':
          description: TMS credentials successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperatorTmsCredentials'
              example:
                operatorId: 1
                tmsId: 1
                tmsName: Collins
                tmsSlug: CO
                clientId: null
                secretId: null
                bearer: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
                externalOperatorId: 514ada610df690b6770000fd
                active: true
                createdAt: '2025-01-15T10:30:00Z'
                updatedAt: '2025-02-19T16:45:00Z'
        '400':
          description: Invalid request data
        '404':
          description: Operator or TMS credentials not found
      security:
        - Production:
            - venue-group:update
        - Sandbox:
            - venue-group:update
    delete:
      tags:
        - operator-tms-credentials
      summary: Delete TMS credentials
      description: Remove a TMS credentials from an operator.
      operationId: deleteOperatorTmsCredentials
      parameters:
        - name: operatorId
          in: path
          required: true
          description: The unique identifier of the operator
          schema:
            type: integer
            example: 1
        - name: tmsId
          in: path
          required: true
          description: The unique identifier of the TMS
          schema:
            type: integer
            example: 1
      responses:
        '204':
          description: TMS credentials successfully deleted
        '404':
          description: Operator or TMS credentials not found
      security:
        - Production:
            - venue-group:update
        - Sandbox:
            - venue-group:update
components:
  schemas:
    Operator:
      type: object
      description: Complete operator details
      properties:
        id:
          type: integer
          description: The unique identifier of the operator
          example: 1
        businessName:
          type: string
          description: Business name of the operator
          example: Acme Restaurant Group
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the operator was created
          example: '2025-01-10T08:00:00Z'
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the operator was last updated
          example: '2025-02-15T10:30:00Z'
      required:
        - id
        - businessName
        - createdAt
        - updatedAt
    OperatorList:
      type: array
      description: List of operators
      items:
        $ref: '#/components/schemas/Operator'
    OperatorRequest:
      type: object
      description: Request payload for creating a new operator
      properties:
        businessName:
          type: string
          description: Business name of the operator
          minLength: 1
          maxLength: 255
          example: New Restaurant Group
        partnerSource:
          type: string
          nullable: true
          description: >
            Partner source identifier.

            This is required for partner users. 

            This will be used to track bookings that come from your integration
            with this operator.

            If you have been working with the operator already, it is likely
            they already have created a label for your channel. Please ask for
            this to continue to use the same partnerSource.
          minLength: 1
          maxLength: 255
          example: Partner Trading Name
      required:
        - businessName
    OperatorUpdateRequest:
      type: object
      description: Request payload for updating an existing operator
      properties:
        businessName:
          type: string
          description: Updated business name of the operator
          minLength: 1
          maxLength: 255
          example: Updated Restaurant Group Name
      required:
        - businessName
    OperatorTmsCredentialsList:
      type: array
      description: List of TMS credentials for an operator
      items:
        $ref: '#/components/schemas/OperatorTmsCredentialsSummary'
    OperatorTmsCredentialsSummary:
      type: object
      description: Summary of a TMS credentials (without sensitive credentials)
      properties:
        operatorId:
          type: integer
          description: The unique identifier of the operator
          example: 1
        tmsId:
          type: integer
          description: The unique identifier of the TMS
          example: 1
        tmsName:
          type: string
          description: The name of the TMS
          example: Collins
        tmsSlug:
          type: string
          description: The slug identifier of the TMS
          example: CO
        active:
          type: boolean
          description: Whether this TMS credentials is currently active
          example: true
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the connection was created
          example: '2025-01-15T10:30:00Z'
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the connection was last updated
          example: '2025-02-10T14:20:00Z'
      required:
        - operatorId
        - tmsId
        - tmsName
        - tmsSlug
        - active
    OperatorTmsCredentials:
      type: object
      description: Complete TMS credentials for an operator including credentials
      properties:
        operatorId:
          type: integer
          description: The unique identifier of the operator
          example: 1
        tmsId:
          type: integer
          description: The unique identifier of the TMS
          example: 1
        tmsName:
          type: string
          description: The name of the TMS
          example: Collins
        tmsSlug:
          type: string
          description: The slug identifier of the TMS
          example: CO
        clientId:
          type: string
          nullable: true
          description: >-
            Client ID used for authentication with the TMS. Required for
            BaseAuth and ClientCredentials auth types.
          example: 44966392-f2d4-4929-8c9a-e87a0e7dc856
        secretId:
          type: string
          nullable: true
          description: >-
            Client secret used for authentication with the TMS. Required for
            BaseAuth and ClientCredentials auth types.
          example: LjjXs5$3M%Btx@tt
        bearer:
          type: string
          nullable: true
          description: >-
            Bearer token used for authentication with the TMS. Required for
            BearerToken auth type (e.g., Collins).
          example: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
        externalOperatorId:
          type: string
          description: >-
            External identifier for the operator in the TMS system. Format
            varies by TMS (hex string for Collins, UUID for others, or empty
            string).
          example: 514ada610df690b6770000fd
        active:
          type: boolean
          description: Whether this TMS credentials is currently active
          example: true
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the connection was created
          example: '2025-01-15T10:30:00Z'
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the connection was last updated
          example: '2025-02-10T14:20:00Z'
      required:
        - operatorId
        - tmsId
        - tmsName
        - tmsSlug
        - externalOperatorId
        - active
    OperatorTmsCredentialsRequest:
      type: object
      description: Request payload for creating a new TMS credentials
      properties:
        tmsSlug:
          type: string
          description: |
            The slug identifier of the TMS to connect. Supported values:
            - `CO` - Collins (uses BearerToken authentication)
            - `SR` - SevenRooms (uses ClientCredentials authentication)
            - `ZO` - Zonal (uses BaseAuth authentication)
          enum:
            - CO
            - SR
            - ZO
          example: CO
        clientId:
          type: string
          nullable: true
          description: >-
            Client ID for authentication. Required for BaseAuth and
            ClientCredentials TMS types.
          example: 44966392-f2d4-4929-8c9a-e87a0e7dc856
        secretId:
          type: string
          nullable: true
          description: >-
            Client secret for authentication. Required for BaseAuth and
            ClientCredentials TMS types.
          example: LjjXs5$3M%Btx@tt
        bearer:
          type: string
          nullable: true
          description: >-
            Bearer token for authentication. Required for BearerToken TMS type
            (e.g., Collins).
          example: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
        externalOperatorId:
          type: string
          description: External identifier for the operator in the TMS system
          example: 514ada610df690b6770000fd
        active:
          type: boolean
          description: Whether this TMS credentials should be active
          example: true
      required:
        - tmsSlug
        - externalOperatorId
        - active
    OperatorTmsCredentialsUpdateRequest:
      type: object
      description: >-
        Request payload for updating an existing TMS credentials (tmsId is in
        the URL path)
      properties:
        clientId:
          type: string
          nullable: true
          description: >-
            Client ID for authentication. Required for BaseAuth and
            ClientCredentials TMS types.
          example: 44966392-f2d4-4929-8c9a-e87a0e7dc856
        secretId:
          type: string
          nullable: true
          description: >-
            Client secret for authentication. Required for BaseAuth and
            ClientCredentials TMS types.
          example: LjjXs5$3M%Btx@tt
        bearer:
          type: string
          nullable: true
          description: >-
            Bearer token for authentication. Required for BearerToken TMS type
            (e.g., Collins).
          example: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
        externalOperatorId:
          type: string
          description: External identifier for the operator in the TMS system
          example: 514ada610df690b6770000fd
        active:
          type: boolean
          description: Whether this TMS credentials should be active
          example: true
      required:
        - externalOperatorId
        - active
  securitySchemes:
    Production:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.bookabletech.com/oauth/token
          scopes:
            venue-group:read: Grants read access to venue group details and RMS configurations
            venue-group:create: Grants permission to create venue group RMS configurations
            venue-group:update: Grants permission to update venue group RMS configurations
            venue-group:delete: Grants permission to delete venue group RMS configurations
      description: |
        This API uses OAuth2 client credentials flow via Auth0.
        **Important:** Include the `audience` parameter in your token request.
        Example token request:
        ```
        POST https://auth.bookabletech.com/oauth/token
        {
          "grant_type": "client_credentials",
          "client_id": "YOUR_CLIENT_ID",
          "client_secret": "YOUR_CLIENT_SECRET",
          "audience": "api.bookabletech.com"
        }
        ```
    Sandbox:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth-sandbox.bookabletech.com/oauth/token
          scopes:
            venue-group:read: Grants read access to venue group details and RMS configurations
            venue-group:create: Grants permission to create venue group RMS configurations
            venue-group:update: Grants permission to update venue group RMS configurations
            venue-group:delete: Grants permission to delete venue group RMS configurations
      description: >
        This API uses OAuth2 client credentials flow via Auth0 for the Sandbox
        Production environment.

        This environment is used for partner testing with production-like data
        and WireMock integrations.

        **Important:** Include the `audience` parameter in your token request.

        Example token request:

        ```

        POST https://auth-sandbox.bookabletech.com/oauth/token

        {
          "grant_type": "client_credentials",
          "client_id": "YOUR_CLIENT_ID",
          "client_secret": "YOUR_CLIENT_SECRET",
          "audience": "api.bookabletech.com"
        }

        ```
