openapi: 3.1.0
info:
  title: AI Integration Gateway API
  version: 1.0.0
  x-logo:
    url: https://thumb.wikimedia.org/wikipedia/commons/thumb/9/9f/Logo_Bechtle.svg/330px-Logo_Bechtle.svg.png
    altText: Always prepared for success.
  description: |
    The AI Integration Gateway gives customers authenticated access to the AI integration services.

    ## Authentication

    1. Call `POST /login` with your username and password. The response contains a JWT.
    2. Send the token in the `Authorization` header of every other request:
       `Authorization: Bearer <token>`.

    Tokens are short-lived (15 minutes by default). When a request returns `401` with
    `Invalid or expired token`, log in again to get a new token.

    ## Errors

    Errors raised by the gateway itself have a JSON body of the form `{"error": "<message>"}`.
servers:
  - url: https://aiintegrationgw.api.bechtle.cloud/api
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: Obtain an access token.
  - name: Gateway
    description: Endpoints that require an access token.
  - name: Status
    description: Service status.
paths:
  /login:
    post:
      operationId: login
      tags:
        - Authentication
      summary: Log in
      description: Exchange username and password for a short-lived JWT access token.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            example:
              username: customer1
              password: supersecret
      responses:
        '200':
          description: Login successful.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Wrong username or password.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Unauthorized
        '503':
          description: The authentication backend is temporarily unavailable. Retry later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Authentication backend unavailable
  /callerid:
    post:
      operationId: getCallerId
      tags:
        - Gateway
      summary: Get caller ID
      description: |
        Returns the caller ID for the given telephone number. The customer is determined from the
        access token.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CallerIdRequest'
            example:
              telephone: 49123456789
      responses:
        '200':
          description: Caller ID for the telephone number.
          content:
            application/json:
              schema:
                type: object
        '400':
          description: The request body is not valid JSON or `telephone` is missing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Missing 'telephone' in request body
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Telephone number not found could not identify caller ID.
          content:
            application/json:
              schema:
                type: object
        '502':
          $ref: '#/components/responses/UpstreamError'
  /sendmail:
    post:
      operationId: sendMail
      tags:
        - Gateway
      summary: Send mail
      description: |
        Sends an email. The customer is determined from the access token.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMailRequest'
            example:
              subject: Your request
              recipientsTo: max@example.com;erika@example.com
              recipientsCc: team@example.com
              importance: Normal
              mailHeaderText: Status update
              mailBody: Your request has been processed.
      responses:
        '200':
          description: The mail was accepted for delivery.
          content:
            application/json:
              schema:
                type: object
        '400':
          description: The request body is not valid JSON, a required field is missing or a field is invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Missing or invalid 'recipientsTo' (email addresses separated by ';')
        '401':
          $ref: '#/components/responses/Unauthorized'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /health:
    get:
      operationId: health
      tags:
        - Status
      summary: Health check
      description: Returns `ok` when the gateway is running. Does not require authentication.
      security: []
      responses:
        '200':
          description: The gateway is running.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  status:
                    type: string
                    const: ok
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Token returned by `POST /login`.
  schemas:
    LoginRequest:
      type: object
      required:
        - username
        - password
      properties:
        username:
          type: string
          minLength: 1
        password:
          type: string
          minLength: 1
          format: password
    LoginResponse:
      type: object
      required:
        - token
      properties:
        token:
          type: string
          description: 'JWT access token. Send it as `Authorization: Bearer <token>`.'
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    CallerIdRequest:
      type: object
      required:
        - telephone
      properties:
        telephone:
          type: string
          minLength: 1
          description: Telephone number to look up.
    SendMailRequest:
      type: object
      required:
        - subject
        - recipientsTo
        - mailBody
      properties:
        subject:
          type: string
          minLength: 1
          description: Mail subject (plain text).
        recipientsTo:
          type: string
          minLength: 1
          description: Recipient email addresses, separated by semicolons.
          example: max@example.com;erika@example.com
        recipientsCc:
          type: string
          description: CC email addresses, separated by semicolons.
        importance:
          type: string
          enum:
            - Low
            - Normal
            - High
          default: Normal
          description: Mail importance (case-insensitive).
        mailHeaderText:
          type: string
          description: Header text of the mail, plain text or base64.
        mailBody:
          type: string
          minLength: 1
          description: Mail body, plain text or base64.
        buttons:
          type: string
          description: Optional buttons shown in the mail.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable error message.
  responses:
    BadRequest:
      description: The request body is not valid JSON or required fields are missing.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Missing 'username' or 'password' in request body
    Unauthorized:
      description: The access token is missing, invalid or expired.
      headers:
        WWW-Authenticate:
          schema:
            type: string
            example: Bearer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Invalid or expired token
    UpstreamError:
      description: The backend could not be reached. Retry later.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Upstream error
