{
  "openapi": "3.1.0",
  "info": {
    "title": "Kyma API",
    "description": "LLM API gateway for open-source models. One endpoint, 16 models, multi-provider redundancy. OpenAI and Anthropic SDK compatible.",
    "version": "1.0.0",
    "contact": {
      "name": "Kyma API",
      "url": "https://kymaapi.com",
      "email": "support@kymaapi.com"
    },
    "termsOfService": "https://kymaapi.com/terms",
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://kymaapi.com/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "summary": "Create chat completion",
        "description": "Generate a chat response from a model. OpenAI-compatible format. Supports streaming, tool calling, structured outputs, and prompt caching.",
        "tags": ["Chat"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionResponse"
                }
              },
              "text/event-stream": {
                "description": "Server-sent events stream (when stream=true)"
              }
            },
            "headers": {
              "X-Kyma-Model": {
                "description": "Actual model used for this request",
                "schema": { "type": "string" }
              },
              "X-Kyma-Alias": {
                "description": "Alias that was resolved (if alias was used)",
                "schema": { "type": "string" }
              },
              "X-Kyma-Fallback": {
                "description": "Whether a fallback provider was used",
                "schema": { "type": "boolean" }
              },
              "X-Kyma-Fallback-Layer": {
                "description": "Fallback layer used (1=same model different provider, 3=different model)",
                "schema": { "type": "integer", "enum": [1, 2, 3] }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Create message (Anthropic format)",
        "description": "Generate a response using the Anthropic Messages API format. Same models and pricing as /chat/completions.",
        "tags": ["Chat"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnthropicMessageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message response in Anthropic format"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List all models",
        "description": "Returns all available models with pricing, capabilities, context windows, and recommendations. No authentication required.",
        "tags": ["Models"],
        "security": [],
        "parameters": [
          {
            "name": "recommended_for",
            "in": "query",
            "description": "Filter by recommended use case (comma-separated). Values: general, coding, reasoning, agent, vision, fast, cheap, long-context, math, multilingual, balanced, value, writing, bulk",
            "schema": { "type": "string" }
          },
          {
            "name": "tools",
            "in": "query",
            "description": "Filter to models supporting tool calling",
            "schema": { "type": "boolean" }
          },
          {
            "name": "vision",
            "in": "query",
            "description": "Filter to models supporting image input",
            "schema": { "type": "boolean" }
          },
          {
            "name": "reasoning",
            "in": "query",
            "description": "Filter to models with reasoning capabilities",
            "schema": { "type": "boolean" }
          },
          {
            "name": "structured_outputs",
            "in": "query",
            "description": "Filter to models supporting structured outputs / JSON mode",
            "schema": { "type": "boolean" }
          },
          {
            "name": "latency_tier",
            "in": "query",
            "description": "Filter by latency tier",
            "schema": { "type": "string", "enum": ["fast", "medium", "slow"] }
          },
          {
            "name": "cost_tier",
            "in": "query",
            "description": "Filter by cost tier",
            "schema": { "type": "string", "enum": ["cheap", "balanced", "premium"] }
          },
          {
            "name": "quality_tier",
            "in": "query",
            "description": "Filter by quality tier",
            "schema": { "type": "string", "enum": ["efficient", "strong", "frontier-open"] }
          },
          {
            "name": "min_context_window",
            "in": "query",
            "description": "Minimum context window size in tokens",
            "schema": { "type": "integer" }
          },
          {
            "name": "max_input_price",
            "in": "query",
            "description": "Maximum input price per 1M tokens",
            "schema": { "type": "number" }
          }
        ],
        "responses": {
          "200": {
            "description": "List of models",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            }
          }
        }
      }
    },
    "/models/recommend": {
      "get": {
        "operationId": "recommendModel",
        "summary": "Get model recommendation",
        "description": "Get a model recommendation by use case or specific agent. Returns config examples. No authentication required.",
        "tags": ["Models"],
        "security": [],
        "parameters": [
          {
            "name": "agent",
            "in": "query",
            "description": "Agent name for specific config. Supported: cline, roo-code, openclaw, claude-code, aider, opencode, cursor, kilo-code",
            "schema": { "type": "string" }
          },
          {
            "name": "usecase",
            "in": "query",
            "description": "Use case for recommendation. Values: coding, reasoning, general, agent, vision, long-context, cheap, fast",
            "schema": { "type": "string" }
          },
          {
            "name": "for",
            "in": "query",
            "description": "Alias for usecase parameter",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Model recommendation with config example"
          }
        }
      }
    },
    "/config": {
      "get": {
        "operationId": "getConfig",
        "summary": "Agent auto-configuration",
        "description": "Returns full auto-configuration for AI agents: base_url, format, streaming, default model, recommended models, full model list, endpoints, docs/MCP/dashboard links. No authentication required.",
        "tags": ["Discovery"],
        "security": [],
        "responses": {
          "200": {
            "description": "Agent configuration"
          }
        }
      }
    },
    "/capabilities": {
      "get": {
        "operationId": "getCapabilities",
        "summary": "Gateway capabilities",
        "description": "Returns AI-readable summary of gateway capabilities: limits, model count, reliability info, compatibility flags, pricing model. No authentication required.",
        "tags": ["Discovery"],
        "security": [],
        "responses": {
          "200": {
            "description": "Capabilities summary"
          }
        }
      }
    },
    "/credits/pricing": {
      "get": {
        "operationId": "getPricing",
        "summary": "Model pricing table",
        "description": "Returns per-model token pricing (input_per_1m, output_per_1m). No authentication required.",
        "tags": ["Discovery"],
        "security": [],
        "responses": {
          "200": {
            "description": "Pricing table"
          }
        }
      }
    },
    "/credits/balance": {
      "get": {
        "operationId": "getBalance",
        "summary": "Check credit balance",
        "description": "Returns current credit balance for the authenticated user.",
        "tags": ["Credits"],
        "responses": {
          "200": {
            "description": "Balance info"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/models/uptime": {
      "get": {
        "operationId": "getUptime",
        "summary": "Model uptime statistics",
        "description": "Returns 7-day per-model uptime percentages. No authentication required.",
        "tags": ["Discovery"],
        "security": [],
        "responses": {
          "200": {
            "description": "Uptime data"
          }
        }
      }
    },
    "/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Service status",
        "description": "Returns current service status. No authentication required.",
        "tags": ["Discovery"],
        "security": [],
        "responses": {
          "200": {
            "description": "Status info"
          }
        }
      }
    },
    "/auth/register": {
      "post": {
        "operationId": "register",
        "summary": "Create account",
        "description": "Create a new account and get an API key. Returns user_id, api_key (ky-), and session_token (ks-).",
        "tags": ["Auth"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "password": { "type": "string", "minLength": 6 }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user_id": { "type": "string" },
                    "api_key": { "type": "string", "description": "Starts with ky-" },
                    "session_token": { "type": "string", "description": "Starts with ks-" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "operationId": "login",
        "summary": "Login",
        "description": "Sign in and get a session token.",
        "tags": ["Auth"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "password": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful"
          }
        }
      }
    },
    "/auth/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Get current user",
        "description": "Get account info and API keys for the authenticated user.",
        "tags": ["Auth"],
        "responses": {
          "200": {
            "description": "User info"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/auth/keys": {
      "get": {
        "operationId": "listKeys",
        "summary": "List API keys",
        "description": "List all API keys for the authenticated user.",
        "tags": ["Auth"],
        "responses": {
          "200": {
            "description": "API keys list"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/auth/limits": {
      "get": {
        "operationId": "getLimits",
        "summary": "Check rate limits",
        "description": "Check your current tier, rate limits, and usage counters.",
        "tags": ["Auth"],
        "responses": {
          "200": {
            "description": "Rate limit info"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Kyma API key (starts with ky-) or session token (starts with ks-)"
      }
    },
    "schemas": {
      "ChatCompletionRequest": {
        "type": "object",
        "required": ["model", "messages"],
        "properties": {
          "model": {
            "type": "string",
            "description": "Model ID or alias. Aliases: best, fast, code, cheap, long-context, vision, reasoning, agent, balanced",
            "examples": ["qwen-3.6-plus", "best", "code"]
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "description": "Array of messages in the conversation"
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "default": 1,
            "description": "Sampling temperature. Lower = more focused, higher = more creative"
          },
          "max_tokens": {
            "type": "integer",
            "description": "Maximum tokens to generate. Default 4096. Forwarded directly to model with no gateway cap"
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Stream response as server-sent events"
          },
          "top_p": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "default": 1,
            "description": "Nucleus sampling parameter"
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "List of tools/functions the model can call. Supported on 15/16 models"
          },
          "response_format": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": ["text", "json_object"]
              }
            },
            "description": "Force output format. Use json_object for structured outputs"
          }
        }
      },
      "Message": {
        "type": "object",
        "required": ["role", "content"],
        "properties": {
          "role": {
            "type": "string",
            "enum": ["system", "user", "assistant", "tool"]
          },
          "content": {
            "oneOf": [
              { "type": "string" },
              {
                "type": "array",
                "items": { "type": "object" },
                "description": "Multimodal content (text + images)"
              }
            ]
          },
          "tool_calls": {
            "type": "array",
            "items": { "type": "object" },
            "description": "Tool calls made by the assistant"
          },
          "tool_call_id": {
            "type": "string",
            "description": "ID of the tool call this message is responding to"
          }
        }
      },
      "ChatCompletionResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "object": { "type": "string", "const": "chat.completion" },
          "created": { "type": "integer" },
          "model": { "type": "string", "description": "Actual model used" },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": { "type": "integer" },
                "message": { "$ref": "#/components/schemas/Message" },
                "finish_reason": {
                  "type": "string",
                  "enum": ["stop", "length", "tool_calls"]
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "prompt_tokens": { "type": "integer" },
              "completion_tokens": { "type": "integer" },
              "total_tokens": { "type": "integer" },
              "cached_tokens": { "type": "integer", "description": "Number of prompt tokens served from cache" },
              "cost": { "type": "number", "description": "Cost in USD for this request" },
              "cache_discount": { "type": "number", "description": "Amount saved from prompt caching in USD" }
            }
          }
        }
      },
      "AnthropicMessageRequest": {
        "type": "object",
        "required": ["model", "messages", "max_tokens"],
        "properties": {
          "model": { "type": "string" },
          "messages": {
            "type": "array",
            "items": { "type": "object" }
          },
          "max_tokens": { "type": "integer" },
          "system": { "type": "string" },
          "stream": { "type": "boolean" },
          "tools": {
            "type": "array",
            "items": { "type": "object" }
          }
        }
      },
      "ModelList": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "const": "list" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Model" }
          },
          "aliases": {
            "type": "object",
            "description": "Map of alias name to resolved model ID",
            "additionalProperties": { "type": "string" }
          }
        }
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "context_window": { "type": "integer" },
          "max_output_tokens": { "type": "integer" },
          "best_for": { "type": "string" },
          "speed": { "type": "string" },
          "recommended": { "type": "boolean" },
          "hot": { "type": "boolean" },
          "input_modalities": {
            "type": "array",
            "items": { "type": "string", "enum": ["text", "image", "audio", "video"] }
          },
          "output_modalities": {
            "type": "array",
            "items": { "type": "string", "enum": ["text", "audio", "image"] }
          },
          "supported_parameters": {
            "type": "array",
            "items": { "type": "string" }
          },
          "supports_tools": { "type": "boolean" },
          "supports_vision": { "type": "boolean" },
          "supports_reasoning": { "type": "boolean" },
          "supports_structured_outputs": { "type": "boolean" },
          "latency_tier": { "type": "string", "enum": ["fast", "medium", "slow"] },
          "cost_tier": { "type": "string", "enum": ["cheap", "balanced", "premium"] },
          "quality_tier": { "type": "string", "enum": ["efficient", "strong", "frontier-open"] },
          "release_stage": { "type": "string", "enum": ["stable", "preview", "limited"] },
          "recommended_for": {
            "type": "array",
            "items": { "type": "string" }
          },
          "pricing": {
            "type": "object",
            "properties": {
              "input_per_1m": { "type": "number" },
              "output_per_1m": { "type": "number" }
            }
          },
          "gateway_output_limit": {
            "type": "null",
            "description": "Always null. Kyma does not impose output limits"
          },
          "max_tokens_passthrough": {
            "type": "boolean",
            "const": true,
            "description": "Always true. max_tokens is forwarded directly to the model"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": { "type": "string" },
              "type": { "type": "string" }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      },
      "InsufficientCredits": {
        "description": "Insufficient credits",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "error": {
                "message": "Insufficient credits. Add credits at https://kymaapi.com/dashboard.",
                "type": "insufficient_credits"
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "Retry-After": {
            "description": "Seconds until the rate limit resets",
            "schema": { "type": "integer" }
          }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    }
  },
  "tags": [
    { "name": "Chat", "description": "Chat completion endpoints (OpenAI + Anthropic format)" },
    { "name": "Models", "description": "Model catalog, recommendations, and filtering" },
    { "name": "Discovery", "description": "Auto-configuration and capability discovery (no auth required)" },
    { "name": "Credits", "description": "Balance and pricing" },
    { "name": "Auth", "description": "Account management and API keys" }
  ]
}
