{
  "openapi": "3.0.3",
  "info": {
    "title": "Wombat AI API",
    "version": "1.0.0",
    "description": "OpenAI-совместимый агрегатор GPT-5, Claude, Gemini, DeepSeek и других моделей. Биллинг в рублях через СБП/карты РФ.\n\nКлюч `sk-kvs-…` берётся в кабинете https://wombatai.app/miniapp/keys (нужна подписка Pro/Business).",
    "contact": {
      "name": "Поддержка Wombat AI",
      "email": "support@wombatai.app",
      "url": "https://wombatai.app/support"
    },
    "termsOfService": "https://wombatai.app/terms"
  },
  "servers": [
    {"url": "https://api.wombatai.app/v1", "description": "Production"}
  ],
  "security": [{"BearerApiKey": []}],
  "tags": [
    {"name": "Models", "description": "Перечень доступных моделей"},
    {"name": "Chat", "description": "Генерация чатовых ответов"}
  ],
  "paths": {
    "/models": {
      "get": {
        "tags": ["Models"],
        "summary": "Список моделей",
        "description": "Возвращает массив моделей, доступных через шлюз. Используйте `id` из ответа в поле `model` запросов chat/completions.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/ModelsList"},
                "example": {
                  "object": "list",
                  "data": [
                    {"id": "openai/gpt-5", "object": "model", "owned_by": "openai"},
                    {"id": "openai/gpt-4o-mini", "object": "model", "owned_by": "openai"}
                  ]
                }
              }
            }
          },
          "401": {"$ref": "#/components/responses/Unauthorized"}
        }
      }
    },
    "/chat/completions": {
      "post": {
        "tags": ["Chat"],
        "summary": "Создать ответ модели",
        "description": "Главный эндпоинт. Принимает OpenAI-совместимый payload. Поддерживается мультимодальный content (массив text + image_url) на vision-моделях.",
        "parameters": [
          {
            "in": "header",
            "name": "X-Request-Id",
            "required": false,
            "schema": {"type": "string", "maxLength": 64},
            "description": "Идемпотентный ключ. Повторный запрос с тем же ID в течение 10 мин не дублирует биллинг и возвращает закешированный ответ."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {"$ref": "#/components/schemas/ChatCompletionRequest"},
              "examples": {
                "simple": {
                  "summary": "Простой текстовый запрос",
                  "value": {
                    "model": "openai/gpt-4o-mini",
                    "messages": [
                      {"role": "system", "content": "Отвечай по-русски."},
                      {"role": "user", "content": "Привет!"}
                    ],
                    "max_tokens": 100
                  }
                },
                "vision": {
                  "summary": "С картинкой (vision-модель)",
                  "value": {
                    "model": "openai/gpt-4o",
                    "messages": [{
                      "role": "user",
                      "content": [
                        {"type": "text", "text": "Что на картинке?"},
                        {"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}
                      ]
                    }],
                    "max_tokens": 200
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/ChatCompletionResponse"}
              }
            }
          },
          "400": {"$ref": "#/components/responses/BadRequest"},
          "401": {"$ref": "#/components/responses/Unauthorized"},
          "402": {"$ref": "#/components/responses/InsufficientQuota"},
          "422": {"$ref": "#/components/responses/Unprocessable"},
          "429": {"$ref": "#/components/responses/RateLimited"},
          "502": {"$ref": "#/components/responses/Upstream"}
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk-kvs-…",
        "description": "API-ключ из кабинета. Заголовок: Authorization: Bearer sk-kvs-..."
      }
    },
    "schemas": {
      "Model": {
        "type": "object",
        "properties": {
          "id": {"type": "string", "example": "openai/gpt-4o-mini"},
          "object": {"type": "string", "enum": ["model"]},
          "owned_by": {"type": "string", "example": "openai"}
        }
      },
      "ModelsList": {
        "type": "object",
        "properties": {
          "object": {"type": "string", "enum": ["list"]},
          "data": {"type": "array", "items": {"$ref": "#/components/schemas/Model"}}
        }
      },
      "Message": {
        "type": "object",
        "required": ["role", "content"],
        "properties": {
          "role": {"type": "string", "enum": ["system", "user", "assistant"]},
          "content": {
            "oneOf": [
              {"type": "string", "maxLength": 30000},
              {
                "type": "array",
                "items": {"$ref": "#/components/schemas/ContentPart"},
                "minItems": 1, "maxItems": 20
              }
            ]
          }
        }
      },
      "ContentPart": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {"type": "string", "enum": ["text"]},
              "text": {"type": "string", "maxLength": 30000}
            },
            "required": ["type", "text"]
          },
          {
            "type": "object",
            "properties": {
              "type": {"type": "string", "enum": ["image_url"]},
              "image_url": {
                "type": "object",
                "properties": {
                  "url": {"type": "string", "description": "data:image/...;base64,... ИЛИ https://..."},
                  "detail": {"type": "string", "enum": ["auto", "low", "high"], "default": "auto"}
                },
                "required": ["url"]
              }
            },
            "required": ["type", "image_url"]
          }
        ]
      },
      "ChatCompletionRequest": {
        "type": "object",
        "required": ["model", "messages"],
        "properties": {
          "model": {"type": "string", "description": "provider/model, например openai/gpt-4o-mini"},
          "messages": {
            "type": "array",
            "items": {"$ref": "#/components/schemas/Message"},
            "minItems": 1, "maxItems": 50
          },
          "max_tokens": {"type": "integer", "minimum": 1, "maximum": 16384, "default": 2048},
          "temperature": {"type": "number", "minimum": 0, "maximum": 2, "default": 1.0},
          "top_p": {"type": "number", "minimum": 0, "maximum": 1},
          "stream": {"type": "boolean", "default": false},
          "response_format": {
            "type": "object",
            "properties": {"type": {"type": "string", "enum": ["text", "json_object"]}}
          },
          "tools": {"type": "array", "items": {"type": "object"}}
        }
      },
      "ChatCompletionResponse": {
        "type": "object",
        "properties": {
          "id": {"type": "string"},
          "object": {"type": "string", "enum": ["chat.completion"]},
          "created": {"type": "integer"},
          "model": {"type": "string"},
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {"type": "integer"},
                "message": {
                  "type": "object",
                  "properties": {
                    "role": {"type": "string", "enum": ["assistant"]},
                    "content": {"type": "string"}
                  }
                },
                "finish_reason": {"type": "string"}
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": {"type": "integer"},
              "completion_tokens": {"type": "integer"},
              "total_tokens": {"type": "integer"}
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {"type": "string"},
              "type": {"type": "string"}
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Невалидный запрос или модель не из /v1/models",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      },
      "Unauthorized": {
        "description": "Нет/неверный/отозванный API-ключ",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      },
      "InsufficientQuota": {
        "description": "Недостаточно кредитов на балансе",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      },
      "Unprocessable": {
        "description": "Картинка слишком большая, vision-only-модель, и т.п.",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      },
      "RateLimited": {
        "description": "Превышен RPM",
        "headers": {
          "x-ratelimit-limit": {"schema": {"type": "integer"}},
          "x-ratelimit-remaining": {"schema": {"type": "integer"}},
          "x-ratelimit-reset": {"schema": {"type": "integer", "description": "сек до сброса окна"}}
        },
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      },
      "Upstream": {
        "description": "Апстрим-провайдер вернул ошибку",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      }
    }
  }
}
