一个端点,
所有模型。
Tare 是挡在你所有模型前面的一层 OpenAI 兼容网关 —— 我们的,和你自己带来的。一个 base URL、一把 key,每一个 token 都算得清。
接口列表
Base URL:https://tare.jamerly.ai
模型流量
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /v1/chat/completions | 模型调用。OpenAI 形状,支持流式 |
| POST | /v1/embeddings | 文本转向量。OpenAI 形状,无流式 |
| POST | /v1/images | 图片生成。无流式 |
| POST | /v1/images/generations | 同一接口的兼容路径 |
| GET | /v1/models | 本账号可用的模型与价格 |
| GET | /v1/generation?id=gen-… | 事后查询单次调用的成本 |
不支持的接口
模型流量只有上面六条,以下接口不存在,请求返回 404:
| 路径 | 状态 |
|---|---|
/v1/images/edits、/v1/images/variations | 不提供 |
/v1/audio/*(转写、TTS) | 不提供 |
/v1/completions(旧式 text completion) | 不提供,请用 /v1/chat/completions |
/v1/credits | 不提供;余额读 对账 API 的 /v1/integration/balance |
POST /v1/embeddings:文本转向量
OpenAI 形状。请求体原样透传,回包是上游原文加一格 usage.cost:
{"model":"text-embedding-3-small","input":"hello"}
与 chat 的三点不同:
- ⚠️ 模型名不做映射。 chat 填写的是平台侧模型名(
GET /v1/models的id), 这里写的是上游自己的名字。embeddings 不走模型路由表,没有那层映射,回包里的模型名 同样不改写。 - ⚠️ 渠道要显式配过才做 embeddings。 在 Channels 页给这条渠道填上 embeddings 地址,才表示它提供这个接口;留空即不提供。平台不按方言推断 —— 「chat 接口是 OpenAI 形状」和「有 embeddings 接口」是两件事,大量中转、聚合网关与自建推理服务 只提供 chat,推断出的地址在它们那里并不存在。
- 候选顺序:自己的渠道优先,平台渠道兜底。 你自己配过 embeddings 地址的渠道 按渠道 id 升序全部作为候选;一条都没配时,才轮到平台渠道被指定服务 embeddings 的那条。
- 自有渠道之间会故障转移。 配了几条就依次试几条,第一条打不通自动换下一条, 转移痕迹在调用详情里逐条可见。
- ⚠️ 不会从自有渠道转到平台渠道。 二者计费不同:自己的渠道只记账不扣钱,平台渠道 按售价扣余额。静默回退等于在未经同意的情况下开始扣费,而表现只是「调用成功了」。 自有渠道全部不可用时直接报错,不替换成平台的。
- ⚠️ 平台渠道上未定价的模型会被拒绝,而不是免费提供。 平台渠道的 token 由平台向上游 购买,价目表缺这一行时定价会算成 0 —— 与其静默地免费服务,不如明确失败。 这种情况返回 404 并说明原因;改用自己的渠道,或联系我们为该模型定价。
无流式。gen- 编号照常走响应头,/v1/generation 可回查。
[!NOTE]
⚠️ embedding 模型不会出现在 GET /v1/models 里。 那份目录来自上游的模型目录,
而上游的目录里就没有 embedding 模型(实测:421 个模型,0 个)。模型名请按上游文档填写,
不能从平台目录中选取。
[!NOTE] 向量化的调用和 chat 走同一个留存开关。 开关打开时,请求正文与 上游回包一并留存,在调用详情里可以展开查 看;关闭时一个字节都不落库。
⚠️ 此前这条端点无论开关如何都不留存,理由是「输入常常是整篇文档」。代价是它在调用详情 里什么都看不到 —— 一次成功的向量化调用和一次没跑完的记录长得一模一样。留不留存 现在由你决定,而不是由端点类型决定。
POST /v1/images:图片生成
{"model":"google/gemini-3-pro-image","prompt":"a red fox in the snow"}
请求
| 字段 | |
|---|---|
model | 必填。 你在 Routing 页配过的模型,或平台默认模型 |
prompt | 必填。 图片描述 |
| 其余字段 | 原样转发给上游 —— size、aspect_ratio、n、input_references、以及各家自己的参数。具体支持哪些取决于模型;传入上游不支持的字段时,返回的是上游的报错,而非平台的报错 |
POST /v1/images/generations 是同一个接口 —— 请求和回包完全一样。
回包
{
"id": "gen-c9d21c16eec04f968fc9bbcd08e140f9",
"created": 1787820572,
"model": "google/gemini-3-pro-image",
"data": [
{
"b64_json": "iVBORw0KGgo…",
"media_type": "image/png",
"url": "https://s.jamerly.ai/img/36/b21a5d9fa79b4135993282e1baf34999.png",
"expires_at": 1787906972
}
],
"usage": {"prompt_tokens": 7, "completion_tokens": 4175, "total_tokens": 4182, "cost": 0.000900}
}
| 字段 | |
|---|---|
id | 这次调用的编号,和响应头 X-Generation-Id 是同一个值,可用它查 /v1/generation |
model | 请求中使用的模型名,而非上游的模型名 |
data[].b64_json | 图片字节,base64。该字段长期有效 |
data[].media_type | image/png、image/jpeg … |
data[].url | 同一份字节的托管地址。⚠️ 调用后 24 小时失效 |
data[].expires_at | Unix 秒,该 URL 的失效时刻,以此为准 |
text | 模型在图片之外返回的文本。为空时不返回该字段。 标准 images 回包没有承载文本的字段,因此这是平台新增的字段,标准字段不作改动 |
finish_reason | 上游的结束原因。⚠️ data 为空时首先读该字段 —— content_filter 表示上游已生成图片,但被其自身内容策略拦截 |
usage | token 数,以及 cost = 本次调用的成本。图片按 token 计费,因此 completion_tokens 会很大 |
[!WARNING]
data可能是空数组,而这不是错误。 上游正常返回、只是没给图 —— 比如模型这次 只返回了文字,或图片被上游的内容策略拦截。平台<b>不会将其判定为失败</b>: HTTP 状态码仍为 200,具体原因见finish_reason与text字段。
[!WARNING] 不要将
url持久化到数据库。 该链接次日即失效,且失效前与永久链接无法区分。 需要留存时请保存b64_json,或将字节转存至自有存储。 该 URL 的用途是向其他系统传递图片时避免传输数 MB 的字节。
行为
- 按模型路由,和
/v1/chat/completions一样:你在 Routing 页把google/gemini-3-pro-image指到哪条渠道,这次调用就走哪条。出图模型之间价差一个 数量级以上,模型选择对成本影响显著。 - ⚠️ 没有故障转移。 渠道失败时直接返回该错误,平台不会静默切换到另一条重试。 第二条候选的计费方式可能不同,回退等于在未经选择的渠道上产生费用 —— 单张图片的成本以分计,而不是几个 token。
- 计费、限额、调用留痕与 chat 完全一致:同样先过余额 / 预算 / 子 Key 额度三道检查, 同样落入调用详情(含提示词),计费口径一致。不同接口不使用不同的记账口径。
- 不支持流式。
在 chat 调用里出图:modalities
该方式同样支持:在 /v1/chat/completions 上传入 modalities,图片位于回包的
message.images 中。同一次调用需同时返回文字与图片时使用该方式;仅需图片时使用
/v1/images。
{"model":"…","messages":[{"role":"user","content":"a red fox"}],
"modalities":["image","text"]}
请求体原样透传,回包是上游原文(只改写 model 和 id)。三点需要注意:
- ⚠️ 路由只看输入模态,不看请求的输出模态。 一个模型名下挂多条候选、只有部分能出图 时,故障转移可能落到出不了图的那条上,表现为「同样的请求有时出图有时只出文字」。 在配置上规避:给出图的模型单独一个模型名,或只给它配一条渠道。按输出模态挑候选 已在排期。
- 计价按 token 与上游自报成本。
GET /v1/models的pricing.image恒为 0,不代表 免费(没有「 每张图」这一档)。单次图片成本读回包的usage.cost。 - 图片以 base64 还是 URL 返回由上游决定,平台不做改写。
请求头
⚠️ 未识别的请求头一律忽略:不会因此拒绝请求,也不会转发给上游。 发往上游的请求头由
平台重建(凭据、Content-Type、方言要求的若干头),客户端携带的请求头不会出现在
上游一侧。
归因头 HTTP-Referer / X-Title 属于这一类:携带无副作用(不影响路由、计费、
限流),但不会到达上游。归因请使用以下两种方式:
| 需求 | 方式 |
|---|---|
| 标记调用所属业务 | 请求体里的 usage_label,原样落进用量记录 |
| 标记调用所属终端用户 | 为该用户单独创建子钥,见 母钥 |
[!NOTE] 未开启 CORS。 从浏览器直连时这两个自定义头会在预检阶段被浏览器拦下,请求根本没有 发出。服务端调用不受影响,也建议始终从服务端调用:推理 key 放进浏览器等于公开它。
gen- 编号
每次调用返回一个 gen-xxxxx,由平台生成,而非上游生成。用于查询成本,也可作为
你侧记账的幂等键。
前缀是硬要求:不少客户端用 id.startsWith("gen-") 判断调用是否有编号,
换前缀会让该判断失败,对账链路空转。
Key 管理(母钥)
供平台型客户给终端用户签发子钥,凭母钥调用,不依赖登录态。见 母钥。
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /v1/keys | 创建子钥(带 external_id 时幂等) |
| GET | /v1/keys | 列出名下子钥,游标分页,含已停用 |
| GET | /v1/keys/{hash} | 查询子钥的额度与用量 |
| PATCH | /v1/keys/{hash} | 改额度 / 停用 / 改名 |
| GET | /v1/keys/external/{externalId} | 同上,按外部编号定位 |
| PATCH | /v1/keys/external/{externalId} | 同上,按外部编号定位 |
控制台与对账
控制台(渠道、路由、账单、告警)是另一套界面,用登录态。机器对机器的对账有专门的、按 key 鉴权的接口,见 对账 API。
[!NOTE] 三类 key 权限互不重叠:推理 key 只能调模型,对账 key 只能读报表,母钥只能管 key。 用错类型返回的是明确的拒绝,不是含糊的 401。
GET /v1/models:字段与口径
[!NOTE] 带上你的推理 key,目录里就包含你自己配的模型:你在自己渠道上配的那些 ∪ 平台的那些, 同名时以你自己那条为准 —— 和真正调用时的路由口径完全一致。 不带 key 拿到的是平台目录(这条路一直保留,客户端可以不带任何请求头拉目录)。
推理 key 和母钥都可以。 母钥没有绑 Router,它拿到的是账号默认那套路由的目录; 要查看某一把绑定了其他 Router 的子钥可用哪些模型,请使用该子钥调用。
⚠️ 携带了 key 但无效或已 过期时返回 401(不会静默返回一份缺少自有模型的目录); 对账 key 返回 403 —— 对账 key 无权访问模型相关接口。
⚠️ 你自己渠道上的模型,pricing.prompt / completion 是 0:那些 token
由你直接支付给上游,不经平台价目表。真实成本读回包的 usage.cost。
{"data":[{"id":"GLM 5.1","name":"GLM 5.1","description":"…","context_length":128000,
"architecture":{"modality":"text->text","input_modalities":["text"],"output_modalities":["text"]},
"reasoning":{"mandatory":false,"default_enabled":true,
"supported_efforts":["low","medium","high"],"default_effort":"medium"},
"pricing":{"prompt":"0.0000006","completion":"0.0000022",
"input_cache_read":"0.00000006","input_cache_write":"0.00000075",
"request":"0","image":"0"}}]}
| 字段 | 口径 |
|---|---|
id | 平台侧模型名,用它发起调用 |
pricing.prompt / completion | 每 token(不是每百万),字符串 |
pricing.input_cache_read / input_cache_write | 缓存两档,同样每 token |
pricing.request / image | 恒为 0,见下方警告 |
| 币种 | 美元,暂不提供其他币种换算 |
description | 上游目录的模型说明;不可用时该字段不出现 |
context_length | 来自上游目录;不可用时该字段不出现(不要当成 0) |
architecture | 来自上游目录;不可用时兜底为纯文本 ["text"] |
reasoning | 思考能力,来自上游目录;不可用时该字段不出现,不给默认值 |
⚠️ pricing.image 恒为 0,但图片不是免费的。价目表只有 token 四档(输入 / 输出 /
缓存读 / 缓存写),没有「每张图」这一档;带图的调用按上游报的 token 与成本计价。
不要用这个字段估算图片成本,读回包的 usage.cost。
reasoning:思考能力
{"mandatory":false,"default_enabled":true,
"supported_efforts":["low","medium","high"],"default_effort":"medium"}
用于决定是否展示「思考强度」选择器、展示哪几档:
supported_efforts的取值由上游决定,不限于这三档(部分上游还提供minimal/xhigh/none)。按字段渲染,不要在客户端写死。mandatory: true表示无法关闭,此时不要渲染开关。- ⚠️
reasoning缺席表示未知,不表示「不支持思考」。 自建和本地模型没有目录条目, 该字段就会缺失;把缺席当成不支持会让这些模型的选择器消失。这里不做兜底:编造默认值 等于代替上游做出未经确认的承诺,用户选了上游不认的强度会收到 400,看起来像模型故障。
⚠️ 目前没有单独的工具调用能力标记,无法从这份目录判断模型是否支持工具调用。
usage.cost:这次调用的成本
单位美元:
- 平台模型:等于平台售价;
- BYOK:上游进价 + 服务费。BYOK 的 token 你直接付给供应商,这里给 0 会让成本报表 显示本月免费用掉了几百万 token。
- ⚠️ 无法计算时该字段不出现,而不是 0:一个假的 0 会被当真。
「这个模型还没定价」也算无法计算,因此出现的
0是真的 0。 - ⚠️ 流式的末帧同样带
cost(末帧才有 usage)。 - 上游在回包里自报成本的渠道以自报值为准,不录进价也能拿到。
- ⚠️ 平台模型的回包里没有
usage.cost_details:该字段是上游向平台收取的费用。 BYOK 下保留 —— 该数值来自你自己的上游账单,正是成本归因所需。GET /v1/generation的upstream_inference_cost同理,仅 BYOK 调用具备该字段。
⚠️ architecture 是上游目录的原样透传,自建和本地模型没有目录条目,会兜底成纯文本。
按 input_modalities 含 image 过滤模型时,这类模型会被前端筛掉。
GET /v1/generation?id=:数据何时可查
数据来自用量记录,而用量记录在响应之后才写入,因此拿到编号立刻查询会 404。
⚠️ 404 有两种含义且目前同码:尚未写入(应重试)和不属于你的调用(应放弃)。用时间 区分:收到编号后 60 秒内的 404 一律视为尚未写入,超过则视为后者。不区分是刻意的, 区分等于提供一个「这个编号是否存在」的探测接口。
- 非流式:响应返回后通常 1 秒内可查。
- 流式:末帧之后写入,以流结束为准。
- 404 是正常路径,按「稍后再试」处理,退避几秒重试。
- ⚠️ 中途断开的流式调用,成本需事后向上游回查补记,最长可能到分钟级。
流式:强制打开 stream_options.include_usage
没有 usage 即无法计费,因此该项覆盖请求中的设置(stream_options 整块被替换)。
由此产生的形状差异:
| 上游方言 | 末帧形状 |
|---|---|
| OpenAI 兼容 | 上游末帧原样透传:choices 为空数组,带 usage |
| Anthropic | 由平台翻译:choices 有一项、delta 为空、带 finish_reason 和 usage |
⚠️ 两种方言的末帧形状不一致。 前端按帧渲染时,判据写成「choices 为空或
delta 无内容 → 跳过渲染,只取 usage」即可覆盖两种方言。Anthropic 那条不会补成空
choices 帧,那样会多出一帧。
OpenAPI / JSON Schema
对外接口(/v1/chat/completions、/v1/keys、/v1/models、/v1/generation、
/v1/integration/*)有一份手工维护的 OpenAPI 3.1 描述文件,与本文档同步更新:
| 在线查看 | 单页面,离线可用,无外部依赖 |
| 下载 openapi.yaml | 用于生成客户端、导入 Postman / Insomnia |
⚠️ 不提供服务自动生成的那一份:它会一并暴露控制台、运营、健康检查等内部接口,那些不是 对外契约,网关上也未开放。手写这份的覆盖范围就是本文档中出现的接口。
⚠️ 描述文件只说明形状,不重复这里的判断依据(为什么额度用尽是 403、为什么流式末帧 两种方言不一致等)。接入时两份一起读。