Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

客户端 HTTP API

本规范描述客户端与 ScootGate API listener 的当前 HTTP 契约。

通用要求

  • 传输:HTTP/1.1;生产环境使用 TLS 1.2+;
  • 每个 API listener 请求都必须鉴权,包括 /v1/models
  • POST 请求必须带唯一、有效的 Content-Length
  • JSON 请求体大小受 api.max_request_body_bytes 限制;
  • 每个响应使用 Connection: close
  • 未声明的路径返回 404,不存在管理 API。

鉴权

支持两种请求头:

Authorization: Bearer <scootgate-client-key>
x-api-key: <scootgate-client-key>

两者同时出现时,有效 Bearer 值优先。key 缺失、未知或已吊销时:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
Content-Type: application/json

{"status":"unauthorized"}

客户端 key 只用于 ScootGate 鉴权,不会转发给 Provider。

支持的端点

方法路径协议
POST/v1/chat/completionsOpenAI-compatible
POST/v1/messagesAnthropic Messages
GET/v1/modelsOpenAI-compatible 模型目录

路径存在但方法错误时返回:

{"status":"method_not_allowed"}

状态码为 405。

GET /v1/models

只列出已启用的 OpenAI-compatible 公共模型。Anthropic 模型、backend ID、 真实模型名和 Provider origin 不会出现。

响应示例:

{
  "object": "list",
  "data": [
    {
      "id": "chat-fast",
      "object": "model",
      "owned_by": "scootgate"
    }
  ]
}

POST /v1/chat/completions

请求体必须是 JSON object,并包含字符串 model

POST /v1/chat/completions HTTP/1.1
Authorization: Bearer demo-client-key
Content-Type: application/json
Content-Length: 67

{"model":"chat-fast","messages":[{"role":"user","content":"ping"}]}

ScootGate 选择 openai_compatible target,把公共 model 改写为真实模型名, 保留其他 JSON 字段,然后注入 backend credential。

stream: true 时要求 target 支持 stream,并透明转发 Provider SSE。

POST /v1/messages

请求体同样必须包含字符串 model

POST /v1/messages HTTP/1.1
x-api-key: demo-client-key
anthropic-version: 2023-06-01
Content-Type: application/json
Content-Length: 85

{"model":"claude-fast","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}

只选择 anthropic_messages target。anthropic-versionanthropic-beta 会转发给 Provider;客户端 x-api-key 会被 backend credential 替换。

能力过滤

ScootGate 从请求体推导所需能力:

请求字段所需能力
"stream": truesupports_stream
非空 tools(或非 array 值)supports_tools
response_format.type == "json_schema"supports_json_schema

模型存在但没有 target 同时满足能力时返回 400,不会出网。

请求头转发

客户端请求头采用 allowlist。只可能转发:

  • Content-Type
  • Accept
  • anthropic-version
  • anthropic-beta

ScootGate 重建 request line、Host、Provider 鉴权、Content-LengthConnection。客户端 Authorizationx-api-key、Host、代理头和其他 自定义头不会转发。

Provider 响应

除以下特殊处理外,ScootGate 转发 Provider 状态码、响应头和 body:

  • 移除 ConnectionKeep-AliveProxy-Connection, Proxy-AuthenticateTE
  • 添加 Connection: close
  • Provider 401/403 不原样返回:backend 被停用,客户端收到 502;
  • Provider 429 原样返回,并让 backend 进入短暂冷却;
  • SSE 按字节增量转发;客户端断开会关闭 Provider tunnel;
  • Provider body 超过 stream_idle_timeout_ms 无数据时结束 relay。

网关错误

通用错误 body

状态body场景
400{"status":"bad_request"}HTTP 头或 framing 不合法
401{"status":"unauthorized"}key 缺失/未知/吊销
404{"status":"not_found"}未知路径
405{"status":"method_not_allowed"}方法错误
411{"status":"length_required"}POST 缺少 Content-Length
413{"status":"payload_too_large"}请求体超过上限
502{"status":"bad_gateway"}出站、TLS、写入、响应头或 Provider 鉴权失败
503{"status":"not_ready"}snapshot 路由尚未加载
504{"status":"gateway_timeout"}响应头预算耗尽

OpenAI-shaped 模型错误

无效 JSON、缺少 model、未知模型、能力不支持或无 backend 时使用:

{
  "error": {
    "message": "model `missing` does not exist",
    "type": "not_found_error",
    "param": "model",
    "code": null
  }
}

未知模型为 404;无效请求/能力不足为 400;无可用 backend 为 503。

Anthropic-shaped 模型错误

{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "model `missing` does not exist"
  }
}

重试语义

ScootGate 不自动重试可能已到达 Provider 的请求。只有在能证明尚未发送 Provider 请求字节时,才可能在 max_pre_send_attempts 范围内改选其他 backend。客户端和外层代理也不应对这些 POST 请求进行无条件自动重试。