{
  "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.\n\n## Authentication\n\n1. Call `POST /login` with your username and password. The response contains a JWT.\n2. Send the token in the `Authorization` header of every other request:\n   `Authorization: Bearer <token>`.\n\nTokens are short-lived (15 minutes by default). When a request returns `401` with\n`Invalid or expired token`, log in again to get a new token.\n\n## Errors\n\nErrors raised by the gateway itself have a JSON body of the form `{\"error\": \"<message>\"}`.\n"
  },
  "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\naccess token.\n",
        "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.\n",
        "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"
            }
          }
        }
      }
    }
  }
}