{
  "openapi": "3.0.3",
  "info": {
    "title": "JustCode API",
    "version": "2026-11-01",
    "description": "Шлюз доступа к языковым моделям (Claude, GPT, Gemini, Grok, эмбеддинги). Совместим с Anthropic Messages API и OpenAI Chat Completions API одновременно: оба протокола работают на одном адресе и одном ключе.",
    "contact": {
      "url": "https://justcode.lol"
    }
  },
  "servers": [
    {
      "url": "https://api.justcode.lol/v1"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "AnthropicMessage": {
        "type": "object",
        "required": [
          "model",
          "messages",
          "max_tokens"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "claude-opus-5.5",
              "claude-opus-5",
              "claude-opus-4.8",
              "claude-opus-4.7",
              "claude-opus-4.6",
              "claude-opus-4.5",
              "claude-sonnet-5.5",
              "claude-sonnet-5",
              "claude-sonnet-4.6",
              "claude-sonnet-4.5",
              "claude-sonnet-4",
              "claude-haiku-4.5",
              "claude-fable-5-1",
              "claude-fable-5",
              "gpt-6.1-sol",
              "gpt-6-sol",
              "gpt-6-astra",
              "gpt-5.6-sol",
              "gpt-5.6-terra",
              "gemini-3-flash",
              "grok-4.5",
              "gemini-3.1-pro-preview",
              "grok-4.7",
              "glm-5.3",
              "glm-5.3-flash",
              "qwen3.8-max",
              "qwen3.8-flash",
              "kimi-k3",
              "deepseek-v4-pro",
              "deepseek-v4.1-flash",
              "gemini-3.1-flash-lite"
            ]
          },
          "max_tokens": {
            "type": "integer"
          },
          "system": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "stream": {
            "type": "boolean"
          },
          "temperature": {
            "type": "number"
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "ChatCompletion": {
        "type": "object",
        "required": [
          "model",
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "claude-opus-5.5",
              "claude-opus-5",
              "claude-opus-4.8",
              "claude-opus-4.7",
              "claude-opus-4.6",
              "claude-opus-4.5",
              "claude-sonnet-5.5",
              "claude-sonnet-5",
              "claude-sonnet-4.6",
              "claude-sonnet-4.5",
              "claude-sonnet-4",
              "claude-haiku-4.5",
              "claude-fable-5-1",
              "claude-fable-5",
              "gpt-6.1-sol",
              "gpt-6-sol",
              "gpt-6-astra",
              "gpt-5.6-sol",
              "gpt-5.6-terra",
              "gemini-3-flash",
              "grok-4.5",
              "gemini-3.1-pro-preview",
              "grok-4.7",
              "glm-5.3",
              "glm-5.3-flash",
              "qwen3.8-max",
              "qwen3.8-flash",
              "kimi-k3",
              "deepseek-v4-pro",
              "deepseek-v4.1-flash",
              "gemini-3.1-flash-lite"
            ]
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "max_tokens": {
            "type": "integer"
          },
          "stream": {
            "type": "boolean"
          },
          "temperature": {
            "type": "number"
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "EmbeddingRequest": {
        "type": "object",
        "required": [
          "model",
          "input"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "jc-embed-multilingual",
              "text-embedding-3-small",
              "text-embedding-3-large",
              "text-embedding-ada-002",
              "text-embedding-004",
              "gemini-embedding-001"
            ]
          },
          "input": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          }
        }
      }
    }
  },
  "paths": {
    "/messages": {
      "post": {
        "summary": "Anthropic Messages API",
        "description": "Диалог в формате Anthropic. Поддерживает потоковую передачу, инструменты, изображения и кэш промпта.",
        "security": [
          {
            "ApiKeyAuth": [],
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnthropicMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ответ модели"
          },
          "400": {
            "description": "Некорректный запрос или превышено окно"
          },
          "401": {
            "description": "Ключ не принят"
          },
          "402": {
            "description": "Недостаточно средств"
          }
        }
      }
    },
    "/chat/completions": {
      "post": {
        "summary": "OpenAI Chat Completions API",
        "description": "Диалог в формате OpenAI. Доступны все модели, включая Claude.",
        "security": [
          {
            "ApiKeyAuth": [],
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletion"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ответ модели"
          }
        }
      }
    },
    "/responses": {
      "post": {
        "summary": "OpenAI Responses API",
        "description": "Формат Responses, им работает Codex CLI.",
        "security": [
          {
            "ApiKeyAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Ответ модели"
          }
        }
      }
    },
    "/embeddings": {
      "post": {
        "summary": "Векторные представления текста",
        "description": "Формат OpenAI. Размерность вектора 384, до 256 текстов за запрос.",
        "security": [
          {
            "ApiKeyAuth": [],
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Список векторов"
          }
        }
      }
    },
    "/models": {
      "get": {
        "summary": "Каталог моделей",
        "description": "Доступные модели с размерами окон контекста.",
        "security": [
          {
            "ApiKeyAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Список моделей"
          }
        }
      }
    },
    "/messages/count_tokens": {
      "post": {
        "summary": "Оценка размера запроса",
        "description": "Считает токены локально, деньги не списываются.",
        "security": [
          {
            "ApiKeyAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Количество токенов"
          }
        }
      }
    }
  }
}