{
  "openapi": "3.1.0",
  "info": {
    "title": "BreachLine API",
    "summary": "The BreachLine LLM API (OpenAI- and Anthropic-compatible) and the Platform API.",
    "contact": {
      "name": "BreachLine support",
      "url": "https://breachline.io/contact"
    },
    "termsOfService": "https://breachline.io/terms",
    "version": "next",
    "description": "Reference for the BreachLine API, documentation version `next`. Guides, examples and policies live at https://dev.breachline.io/.\n\n## Versioning\n\nThe API is versioned by its URL path (`/v1`). There is no version request header. Each documentation version is a dated snapshot of the `/v1` surface, so you can see exactly what changed between snapshots. `next` previews changes that are not released or not stable yet.\n\n## Changelog\n\nThe changes between documentation versions are listed at https://dev.breachline.io/changelog/.\n\n## Accessing the API\n\nSend a BreachLine API key (`bl_live_…`) as `X-API-Key: <key>` or `Authorization: Bearer <key>`. Create keys in the console under Settings, API & Developer. Most errors use the envelope `{ \"error\": { \"status\", \"message\", \"code\", \"detail\", \"request_id\" } }`; the Anthropic-compatible endpoints use the Anthropic envelope, and a few edge responses (an oversized body, the per-user rate limits, an empty completion) do not use the envelope. See the Errors guide.\n\n## Rate limits\n\nChat completions and Responses are limited per API key per minute, hour and day, in fixed UTC windows. Embeddings, rerank and the Platform API are limited per user per minute, and Platform API responses carry `X-RateLimit-*` headers. A limited request gets `429`. See the Rate limits guide.\n\n## Changes from 2026-11-11 to next\n\nNo endpoint changes."
  },
  "servers": [
    {
      "url": "https://api.breachline.io",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Chat",
      "description": "OpenAI-compatible chat completions."
    },
    {
      "name": "Responses",
      "description": "OpenAI-compatible Responses API, with optional stored threads."
    },
    {
      "name": "Models",
      "description": "The public Nebula model catalog with GBP prices."
    },
    {
      "name": "Embeddings",
      "description": "OpenAI-compatible text embeddings."
    },
    {
      "name": "Rerank",
      "description": "Cohere-compatible document reranking."
    },
    {
      "name": "Batches",
      "description": "Asynchronous bulk chat completions and their JSONL input files."
    },
    {
      "name": "Messages",
      "description": "Anthropic-compatible Messages API. Beta."
    },
    {
      "name": "API keys",
      "description": "Create, list, rotate and revoke `bl_live_` API keys."
    },
    {
      "name": "Usage",
      "description": "Token usage, the activity log and the self-service spend cap."
    },
    {
      "name": "Account",
      "description": "The signed-in user's profile, data export and deletion."
    },
    {
      "name": "Organizations",
      "description": "Organizations, members and invitations."
    },
    {
      "name": "Settings",
      "description": "Notification preferences and audit logs."
    },
    {
      "name": "Privacy",
      "description": "Data-subject erasure requests."
    },
    {
      "name": "Integrations",
      "description": "Integration status, Slack notifications and the Jira configuration."
    }
  ],
  "paths": {
    "/api/v1/llm/v1/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "tags": [
          "Chat"
        ],
        "summary": "Create a chat completion",
        "description": "OpenAI-compatible chat completions with tool calling, structured output and streaming. Every request is routed to a Nebula model; vendor model ids and retired Nebula ids resolve to `nebula-4.5`. Requires the `llm:access` or `llm:chat` scope. A credit check runs before the model is called (`402` when the organization has no spendable credit or its spend cap is reached).",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              },
              "example": {
                "model": "nebula-4.5",
                "messages": [
                  {
                    "role": "system",
                    "content": "You are a concise security assistant."
                  },
                  {
                    "role": "user",
                    "content": "Explain what a reflected XSS finding means for a login page."
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A `chat.completion` object, or with `stream: true` a `text/event-stream` of `chat.completion.chunk` events ending with `data: [DONE]`. Errors after the stream opens arrive in-band as a `StreamError` event.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletion"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-sent events. Each `data:` line holds a `chat.completion.chunk` JSON object."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ChatUnavailable"
          }
        }
      }
    },
    "/api/v1/llm/v1/models": {
      "get": {
        "operationId": "listModels",
        "tags": [
          "Models"
        ],
        "summary": "List models",
        "description": "The Nebula models available to the caller, with the GBP price per million tokens. Cached privately for 60 seconds (`Cache-Control: private, max-age=60`). Requires `llm:access`. `nebula-v` is listed only while a vision engine is enabled.",
        "responses": {
          "200": {
            "description": "The model list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/llm/v1/responses": {
      "post": {
        "operationId": "createResponse",
        "tags": [
          "Responses"
        ],
        "summary": "Create a response",
        "description": "OpenAI-compatible Responses API. With `store: true` the completed response is kept for 30 days by default so a later request can continue it with `previous_response_id`; storing and threading need an organization-bound user (`403` otherwise). Hosted tools are not supported and are dropped; function tools work. Requires `llm:access` or `llm:chat`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResponsesRequest"
              },
              "example": {
                "model": "nebula-4.5",
                "instructions": "Answer in two sentences.",
                "input": "What does an SSRF finding let an attacker do?",
                "store": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A `response` object, or with `stream: true` a `text/event-stream` of `response.*` events.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Response"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "`response.created`, `response.output_item.added`, `response.output_text.delta`, …, `response.completed` (or `response.failed`)."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/api/v1/llm/v1/responses/{response_id}": {
      "parameters": [
        {
          "name": "response_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "retrieveResponse",
        "tags": [
          "Responses"
        ],
        "summary": "Retrieve a stored response",
        "description": "Returns a response stored with `store: true`. Stored responses belong to the user and organization that created them, so any key or session of that user in that organization can read them; anyone else gets `404`.",
        "responses": {
          "200": {
            "description": "The stored response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Response"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "operationId": "deleteResponse",
        "tags": [
          "Responses"
        ],
        "summary": "Delete a stored response",
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "object": {
                      "type": "string",
                      "const": "response.deleted"
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/llm/v1/embeddings": {
      "post": {
        "operationId": "createEmbeddings",
        "tags": [
          "Embeddings"
        ],
        "summary": "Create embeddings",
        "description": "768-dimensional float vectors from `nebula-embed`. Up to 256 inputs; each input at most 1,000 UTF-8 bytes, and the whole request at most 1,056 bytes including the task instruction added to each input. Metered at about 4 characters per token at the flat Nebula input rate. Requires `llm:access` or `llm:embeddings`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingsRequest"
              },
              "example": {
                "model": "nebula-embed",
                "input": "Session cookie set without the Secure flag",
                "task_type": "RETRIEVAL_DOCUMENT"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The embeddings, in input order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/llm/v1/rerank": {
      "post": {
        "operationId": "createRerank",
        "tags": [
          "Rerank"
        ],
        "summary": "Rerank documents",
        "description": "Cohere-compatible reranking with `nebula-rerank`: orders up to 256 documents by relevance to a query. Metered on input tokens at the flat Nebula input rate. Requires `llm:access`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RerankRequest"
              },
              "example": {
                "query": "Which finding affects authentication?",
                "documents": [
                  "Missing rate limit on the password reset endpoint",
                  "Verbose server banner on the marketing site"
                ],
                "top_n": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ranked results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RerankResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/llm/v1/batches": {
      "post": {
        "operationId": "createBatch",
        "tags": [
          "Batches"
        ],
        "summary": "Create a batch",
        "description": "Submit up to 50,000 chat completion requests, inline (`requests`) or as an uploaded JSONL file (`input_file_id`). Batches need an organization-bound user and the `llm:batch`, `llm:chat` or `llm:access` scope. They are charged once, at the full Nebula price, when final results are fetched.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created batch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Batch"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "get": {
        "operationId": "listBatches",
        "tags": [
          "Batches"
        ],
        "summary": "List batches",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit100"
          }
        ],
        "responses": {
          "200": {
            "description": "The caller's batches, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Batch"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/llm/v1/batches/{batch_id}": {
      "get": {
        "operationId": "retrieveBatch",
        "tags": [
          "Batches"
        ],
        "summary": "Retrieve a batch",
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The batch and its request counts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Batch"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/llm/v1/batches/{batch_id}/cancel": {
      "post": {
        "operationId": "cancelBatch",
        "tags": [
          "Batches"
        ],
        "summary": "Cancel a batch",
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The batch after the cancel request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Batch"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/llm/v1/batches/{batch_id}/results": {
      "get": {
        "operationId": "getBatchResults",
        "tags": [
          "Batches"
        ],
        "summary": "Get batch results",
        "description": "One result per request. The batch is charged once, when its results are first fetched in a final state. While that charge is not yet settled the endpoint answers `503` with `Retry-After: 30`.",
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The results.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "description": "One result line, keyed by your `custom_id`, with the chat completion or an error.",
                    "properties": {
                      "custom_id": {
                        "type": "string"
                      },
                      "response": {
                        "type": "object"
                      },
                      "error": {
                        "type": [
                          "object",
                          "null"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "502": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/llm/v1/files": {
      "post": {
        "operationId": "uploadFile",
        "tags": [
          "Batches"
        ],
        "summary": "Upload a batch input file",
        "description": "Upload a JSONL file of batch requests (multipart form, field `file`). Maximum 50 MiB by default.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "JSONL, one request per line."
                  },
                  "purpose": {
                    "type": "string",
                    "default": "batch"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored file.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "object": {
                      "type": "string",
                      "const": "file"
                    },
                    "purpose": {
                      "type": "string"
                    },
                    "bytes": {
                      "type": "integer"
                    },
                    "created_at": {
                      "type": "integer",
                      "description": "Unix seconds."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/llm/v1/files/{file_id}/content": {
      "get": {
        "operationId": "getFileContent",
        "tags": [
          "Batches"
        ],
        "summary": "Download file content",
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The raw file bytes.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/llm/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "tags": [
          "Messages"
        ],
        "summary": "Create a message (Anthropic-compatible)",
        "description": "Beta. Anthropic Messages wire format over the same gateway as chat completions, so scopes (`llm:access` or `llm:chat`), rate limits, the credit check and `Idempotency-Key` behave identically. Point an Anthropic SDK at the base URL `https://api.breachline.io/api/v1/llm` with a BreachLine API key in `x-api-key`. Server tools, `mcp_servers`, `container` and URL or file document sources are refused with `400` rather than silently dropped. `temperature` and `top_p` accept 0 to 1. `top_k`, `cache_control`, `service_tier` and `context_management` are accepted and ignored. The `anthropic-version` header is accepted and not used.",
        "security": [
          {
            "AnthropicApiKey": []
          },
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "anthropic-version",
            "in": "header",
            "required": false,
            "description": "Accepted for SDK compatibility. Not used.",
            "schema": {
              "type": "string",
              "examples": [
                "2023-06-01"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessagesRequest"
              },
              "example": {
                "model": "nebula-4.5",
                "max_tokens": 1024,
                "system": "You are a concise security assistant.",
                "messages": [
                  {
                    "role": "user",
                    "content": "Summarise the risk of a missing Content-Security-Policy header."
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An Anthropic `message`, or with `stream: true` a `text/event-stream` of `message_start`, `content_block_start`, `content_block_delta`, `content_block_stop`, `message_delta`, `message_stop` and `ping` events. Usage follows the Anthropic convention: `input_tokens` excludes cache reads and writes, which are reported separately.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "401": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "402": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "403": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "409": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "429": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "503": {
            "$ref": "#/components/responses/AnthropicError"
          }
        }
      }
    },
    "/api/v1/llm/v1/messages/count_tokens": {
      "post": {
        "operationId": "countMessageTokens",
        "tags": [
          "Messages"
        ],
        "summary": "Count tokens (estimate)",
        "description": "Beta. Returns an estimate of about 4 characters per token over the translated request: requests are routed across engines with different tokenizers, so there is no single exact count. No model runs and nothing is charged, but the call is rate limited like chat and the body is capped at 4 MiB (`413` above that).",
        "security": [
          {
            "AnthropicApiKey": []
          },
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessagesRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The estimate.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "input_tokens": {
                      "type": "integer",
                      "minimum": 1
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "403": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "413": {
            "$ref": "#/components/responses/AnthropicError"
          },
          "429": {
            "$ref": "#/components/responses/AnthropicError"
          }
        }
      }
    },
    "/api/v1/keys/create": {
      "post": {
        "operationId": "createApiKey",
        "tags": [
          "API keys"
        ],
        "summary": "Create an API key",
        "description": "Mint a `bl_live_` key. Interactive sessions only: an API key gets `403`, because keys cannot mint keys. The session token must be under 5 minutes old, or the body must include the account `password`; otherwise the response is `428` (a step-up prompt, not a sign-out). At most 10 active keys per user and 5 creations per hour. Lifetime is capped at 365 days by default (an omitted or longer `expiresInDays` is clamped). `llm:*` scopes can always be granted; any other scope must be one you hold in your organization. The plaintext key is returned once, with `Cache-Control: no-store`.",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "AGENT",
                      "NORMAL",
                      "LLM"
                    ],
                    "default": "NORMAL",
                    "description": "A label for the key's purpose. Capability comes from `scopes`."
                  },
                  "scopes": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string"
                    },
                    "description": "Scopes to grant. Empty uses the type's default (NORMAL keys get `llm:access`, `llm:chat`).",
                    "examples": [
                      [
                        "llm:access",
                        "llm:chat"
                      ]
                    ]
                  },
                  "expiresInDays": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1
                  },
                  "password": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Account password, required when the session token is older than 5 minutes.",
                    "format": "password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new key. Store it now; it is never shown again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "key": {
                      "type": "string",
                      "description": "The plaintext key, starting `bl_live_`."
                    },
                    "key_prefix": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "expires_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "warning": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "428": {
            "description": "Step-up required. Re-send with `password`, or sign in again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/api/v1/keys/list": {
      "get": {
        "operationId": "listApiKeys",
        "tags": [
          "API keys"
        ],
        "summary": "List API keys",
        "description": "The caller's active keys. Plaintext is never returned; `key_prefix` identifies each key. An API key needs `keys:read`.",
        "responses": {
          "200": {
            "description": "Keys.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "scopes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "key_prefix": {
                            "type": "string"
                          },
                          "expires_at": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "is_expired": {
                            "type": "boolean"
                          },
                          "last_used_at": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "created_at": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/keys/{key_id}": {
      "delete": {
        "operationId": "revokeApiKey",
        "tags": [
          "API keys"
        ],
        "summary": "Revoke an API key",
        "description": "Revocation is immediate. An API key needs `keys:revoke`.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/keys/refresh/{key_id}": {
      "post": {
        "operationId": "refreshApiKey",
        "tags": [
          "API keys"
        ],
        "summary": "Rotate an API key",
        "description": "Issue a new secret for an existing key; the old secret stops working at once. Interactive sessions only (an API key gets `403`), and the account password is required (`401` if wrong).",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "password"
                ],
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new plaintext key, shown once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "warning": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/me": {
      "get": {
        "operationId": "getMyUsage",
        "tags": [
          "Usage"
        ],
        "summary": "Get your usage",
        "description": "Token, request and GBP totals for the caller over a window, optionally by day. Requires the `usage:read` member scope.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Since"
          },
          {
            "$ref": "#/components/parameters/Until"
          },
          {
            "name": "group_by_day",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The usage summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageSummary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/me/logs": {
      "get": {
        "operationId": "getMyUsageLogs",
        "tags": [
          "Usage"
        ],
        "summary": "List your recent requests",
        "description": "The per-request activity log. Metadata only; prompts and responses are never stored in it.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit100"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "Log entries, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageLogPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/me/budget": {
      "get": {
        "operationId": "getMyBudget",
        "tags": [
          "Usage"
        ],
        "summary": "Get your budget burn",
        "description": "Token burn for the current day or month window, plus an error-rate breakdown.",
        "parameters": [
          {
            "$ref": "#/components/parameters/BudgetWindow"
          },
          {
            "$ref": "#/components/parameters/Since"
          },
          {
            "$ref": "#/components/parameters/Until"
          }
        ],
        "responses": {
          "200": {
            "description": "Budget view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetView"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/me/budget/cap": {
      "get": {
        "operationId": "getMySpendCap",
        "tags": [
          "Usage"
        ],
        "summary": "Get your spend cap",
        "responses": {
          "200": {
            "description": "The cap, or nulls when none is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "cap_gbp": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "window": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "day",
                        "month",
                        null
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      },
      "put": {
        "operationId": "setMySpendCap",
        "tags": [
          "Usage"
        ],
        "summary": "Set your spend cap",
        "description": "A self-service ceiling on retail GBP spend per day or month. Once the window's spend reaches it, LLM requests get `402` until the window resets or the cap is raised. Requires the `settings:write` member scope.",
        "parameters": [
          {
            "name": "max_gbp",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0
            }
          },
          {
            "$ref": "#/components/parameters/BudgetWindow"
          }
        ],
        "responses": {
          "200": {
            "description": "Saved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "cap_gbp": {
                      "type": "number"
                    },
                    "window": {
                      "type": "string",
                      "enum": [
                        "day",
                        "month"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      },
      "delete": {
        "operationId": "clearMySpendCap",
        "tags": [
          "Usage"
        ],
        "summary": "Remove your spend cap",
        "description": "Requires the `settings:write` member scope.",
        "responses": {
          "200": {
            "description": "Removed."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/org/{org_id}": {
      "get": {
        "operationId": "getOrgUsage",
        "tags": [
          "Usage"
        ],
        "summary": "Get organization usage",
        "description": "Usage for an organization you are a member of.",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgId"
          },
          {
            "$ref": "#/components/parameters/Since"
          },
          {
            "$ref": "#/components/parameters/Until"
          },
          {
            "name": "group_by_day",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The usage summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageSummary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/org/{org_id}/logs": {
      "get": {
        "operationId": "getOrgUsageLogs",
        "tags": [
          "Usage"
        ],
        "summary": "List organization requests",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgId"
          },
          {
            "$ref": "#/components/parameters/Limit100"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "Log entries, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageLogPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/usage/org/{org_id}/budget": {
      "get": {
        "operationId": "getOrgBudget",
        "tags": [
          "Usage"
        ],
        "summary": "Get organization budget burn",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgId"
          },
          {
            "$ref": "#/components/parameters/BudgetWindow"
          },
          {
            "$ref": "#/components/parameters/Since"
          },
          {
            "$ref": "#/components/parameters/Until"
          }
        ],
        "responses": {
          "200": {
            "description": "Budget view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetView"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/users/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Account"
        ],
        "summary": "Get your profile",
        "responses": {
          "200": {
            "description": "The profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "operationId": "updateMe",
        "tags": [
          "Account"
        ],
        "summary": "Update your profile",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "email": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "email"
                  },
                  "country": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 120
                  },
                  "job_title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 120
                  },
                  "company": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 200
                  },
                  "industry": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 120
                  },
                  "use_case": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "phone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 40
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          }
        }
      },
      "delete": {
        "operationId": "deleteMe",
        "tags": [
          "Account"
        ],
        "summary": "Delete your account",
        "description": "Irreversible. Needs a console session token issued within the last 5 minutes, so API keys cannot call it.",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string"
                    },
                    "rows_deleted": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/users/me/export": {
      "get": {
        "operationId": "exportMe",
        "tags": [
          "Account"
        ],
        "summary": "Export your data",
        "description": "A JSON export of your account, memberships and API key metadata. Needs a console session token issued within the last 5 minutes.",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The export.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "export_version": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "user_id": {
                      "type": "string"
                    },
                    "account": {
                      "type": "object"
                    },
                    "memberships": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "api_keys": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/gdpr/deletion-requests": {
      "post": {
        "operationId": "requestDeletion",
        "tags": [
          "Privacy"
        ],
        "summary": "Request erasure",
        "description": "File a data-subject erasure request for review. Idempotent; an existing open request is returned instead of a duplicate.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionRequestEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/gdpr/deletion-requests/me": {
      "get": {
        "operationId": "getMyDeletionRequest",
        "tags": [
          "Privacy"
        ],
        "summary": "Get your erasure request",
        "responses": {
          "200": {
            "description": "Your most recent request, or `null`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionRequestEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/organizations": {
      "get": {
        "operationId": "listOrganizations",
        "tags": [
          "Organizations"
        ],
        "summary": "List your organizations",
        "responses": {
          "200": {
            "description": "Organizations you belong to.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "organizations": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/organizations/{org_id}": {
      "get": {
        "operationId": "getOrganization",
        "tags": [
          "Organizations"
        ],
        "summary": "Get an organization",
        "description": "Members only.",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgId"
          }
        ],
        "responses": {
          "200": {
            "description": "The organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/organizations/{org_id}/members": {
      "get": {
        "operationId": "listMembers",
        "tags": [
          "Organizations"
        ],
        "summary": "List members",
        "description": "Members only.",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgId"
          }
        ],
        "responses": {
          "200": {
            "description": "The members.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/organizations/{org_id}/invites": {
      "post": {
        "operationId": "createInvite",
        "tags": [
          "Organizations"
        ],
        "summary": "Invite a member",
        "description": "Requires the `org:invite` member scope. The response includes the invitation token; treat it as a secret.",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrgId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 254
                  },
                  "role": {
                    "type": "string",
                    "default": "MEMBER"
                  },
                  "scopes": {
                    "type": "array",
                    "maxItems": 200,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The invitation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "invitee_email": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "status": {
                      "type": "string"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "token": {
                      "type": "string",
                      "description": "The invitation token. Treat it as a secret."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/settings/notifications": {
      "get": {
        "operationId": "getNotificationPreferences",
        "tags": [
          "Settings"
        ],
        "summary": "Get notification preferences",
        "responses": {
          "200": {
            "description": "Preferences.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "preferences": {
                      "$ref": "#/components/schemas/NotificationPreferences"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "operationId": "updateNotificationPreferences",
        "tags": [
          "Settings"
        ],
        "summary": "Update notification preferences",
        "description": "Send only the fields to change.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationPreferences"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The saved preferences.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "preferences": {
                      "$ref": "#/components/schemas/NotificationPreferences"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          }
        }
      }
    },
    "/api/v1/settings/audit-logs": {
      "get": {
        "operationId": "getAuditLogs",
        "tags": [
          "Settings"
        ],
        "summary": "List audit log entries",
        "description": "Your own trail with `audit:read`, or the whole organization's with `scope=org` and `audit:read:org`.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "name": "severity",
            "in": "query",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "me",
                "org"
              ],
              "default": "me"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of entries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "scope": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "logs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "timestamp": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "action": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "severity": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "actor": {
                            "type": [
                              "string",
                              "object",
                              "null"
                            ]
                          },
                          "target": {
                            "type": [
                              "string",
                              "object",
                              "null"
                            ]
                          },
                          "ip_address": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "user_agent": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "details": {
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "compliance_tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/settings/audit-logs/export": {
      "get": {
        "operationId": "exportAuditLogs",
        "tags": [
          "Settings"
        ],
        "summary": "Export audit log entries",
        "description": "Requires `audit:export` (`audit:export:org` with `scope=org`).",
        "parameters": [
          {
            "name": "severity",
            "in": "query",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "me",
                "org"
              ],
              "default": "me"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The export file.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/integrations/status": {
      "get": {
        "operationId": "getIntegrationsStatus",
        "tags": [
          "Integrations"
        ],
        "summary": "Get integration status",
        "description": "Connection state and health for the organization's integrations. Requires `integrations:read`.",
        "responses": {
          "200": {
            "description": "Status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/integrations/config": {
      "get": {
        "operationId": "getIntegrationsConfig",
        "tags": [
          "Integrations"
        ],
        "summary": "Get the Slack configuration summary",
        "description": "Which Slack method is configured. Secrets are write-only and never returned (`has_webhook`, `has_bot_token` are booleans). Requires `integrations:read`.",
        "responses": {
          "200": {
            "description": "Configuration summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "method": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "has_webhook": {
                      "type": "boolean"
                    },
                    "has_bot_token": {
                      "type": "boolean"
                    },
                    "default_channel": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "team_id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/integrations/slack/notify": {
      "post": {
        "operationId": "slackNotify",
        "tags": [
          "Integrations"
        ],
        "summary": "Send a Slack message",
        "description": "Posts to the organization's connected Slack. Requires `integrations:notify`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 4000
                  },
                  "channel": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Accepted but has no effect: messages go to the channel the Slack incoming webhook was created for. The response echoes the value you sent."
                  },
                  "context": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "description": "Optional key-value fields shown with the message."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "channel": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "ts": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SlackNotConnected"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/integrations/slack/findings": {
      "post": {
        "operationId": "slackFindingsAlert",
        "tags": [
          "Integrations"
        ],
        "summary": "Send a findings alert to Slack",
        "description": "A formatted alert listing findings for one target. Requires `integrations:notify`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scan_target"
                ],
                "properties": {
                  "scan_target": {
                    "type": "string"
                  },
                  "findings": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "title",
                        "severity"
                      ],
                      "properties": {
                        "title": {
                          "type": "string"
                        },
                        "severity": {
                          "type": "string",
                          "examples": [
                            "critical",
                            "high",
                            "medium",
                            "low",
                            "info"
                          ]
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "target": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "evidence_summary": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "remediation": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "jira_ticket": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  },
                  "channel": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Accepted but has no effect; the webhook's own channel is used."
                  },
                  "thread_ts": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "channel": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "ts": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/SlackNotConnected"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    },
    "/api/v1/integrations/jira": {
      "get": {
        "operationId": "getJiraConfig",
        "tags": [
          "Integrations"
        ],
        "summary": "Get the Jira configuration",
        "description": "The legacy Jira configuration for this organization. The API token is never returned (`has_token` is a boolean). Nothing files Jira issues automatically; AI engineers use a Jira connection from the integration catalog when you ask them to. Requires `integrations:read`.",
        "responses": {
          "200": {
            "description": "Configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "configured": {
                      "type": "boolean"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "base_url": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "email": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "project_key": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "auto_ticket_severity": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Stored with this legacy configuration but not used: nothing files Jira issues automatically."
                    },
                    "has_token": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/UserRateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "A BreachLine API key (`bl_live_…`). Create one in the console under Settings, API & Developer."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "A BreachLine API key (`bl_live_…`) or a console session token, sent as `Authorization: Bearer <token>`."
      },
      "SessionAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "An interactive console session token. API keys are refused on endpoints that require it."
      },
      "AnthropicApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "A BreachLine API key (`bl_live_…`), as Anthropic SDKs send it."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Run this exact request at most once in 24 hours. A replay with the same key and the same body, from the same organization, user and API key, is refused with `409` before any model call. See the Idempotency guide.",
        "schema": {
          "type": "string",
          "minLength": 1
        }
      },
      "RequestId": {
        "name": "X-Request-ID",
        "in": "header",
        "required": false,
        "description": "Optional correlation id. Echoed in the `X-Request-ID` response header and in error bodies.",
        "schema": {
          "type": "string"
        }
      },
      "OrgId": {
        "name": "org_id",
        "in": "path",
        "required": true,
        "description": "Organization id.",
        "schema": {
          "type": "string"
        }
      },
      "Since": {
        "name": "since",
        "in": "query",
        "required": false,
        "description": "ISO-8601 start of the window (inclusive). A date without a time zone is read as UTC.",
        "schema": {
          "type": "string",
          "examples": [
            "2026-11-01"
          ]
        }
      },
      "Until": {
        "name": "until",
        "in": "query",
        "required": false,
        "description": "ISO-8601 end of the window (exclusive).",
        "schema": {
          "type": "string",
          "examples": [
            "2026-11-11"
          ]
        }
      },
      "Limit100": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 0,
          "default": 0
        }
      },
      "BudgetWindow": {
        "name": "window",
        "in": "query",
        "required": false,
        "description": "Budget window.",
        "schema": {
          "type": "string",
          "enum": [
            "day",
            "month"
          ],
          "default": "day"
        }
      }
    },
    "headers": {
      "X-Request-ID": {
        "description": "The request's correlation id (yours, or one BreachLine generated). Quote it to support.",
        "schema": {
          "type": "string"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "The error envelope used by every endpoint except the Anthropic-compatible ones.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "status",
              "message"
            ],
            "properties": {
              "status": {
                "type": "integer",
                "description": "The HTTP status code.",
                "examples": [
                  403
                ]
              },
              "message": {
                "type": "string",
                "description": "A short, display-safe summary for the status (for example `Access denied`).",
                "examples": [
                  "Access denied"
                ]
              },
              "code": {
                "type": "string",
                "description": "Machine-readable error code. See the Errors guide for the catalog.",
                "examples": [
                  "AUTHZ_2001"
                ]
              },
              "detail": {
                "type": "string",
                "description": "Human-readable detail for this specific failure.",
                "examples": [
                  "API key missing required scope: llm:access or llm:chat"
                ]
              },
              "errors": {
                "type": "array",
                "description": "Present on `422` validation errors.",
                "items": {
                  "$ref": "#/components/schemas/ValidationIssue"
                }
              },
              "request_id": {
                "type": "string",
                "description": "The request's correlation id."
              }
            }
          }
        }
      },
      "ValidationIssue": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "description": "Location of the invalid value, for example `body -> messages`."
          },
          "message": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "The validator's error type, for example `missing` or `less_than_equal`."
          },
          "constraints": {
            "type": "object",
            "description": "Present when the violated bound is numeric, for example `{ \"le\": 2 }`.",
            "additionalProperties": {
              "type": "number"
            }
          }
        }
      },
      "ChatMessage": {
        "type": "object",
        "required": [
          "role"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "user",
              "assistant",
              "tool"
            ]
          },
          "content": {
            "description": "Text, or an array of content parts (`text`, and `image_url` for `nebula-v`).",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "tool_calls": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "const": "function"
                },
                "function": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "arguments": {
                      "type": "string",
                      "description": "JSON-encoded arguments."
                    }
                  }
                }
              }
            }
          },
          "tool_call_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "For `role: tool`, the id of the call being answered."
          }
        }
      },
      "ChatCompletionRequest": {
        "type": "object",
        "required": [
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "nebula-4.5",
            "description": "`nebula-4.5` (text, smart-routed) or `nebula-v` (vision). Unknown and retired ids resolve to `nebula-4.5`."
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            }
          },
          "max_tokens": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Output-token ceiling. An explicit value is clamped to the platform maximum."
          },
          "max_completion_tokens": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "Alias of `max_tokens`; when both are sent, the smaller wins."
          },
          "temperature": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 2,
            "default": 0.7
          },
          "top_p": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "default": 1
          },
          "stream": {
            "type": [
              "boolean",
              "null"
            ],
            "default": false
          },
          "stop": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "tools": {
            "type": [
              "array",
              "null"
            ],
            "description": "OpenAI-format function tool definitions.",
            "items": {
              "type": "object"
            }
          },
          "tool_choice": {
            "description": "`auto`, `none`, `required`, or `{ \"type\": \"function\", \"function\": { \"name\": … } }`.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ]
          },
          "parallel_tool_calls": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "response_format": {
            "type": [
              "object",
              "null"
            ],
            "description": "`{ \"type\": \"json_object\" }` or `{ \"type\": \"json_schema\", \"json_schema\": { … } }`."
          },
          "reasoning_effort": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "none",
              "low",
              "medium",
              "high",
              "max",
              "xhigh",
              "ultra",
              null
            ],
            "description": "Requested reasoning depth. Omit it for adaptive routing."
          },
          "user": {
            "type": [
              "string",
              "null"
            ],
            "description": "A stable session or end-user id. Send the same value on every turn of a conversation so prompt caching can reuse earlier context."
          }
        }
      },
      "ChatCompletion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "chat.completion"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string",
            "examples": [
              "nebula-4.5"
            ]
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "message": {
                  "$ref": "#/components/schemas/ChatMessage"
                },
                "finish_reason": {
                  "type": "string",
                  "examples": [
                    "stop",
                    "length",
                    "tool_calls"
                  ]
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "completion_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              }
            }
          }
        }
      },
      "ModelList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "examples": [
                    "nebula-4.5",
                    "nebula-v",
                    "nebula-embed"
                  ]
                },
                "object": {
                  "type": "string",
                  "const": "model"
                },
                "created": {
                  "type": "integer"
                },
                "owned_by": {
                  "type": "string",
                  "const": "breachline"
                },
                "pricing": {
                  "type": "object",
                  "description": "The price per million tokens.",
                  "properties": {
                    "input": {
                      "type": "number"
                    },
                    "output": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string",
                      "const": "GBP"
                    },
                    "unit": {
                      "type": "string",
                      "const": "per_1m_tokens"
                    }
                  }
                },
                "capabilities": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "examples": [
                    [
                      "chat",
                      "reasoning",
                      "tool_calling"
                    ]
                  ]
                },
                "context_length": {
                  "type": "integer",
                  "examples": [
                    256000
                  ]
                },
                "description": "{ type: string }"
              }
            }
          }
        }
      },
      "ResponsesRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "nebula-4.5"
          },
          "input": {
            "description": "A string, or an array of input items (messages, function_call_output).",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            ]
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ]
          },
          "max_output_tokens": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "temperature": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 2
          },
          "top_p": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1
          },
          "reasoning": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "effort": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "tools": {
            "type": [
              "array",
              "null"
            ],
            "description": "Function tools. Hosted tools are not supported and are dropped.",
            "items": {
              "type": "object"
            }
          },
          "tool_choice": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ]
          },
          "parallel_tool_calls": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "stream": {
            "type": [
              "boolean",
              "null"
            ],
            "default": false
          },
          "store": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Keep the completed response (30 days by default) for retrieval and `previous_response_id`."
          },
          "previous_response_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Continue a stored response you own. An id you do not own contributes no history."
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ]
          },
          "user": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Response": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "response"
          },
          "created_at": {
            "type": "integer"
          },
          "model": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "examples": [
              "completed",
              "in_progress",
              "failed"
            ]
          },
          "output": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "output_text": {
            "type": "string"
          },
          "usage": {
            "type": "object"
          }
        }
      },
      "EmbeddingsRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "nebula-embed"
          },
          "input": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "maxItems": 256,
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "encoding_format": {
            "type": "string",
            "enum": [
              "float"
            ],
            "default": "float",
            "description": "Only `float` is supported; anything else is `400`. The OpenAI Python SDK sends `base64` when this is omitted, so pass `encoding_format=\"float\"` explicitly."
          },
          "dimensions": {
            "type": "integer",
            "enum": [
              768
            ],
            "default": 768
          },
          "task_type": {
            "type": "string",
            "default": "SEMANTIC_SIMILARITY",
            "enum": [
              "SEMANTIC_SIMILARITY",
              "RETRIEVAL_QUERY",
              "RETRIEVAL_DOCUMENT",
              "CODE_RETRIEVAL_QUERY",
              "CLASSIFICATION",
              "CLUSTERING"
            ],
            "description": "The retrieval task the vectors are for. Use `RETRIEVAL_DOCUMENT` when indexing and `RETRIEVAL_QUERY` when searching."
          },
          "user": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "EmbeddingList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "object": {
                  "type": "string",
                  "const": "embedding"
                },
                "index": {
                  "type": "integer"
                },
                "embedding": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "model": {
            "type": "string"
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              }
            }
          }
        }
      },
      "RerankRequest": {
        "type": "object",
        "required": [
          "query",
          "documents"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "nebula-rerank"
          },
          "query": {
            "type": "string"
          },
          "documents": {
            "type": "array",
            "maxItems": 256,
            "items": {
              "type": "string"
            }
          },
          "top_n": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "return_documents": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "RerankResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "model": {
            "type": "string",
            "const": "nebula-rerank"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "description": "Position of the document in your request."
                },
                "relevance_score": {
                  "type": "number"
                },
                "document": {
                  "type": "object",
                  "description": "Present when `return_documents` is true.",
                  "properties": {
                    "text": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              }
            }
          }
        }
      },
      "BatchCreateRequest": {
        "type": "object",
        "description": "Provide either `requests` or `input_file_id`.",
        "properties": {
          "requests": {
            "type": "array",
            "maxItems": 50000,
            "items": {
              "type": "object",
              "properties": {
                "custom_id": {
                  "type": "string"
                },
                "method": {
                  "type": "string",
                  "const": "POST"
                },
                "url": {
                  "type": "string",
                  "const": "/v1/chat/completions"
                },
                "body": {
                  "$ref": "#/components/schemas/ChatCompletionRequest"
                }
              }
            }
          },
          "input_file_id": {
            "type": "string",
            "description": "A JSONL file uploaded with `POST /api/v1/llm/v1/files`."
          },
          "endpoint": {
            "type": "string",
            "const": "/v1/chat/completions"
          },
          "completion_window": {
            "type": "string",
            "default": "24h"
          }
        }
      },
      "Batch": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "batch"
          },
          "endpoint": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "done",
              "expired",
              "failed",
              "canceled"
            ]
          },
          "completion_window": {
            "type": "string"
          },
          "request_counts": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "completed": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              }
            }
          },
          "output_file_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "error_file_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "input_file_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": [
              "integer",
              "string",
              "null"
            ]
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ]
          }
        }
      },
      "MessagesRequest": {
        "type": "object",
        "required": [
          "model",
          "max_tokens",
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "maxLength": 256,
            "examples": [
              "nebula-4.5"
            ]
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "description": "`user` and `assistant` turns with text, image (base64 or URL), document (base64 PDF, text or content), thinking, `tool_use` and `tool_result` blocks.",
            "items": {
              "type": "object"
            }
          },
          "system": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            ]
          },
          "stop_sequences": {
            "type": "array",
            "maxItems": 16,
            "items": {
              "type": "string"
            }
          },
          "stream": {
            "type": "boolean",
            "default": false
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "top_p": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "top_k": {
            "type": "integer",
            "description": "Accepted and ignored."
          },
          "tools": {
            "type": "array",
            "maxItems": 512,
            "description": "Custom tools with `name`, `description` and `input_schema`. Server tools are refused.",
            "items": {
              "type": "object"
            }
          },
          "tool_choice": {
            "type": "object",
            "description": "`auto`, `any`, `tool` (with `name`) or `none`; `disable_parallel_tool_use` is honoured."
          },
          "thinking": {
            "type": "object",
            "description": "`{ \"type\": \"enabled\" | \"adaptive\" | \"disabled\", \"budget_tokens\"?: int, \"display\"?: \"summarized\" | \"omitted\" }`"
          },
          "output_config": {
            "type": "object",
            "description": "`effort` (low, medium, high, xhigh, max) and `format` (`{ \"type\": \"json_schema\", \"schema\": { … } }`)."
          },
          "metadata": {
            "type": "object"
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "const": "message"
          },
          "role": {
            "type": "string",
            "const": "assistant"
          },
          "model": {
            "type": "string"
          },
          "content": {
            "type": "array",
            "description": "`text`, `thinking` and `tool_use` blocks.",
            "items": {
              "type": "object"
            }
          },
          "stop_reason": {
            "type": "string",
            "enum": [
              "end_turn",
              "max_tokens",
              "stop_sequence",
              "tool_use",
              "refusal"
            ]
          },
          "stop_sequence": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "type": "object",
            "properties": {
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              },
              "cache_creation_input_tokens": {
                "type": "integer"
              },
              "cache_read_input_tokens": {
                "type": "integer"
              }
            }
          }
        }
      },
      "UsageSummary": {
        "type": "object",
        "properties": {
          "scope": {
            "type": "string",
            "enum": [
              "user",
              "org"
            ]
          },
          "scope_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "since": {
            "type": [
              "string",
              "null"
            ]
          },
          "until": {
            "type": [
              "string",
              "null"
            ]
          },
          "totals": {
            "type": "object",
            "properties": {
              "input_tokens": {
                "type": "integer"
              },
              "output_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              },
              "price_gbp": {
                "type": "number",
                "description": "Customer charge for the window, in GBP."
              },
              "requests": {
                "type": "integer"
              },
              "p50_latency_ms": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "p95_latency_ms": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "cache_hit_rate_pct": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "daily": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "description": "YYYY-MM-DD (UTC)."
                },
                "input_tokens": {
                  "type": "integer"
                },
                "output_tokens": {
                  "type": "integer"
                },
                "total_tokens": {
                  "type": "integer"
                },
                "price_gbp": {
                  "type": "number"
                },
                "requests": {
                  "type": "integer"
                }
              }
            }
          },
          "rates": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          }
        }
      },
      "UsageLogPage": {
        "type": "object",
        "description": "A page of activity entries.",
        "properties": {
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "has_more": {
            "type": "boolean"
          },
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageLogEntry"
            }
          }
        }
      },
      "UsageLogEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "endpoint": {
            "type": "string",
            "examples": [
              "/api/v1/llm/v1/chat/completions"
            ]
          },
          "tier": {
            "type": "string",
            "description": "The public Nebula model label."
          },
          "input_tokens": {
            "type": "integer"
          },
          "output_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          },
          "response_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "cache_read_tokens": {
            "type": "integer"
          },
          "cache_write_tokens": {
            "type": "integer"
          },
          "latency_ms": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "BudgetView": {
        "type": "object",
        "properties": {
          "budget": {
            "type": "object",
            "properties": {
              "scope": {
                "type": "string"
              },
              "scope_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "window": {
                "type": "string",
                "enum": [
                  "day",
                  "month"
                ]
              },
              "window_start": {
                "type": "string",
                "format": "date-time"
              },
              "window_end": {
                "type": "string",
                "format": "date-time"
              }
            },
            "additionalProperties": true
          },
          "error_rate_by_model": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "Profile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "email_verified": {
            "type": "boolean"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "organization_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "company": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "industry": {
            "type": [
              "string",
              "null"
            ]
          },
          "job_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "use_case": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "DeletionRequestEnvelope": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "request": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "approved",
                  "completed",
                  "failed",
                  "rejected"
                ]
              }
            },
            "additionalProperties": true
          }
        }
      },
      "NotificationPreferences": {
        "type": "object",
        "properties": {
          "email_enabled": {
            "type": "boolean"
          },
          "email_scan_complete": {
            "type": "boolean"
          },
          "email_finding_critical": {
            "type": "boolean"
          },
          "email_finding_high": {
            "type": "boolean"
          },
          "email_finding_medium": {
            "type": "boolean"
          },
          "email_finding_low": {
            "type": "boolean"
          },
          "email_weekly_digest": {
            "type": "boolean"
          },
          "email_security_alerts": {
            "type": "boolean"
          },
          "email_product_updates": {
            "type": "boolean"
          },
          "browser_enabled": {
            "type": "boolean"
          },
          "browser_scan_complete": {
            "type": "boolean"
          },
          "browser_findings": {
            "type": "boolean"
          },
          "slack_enabled": {
            "type": "boolean"
          },
          "slack_scan_complete": {
            "type": "boolean"
          },
          "slack_findings_critical": {
            "type": "boolean"
          },
          "sound_enabled": {
            "type": "boolean"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was malformed or failed a server-side check.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, invalid, expired or revoked credentials.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "status": 401,
                "message": "Authentication required",
                "code": "AUTH_1001",
                "request_id": "6c5d0c9e-0000-4000-8000-000000000000"
              }
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "The organization has no spendable credit, or its self-service spend cap is reached. Top up or raise the cap in the console. This status currently carries `message: \"Error\"` and `code: \"INTERNAL_9001\"`; rely on the HTTP status.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credential is valid but lacks a required scope or permission.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "status": 403,
                "message": "Access denied",
                "code": "AUTHZ_2001",
                "detail": "API key missing required scope: llm:access or llm:chat",
                "request_id": "6c5d0c9e-0000-4000-8000-000000000000"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource does not exist or is not visible to this caller.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "IdempotencyConflict": {
        "description": "This exact request (same `Idempotency-Key` and body) already ran, so it was not run again. Send a new `Idempotency-Key` to run it again.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "status": 409,
                "message": "Resource conflict",
                "code": "RESOURCE_3003",
                "detail": "This request was already received (same Idempotency-Key and body), so it was not run again. Send a new Idempotency-Key to run it again.",
                "request_id": "6c5d0c9e-0000-4000-8000-000000000000"
              }
            }
          }
        }
      },
      "ValidationFailed": {
        "description": "The request body or parameters failed schema validation.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "status": 422,
                "message": "Validation error",
                "code": "VALIDATION_4001",
                "detail": "Request validation failed. Check the errors array for details.",
                "errors": [
                  {
                    "field": "body -> temperature",
                    "message": "Input should be less than or equal to 2",
                    "type": "less_than_equal",
                    "constraints": {
                      "le": 2
                    }
                  }
                ],
                "request_id": "6c5d0c9e-0000-4000-8000-000000000000"
              }
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "A per-key request limit was exceeded, or the rate limiter could not be reached (it fails closed). There is no `Retry-After` for a window limit; wait for the next window. A concurrency limit, when configured, also returns `429`, with `Retry-After`.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "status": 429,
                "message": "Too many requests",
                "code": "RATE_5001",
                "detail": "Rate limit exceeded: <limit> requests/minute",
                "request_id": "6c5d0c9e-0000-4000-8000-000000000000"
              }
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "A dependency is temporarily unavailable. Retry with backoff; honour `Retry-After` when present.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "UserRateLimited": {
        "description": "A per-user limit was exceeded (the Platform API, embeddings or rerank). This response does not use the error envelope. Wait for `Retry-After` seconds.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "detail",
                "retry_after"
              ],
              "properties": {
                "detail": {
                  "type": "string"
                },
                "retry_after": {
                  "type": "integer",
                  "const": 60
                }
              }
            },
            "example": {
              "detail": "Too many requests. Please try again later.",
              "retry_after": 60
            }
          }
        }
      },
      "ChatUnavailable": {
        "description": "A dependency is temporarily unavailable, or a non-streaming completion finished without an answer. Retry with backoff and honour `Retry-After` when present. The empty-completion case uses an OpenAI-style error object without `status` or `request_id`.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "title": "Empty completion",
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "message",
                        "type",
                        "code"
                      ],
                      "properties": {
                        "message": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "const": "transient_timeout"
                        },
                        "code": {
                          "type": "string",
                          "enum": [
                            "empty_completion",
                            "reasoning_budget_exhausted"
                          ]
                        },
                        "recovery_exhausted": {
                          "type": "boolean",
                          "const": true
                        }
                      }
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "SlackNotConnected": {
        "description": "Slack is not connected for this organization. Connect it in the console under Settings, Integrations.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AnthropicError": {
        "description": "Anthropic error envelope with the same HTTP status. `Retry-After` and `X-Request-ID` are passed through, and `x-should-retry: false` is set when a retry cannot succeed (`402`, `409`). An over-long prompt starts its message with `prompt is too long` so clients that compact on overflow can recover.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "error"
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": [
                        "invalid_request_error",
                        "authentication_error",
                        "billing_error",
                        "permission_error",
                        "not_found_error",
                        "request_too_large",
                        "rate_limit_error",
                        "overloaded_error",
                        "api_error"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "example": {
              "type": "error",
              "error": {
                "type": "permission_error",
                "message": "API key missing required scope: llm:access or llm:chat"
              }
            }
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "LLM API",
      "tags": [
        "Chat",
        "Responses",
        "Messages",
        "Models",
        "Embeddings",
        "Rerank",
        "Batches"
      ]
    },
    {
      "name": "Platform API",
      "tags": [
        "API keys",
        "Usage",
        "Account",
        "Privacy",
        "Organizations",
        "Settings",
        "Integrations"
      ]
    }
  ]
}
