{
  "openapi": "3.1.0",
  "info": {
    "title": "Kourier.sh API",
    "version": "1.0.0",
    "summary": "OpenAI-compatible and Anthropic-compatible inference endpoints, plus authenticated feedback submissions.",
    "description": "Point any OpenAI-compatible client at https://api.kourier.sh/v1 with a Kourier API key sent as `Authorization: Bearer <key>`. Claude Code speaks the Anthropic-compatible surface at https://api.kourier.sh/anthropic (it appends `/v1/messages` itself). The live model string is `deepseek-v4.1-flash`. Paid plans carry no request-volume or token-usage quotas; enforcement is per-plan concurrency (HTTP 429 with `Retry-After` when the limit is reached). Human documentation: https://docs.kourier.sh/docs.",
    "contact": {
      "name": "Kourier.sh support",
      "url": "https://kourier.sh",
      "email": "support@kourier.sh"
    }
  },
  "servers": [
    {
      "url": "https://api.kourier.sh/v1",
      "description": "Production OpenAI-compatible surface"
    },
    {
      "url": "https://api.kourier.sh/anthropic",
      "description": "Production Anthropic-compatible surface for Claude Code"
    }
  ],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/api/feedback": {
      "post": {
        "servers": [{ "url": "https://kourier.sh" }],
        "summary": "Submit private feedback or an error report",
        "operationId": "submitFeedback",
        "description": "Account attribution comes from the bearer API key. Shares per-process limits with MCP: 60 attempts/minute per client and 20 submissions/hour per account. Complete request bodies must fit within 16 KiB of UTF-8. NUL bytes and extra fields are rejected. Do not include secrets or private data. Receipt may be ambiguous on 503; retrying can create duplicates.",
        "externalDocs": { "url": "https://docs.kourier.sh/docs/feedback" },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["kind", "message"],
                "additionalProperties": false,
                "properties": {
                  "kind": { "type": "string", "enum": ["feedback", "error"] },
                  "message": { "type": "string", "minLength": 1, "maxLength": 8000, "pattern": "^[^\\u0000]*$", "description": "Not blank after trimming." },
                  "request_id": { "type": "string", "minLength": 1, "maxLength": 200, "pattern": "^[^\\u0000]*$" },
                  "client_name": { "type": "string", "minLength": 1, "maxLength": 80, "pattern": "^[^\\u0000]*$" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Report saved privately.",
            "content": { "application/json": { "schema": {
              "type": "object",
              "required": ["id", "created_at"],
              "properties": {
                "id": { "type": "string", "format": "uuid" },
                "created_at": { "type": "string", "format": "date-time" }
              }
            } } }
          },
          "400": { "description": "Invalid JSON, UTF-8 or report fields. JSON body contains error and error_description." },
          "401": { "description": "Missing or unusable bearer key, or banned account. JSON body contains error and error_description; WWW-Authenticate: Bearer." },
          "413": { "description": "Body exceeds 16 KiB. JSON error: request_too_large." },
          "415": { "description": "Content-Type must be application/json. JSON error: unsupported_media_type." },
          "429": {
            "description": "Client or account limit reached. JSON body contains error, error_description and retry_after (seconds).",
            "headers": { "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until retry." } }
          },
          "503": { "description": "Receipt could not be confirmed. JSON error: service_unavailable. Do not retry automatically." }
        }
      }
    },
    "/chat/completions": {
      "post": {
        "servers": [{ "url": "https://api.kourier.sh/v1" }],
        "summary": "Create a chat completion",
        "description": "OpenAI Chat Completions API, including streaming via server-sent events. Set `model` to `deepseek-v4.1-flash`. Maximum context length is 262144 tokens for prompt plus output combined.",
        "operationId": "createChatCompletion",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["model", "messages"],
                "properties": {
                  "model": {
                    "type": "string",
                    "example": "deepseek-v4.1-flash"
                  },
                  "messages": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/ChatMessage" }
                  },
                  "stream": { "type": "boolean", "default": false },
                  "max_tokens": { "type": "integer" },
                  "temperature": { "type": "number" },
                  "tools": {
                    "type": "array",
                    "items": { "type": "object" }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion (object or SSE stream when `stream` is true)",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChatCompletionResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/responses": {
      "post": {
        "servers": [{ "url": "https://api.kourier.sh/v1" }],
        "summary": "Create a response (Responses API)",
        "description": "OpenAI Responses API, including streaming and tool calls. Required by Codex CLI pinned to `wire_api = \"responses\"`. Set `model` to `deepseek-v4.1-flash`.",
        "operationId": "createResponse",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["model", "input"],
                "properties": {
                  "model": {
                    "type": "string",
                    "example": "deepseek-v4.1-flash"
                  },
                  "input": {
                    "description": "Prompt text or array of input items",
                    "examples": ["Refactor this function to async/await."]
                  },
                  "stream": { "type": "boolean", "default": false },
                  "max_output_tokens": { "type": "integer" },
                  "tools": {
                    "type": "array",
                    "items": { "type": "object" }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Response object (or SSE stream when `stream` is true)"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/models": {
      "get": {
        "servers": [{ "url": "https://api.kourier.sh/v1" }],
        "summary": "List available models",
        "description": "OpenAI-shaped model list for the identity's granted model. Authenticated but never counts against concurrency.",
        "operationId": "listModels",
        "responses": {
          "200": {
            "description": "Model list",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ModelList" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "servers": [{ "url": "https://api.kourier.sh/anthropic" }],
        "summary": "Create an Anthropic message",
        "description": "Anthropic Messages API for Claude Code. Send the key as `Authorization: Bearer <key>` (or `x-api-key: <key>`). Pin both Claude Code model variables to `deepseek-v4.1-flash`.",
        "operationId": "createAnthropicMessage",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["model", "messages"],
                "properties": {
                  "model": {
                    "type": "string",
                    "example": "deepseek-v4.1-flash"
                  },
                  "messages": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/ChatMessage" }
                  },
                  "max_tokens": { "type": "integer" },
                  "stream": { "type": "boolean", "default": false },
                  "system": { "type": "string" },
                  "tools": {
                    "type": "array",
                    "items": { "type": "object" }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message object (or SSE stream when `stream` is true)"
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Kourier API key created in Dashboard → API Keys (shown once at creation)"
      }
    },
    "schemas": {
      "ChatMessage": {
        "type": "object",
        "required": ["role", "content"],
        "properties": {
          "role": {
            "type": "string",
            "enum": ["system", "user", "assistant", "tool"]
          },
          "content": {
            "type": "string"
          }
        }
      },
      "ChatCompletionResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "object": { "type": "string" },
          "created": { "type": "integer" },
          "model": { "type": "string" },
          "choices": {
            "type": "array",
            "items": { "type": "object" }
          },
          "usage": { "type": "object" }
        }
      },
      "ModelList": {
        "type": "object",
        "required": ["object", "data"],
        "properties": {
          "object": { "type": "string", "example": "list" },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string", "example": "deepseek-v4.1-flash" },
                "object": { "type": "string", "example": "model" }
              }
            }
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Invalid or missing API key"
      },
      "RateLimited": {
        "description": "Concurrency limit or request quota reached; honor the `Retry-After` response header"
      }
    }
  }
}
