参考

HTTP API

统一 `/v1/*` 路由下的鉴权边界、请求方式和返回形态。

如果你已经在用 SDK,通常不需要手写 HTTP 请求。

路由规则

所有 Action 自动映射为 HTTP 路由:

动作                     URL
────                     ───
普通 action              POST /v1/{service}/{action}
GET action               GET  /v1/{service}/{action}
Admin action             POST /v1/{service}/{action}
Admin GET                GET  /v1/{service}/{action}

产品侧路由

路由方法用途
/v1/ai/textPOST文本生成(SDK 通路)
/v1/ai/streamPOST流式生成(SDK 通路)
/v1/ai/imagePOST图片生成
/v1/ai/videoPOST视频生成
/v1/ai/chat/completionsPOSTOpenAI 兼容端点
/v1/ai/modelsGET按身份返回模型目录
/v1/accounts/loginPOSTAccounts 登录
/v1/accounts/oauth/startPOST发起 OAuth
/v1/accounts/oauth/resultGET轮询 OAuth 结果
/v1/accounts/oauth/callbackGET第三方 OAuth 回调入口
/v1/{service}/{action}POST通用 Action 调用
/v1/servicesGETService 列表

/v1/accounts/oauth/callback 是给 GitHub / Google 这类第三方 OAuth 平台回跳用的固定地址。产品前端通常不直接调用它。

管理端常用路由

路由方法用途
/v1/towns/listGETTown 列表
/v1/towns/createPOST创建 Town
/v1/towns/pausePOST暂停 Town
/v1/towns/activatePOST启用 Town
/v1/towns/removePOST删除 Town
/v1/towns/tokens/applyPOST签发 user_token
/v1/env/listGET环境变量列表
/v1/env/upsertPOST写入环境变量
/v1/env/removePOST删除环境变量
/v1/env/importPOST批量导入 .env
同一条 /v1/{service}/{action} 路由会根据 bearer 凭证决定身份:
  • 不带 token:guest
  • user_tokenuser
  • admin_secret_keyadmin

Action 自己声明允许哪些身份访问。默认是 ["user"];传 [] 表示免登录。

产品侧请求格式

认证头

Authorization: Bearer <user_token>
Content-Type: application/json

同一个 /v1/ai/models

  • user_token 访问时,只返回当前可调用模型
  • admin_secret_key 访问时,返回全部代码注册模型,并附带 env_requirements

GET /v1/ai/models

user_token 示例:

{
  "items": [
    {
      "id": "deepseek-v4-flash",
      "name": "DeepSeek V4 Flash",
      "description": "DeepSeek text model",
      "modalities": ["text", "stream"],
      "tags": ["deepseek", "text"],
      "meta": {}
    }
  ]
}

admin_secret_key 示例:

{
  "items": [
    {
      "id": "deepseek-v4-flash",
      "name": "DeepSeek V4 Flash",
      "description": "",
      "modalities": ["text", "stream", "openai"],
      "tags": ["deepseek", "text"],
      "meta": {},
      "env_requirements": [
        {
          "key": "DEEPSEEK_API_KEY",
          "description": "deepseek API Key",
          "required": true
        }
      ],
      "default_modes": ["text", "stream", "openai"]
    }
  ]
}

POST /v1/ai/text

请求(SDK 通路):

{
  "town_id": "town_xxx",
  "model": "deepseek-v4-flash",
  "prompt": "写一段欢迎语"
}

返回:

{
  "id": "msg_xxx",
  "role": "assistant",
  "parts": [
    { "type": "text", "text": "欢迎使用 Downcity" }
  ]
}

POST /v1/ai/stream

请求体和 text 类似。返回值是 AI SDK UIMessage 流式响应(SSE)。

POST /v1/ai/chat/completions

OpenAI 兼容端点。接收标准 OpenAI chat/completions 格式:

{
  "model": "deepseek-v4-flash",
  "messages": [{ "role": "user", "content": "写一段欢迎语" }],
  "stream": true
}

返回 SSE 流:

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"欢迎"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{...}}
data: [DONE]

直接用 OpenAI SDK:

const openai = new OpenAI({
  baseURL: "http://127.0.0.1:43127/v1/ai",
  apiKey: "ub_xxx",
});
await openai.chat.completions.create({
  model: "kimi-k2.6",
  messages: [{ role: "user", content: "你好" }],
  stream: true,
});

GET /v1/services

{
  "items": [
    { "id": "ai", "name": "AI", "env": [] },
    { "id": "accounts", "name": "Accounts", "env": [] }
  ]
}

env 用于暴露该 service 声明的运行时环境变量需求,便于管理端或调试界面展示依赖项。

POST /v1/{service}/{action}

{ "text": "你好" }

管理端请求格式

认证头

Authorization: Bearer <admin_secret_key>
Content-Type: application/json

POST /v1/towns/create

{ "name": "Chrome Extension" }
{ "town_id": "town_xxx", "name": "Chrome Extension", "status": "active", ... }

POST /v1/towns/tokens/apply

{
  "town_id": "town_xxx",
  "user_id": "user_123",
  "metadata": { "plan": "pro" },
  "ttl": "7d"
}
{ "user_token": "ub_xxx", "town_id": "town_xxx", "user_id": "user_123", ... }

POST /v1/env/upsert

{ "key": "DEEPSEEK_API_KEY", "value": "sk-xxx" }

常见状态码

状态码什么时候返回
200请求成功
401token 缺失、过期、签名无效
403town_id 不匹配、town 已暂停
404路由不存在、service 未注册
422model 不存在、action 未命中
500action 逻辑抛出未指定 statusCode 的错误