BazaarLink 开发文档
BazaarLink 是台湾的统一 AI API 闸道器 — 透过单一、与 OpenAI 相容的 API 端点,提供对 OpenAI、Anthropic、Google、Meta 等数百个模型的存取。
Read https://bazaarlink.ai/skill.md and follow the instructions to integrate BazaarLink into your app.收费标准
BazaarLink 的模型用量采零加成计价(与上游供应商官方牌价相同);平台费用于「充值(入金)」时收取:10% 交易费,台币渠道另计 5% 营业税。以美元记账、提供台币报价与电子统一发票。支持自助式 pay as you go 储值,企业亦可洽谈月结账务(Net-30,可议)。
运作方式
- 消耗(扣款):每一次 API 呼叫按实际 token 用量,以上游供应商的官方美元牌价从您的帐户余额扣款;模型零加成、消耗端不再加收任何费用。
- 充值(入金):以当下「台币兑美元即时卖出汇率」将新台币换算成美元存入余额;入金时收取 10% 交易费。
- • 付款方式与各渠道手续费以实时结账页面显示为准。
- • 符合资格的新台币渠道会在付款前显示适用营业税与台湾电子统一发票条件。
- • 银行电汇:大额或企业充值请联系我们安排电汇与定制发票。
- 发票:以 OEN(信用卡)充值会直接开立台湾电子统一发票并发送到您的 Email,可填统一编号。需要采购或月结的公司请联系业务。
关于汇率
外币换算采即时汇率;月结以报账(结算)时汇率为准,储值入金则以入金当下汇率换算为账户余额。汇率与时间随账务留存以供查核。
失败请求不收费(Zero Completion Insurance)
如果上游请求失败,并且没有可结算的用量数据,BazaarLink 会自动退回全部预扣款。即使串流已经开始、途中才中断,该次扣款仍为 0 美元。
- 上游无法连接、拒绝请求,或没有返回可用结果
- 串流在收到最终用量数据前中断,即使此前已返回部分内容
- 响应没有 usage,或 usage 是所有数值都为 0 的空数据
output tokens 为 0,不代表一定免费
usage.cost 是本次请求收取的美元金额。即使 output tokens 为 0,input tokens 仍可能产生费用;请查看 usage.cost 或“活动”记录确认最终金额。
快速入门
三种接入方式
五分钟内开始使用。BazaarLink 与 OpenAI SDK 完全相容 — 只需更改
超过 100 秒的长请求建议使用 stream:true。非流式请求约 12 秒后(默认值,可通过部署设置调整)会先返回 200 并开始发送 keepalive 空白;如果之后出错,则会以 200 + error JSON 返回。keepalive 是 JSON 正文前的空白,标准 JSON 解析器会忽略。
基础 URL
https://api.bazaarlink.ai/v1api.bazaarlink.ai 是 API 专用入口,与网站分开部署。此前的基础网址 https://bazaarlink.ai/api/v1 仍完全支持,现有集成无需变更。
使用 OpenAI SDK
BazaarLink 与 OpenAI SDK 完全相容。只需更改 base URL 和 API 密钥 — 所有其他程式码保持不变。
sk-bl-.自带上游密钥(BYOK)
将上游 API 密钥绑定到个人账户或组织。符合条件的请求会优先使用您的密钥。上游发生错误时,请求可以改试其他可用来源;若没有可用来源,请求会返回错误。个人密钥在密钥页面管理,组织密钥在组织设置中管理。 前往 BYOK 设置 →
内容过滤
为你的 API 流量启用双向内容防护:检测到提示注入的请求会被拦截(400),请求与响应中的敏感数据(API 密钥、信用卡号、身份证号等)会被自动遮蔽。规则与豁免清单可自定义,并提供使用统计。 前往内容过滤设置 →
网页搜索(:online)
让模型在回答前先搜索网页,并将搜索结果作为参考资料提供给模型。适合需要最新信息的问题,例如新闻、价格、近期发布的政策或产品。
支持的端点
POST /api/v1/chat/completionsPOST /api/v1/messagesPOST /api/v1/responses
支持流式(stream: true)和非流式请求。
使用方式
方式一:在模型名称后加上 :online
curl https://bazaarlink.ai/api/v1/chat/completions \
-H "Authorization: Bearer $BAZAARLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.4-mini:online",
"messages": [{ "role": "user", "content": "台湾今天有哪些 AI 相关新闻?" }]
}'方式二:使用 plugins 参数
方式三:使用 web_search_options
{
"model": "gpt-5.4-mini",
"messages": [{ "role": "user", "content": "..." }],
"web_search_options": { "search_context_size": "high", "query_source": "conversation" }
}以上三种方式任选其一即可,也可以混用。
搜索参数
以下参数可以放在 plugins 的 web 项目或 web_search_options 中;两处都指定且值不同时,以 plugins 为准。
search_prompt任意文本—直接指定搜索查询。指定后优先于 query_source。query_sourcelast_user、conversationlast_user没有 search_prompt 时,指定搜索查询的来源。last_user 只使用最后一条用户消息;conversation 使用整段对话(不含 system 消息)。country小写英文国家名(例如 taiwan、japan、united states)不限地区优先搜索指定国家的来源。不指定则不限地区。指定 country 时,搜索类型固定为普通搜索(general);同时指定 topic: "news" 会返回 400。topicgeneral、newsgeneral搜索类型。不指定时使用一般搜索(general);需要新闻类结果时,请明确指定 topic: "news"。search_queries字符串数组,1–5 条—一次指定多个搜索查询,每条各搜索一次、各收取一次搜索费用;结果合并并去除重复网址后提供给模型。不能与 search_prompt 同时使用。部分查询失败时,使用成功的结果继续回答,只收取成功条数的搜索费用;全部失败才返回 503 且不收费。time_rangeday、week、month、year(也接受 d/w/m/y、past_day、24h、7d、30d、365d 等常见写法;参数名也可使用 recency 或 search_recency_filter)不限只搜索指定期间内的内容。languageISO 639-1 语言代码(如 zh、en、ja),单个或数组不限优先搜索指定语言的内容。传入数组时,目前只使用第一个语言。include_domains域名字符串数组,支持通配符(例如 *.gov.tw)—只搜索这些域名,最多 300 个,每个域名最长 253 个字符。exclude_domains域名字符串数组,支持通配符—排除这些域名,最多 150 个。max_results1–10按等级返回的参考来源数量。也可以写成 num_results。enginebasic、fast、ultra-fast、advanced按等级直接指定搜索深度,优先级最高。其他值(包括其他平台的搜索引擎名称)一律使用默认深度,不会报错。(仅 plugins)modeturbo、instant、fast、basic、advanced、deep—另一种指定深度的方式:turbo/instant → 极速、fast → 快速、basic → 标准、advanced/deep → 高级。无法识别的值会被忽略。search_context_sizelow、medium、high、fastmedium搜索等级,见下表。(仅 web_search_options)深度优先级:engine(上表四个值)> mode > search_context_size > 默认 medium。
plugins 与 web_search_options 的参数格式与 OpenRouter 兼容,现有请求可以直接使用。
也兼容 Vercel AI Gateway 的搜索工具写法
Chat Completions 的 tools 也接受以下搜索工具格式,会视为一次网页搜索,由本平台的网页搜索处理,计费与引用格式相同:
- 可接受的
type:vercel:perplexity_search、vercel:exa_search、vercel:parallel_search、vercel:tako_search。这几种type的行为和费用完全相同。 config.query视同search_prompt;config.max_results(或num_results)、config.country等对应上方同名参数;无法识别的字段会被忽略。- 这些搜索工具不会转发给模型。
- 同一个请求带有多个搜索工具时,只采用第一个。
也接受 `web_search_preview` 工具
在 Responses 等端点的 tools 中传入 { "type": "web_search_preview" },同样会视为一次网页搜索,由本平台的网页搜索处理,计费与引用格式相同。这个工具不会转发给模型。
同时使用多种写法时
:online、plugins、web_search_options、搜索工具(包括 web_search_preview)可以同时出现,但每个请求只会执行一次搜索、收取一次搜索费用(使用 search_queries 时按条数计算)。搜索查询优先级为:search_queries > 搜索工具的 config.query > search_prompt > query_source。其他参数按上方各参数的优先级合并。
只有参数类型错误(例如 engine 传入数字、include_domains 不是字符串数组)或值超出范围时,才会返回 400 invalid_web_search_options。
搜索等级
low标准最多 5 条更精简medium标准最多 10 条默认等级high高级最多 10 条搜索更深入,单价更高fast快速最多 10 条响应更快未指定等级时使用 medium。
响应中的引用来源
搜索到的来源会通过 annotations 返回,采用业界通用的 url_citation 格式:
- 每个参考来源都有一条引用。
- 如果模型在回答中标注了对应来源(例如
[source-1]),start_index与end_index会指出该标注在回答文字中的位置;没有标注时两者都是0。
各端点的位置:
- Chat Completions:非流式在
choices[].message.annotations;流式会在[DONE]之前额外发送一个只含delta.annotations的区块。 - Responses:在
output_text内容的annotations中;流式会随response.output_text.done等完成事件发送。 - Messages:附在文本内容区块的
annotations中;流式会在结束前的text_delta事件发送。
计费方式
- 每次请求的费用 = 模型费用 + 网页搜索费用。
- 网页搜索按次计费,单价按平台定价;高级深度(
high等级,或通过engine/mode指定为高级)的单价更高。 - 免费模型也会收取网页搜索费用,模型本身仍然免费。
- 每个请求默认搜索一次;使用
search_queries时,搜索次数等于查询条数,费用也按条数计算。即使系统在后端切换其他路由重试,也不会重复搜索或重复收费。 - 以下情况不收取网页搜索费用:
- 搜索本身失败(会返回 503,见下方)。
- 使用
search_queries时失败的那些查询(只收取成功条数)。 - 搜索成功,但模型最后没有成功生成响应。
- 预扣余额时会包含搜索费用。实际扣款金额会反映在响应的
usage.cost和账务记录中。
错误与限制
web_search_unavailable网页搜索服务暂停,请稍后重试。不收费,也不会调用模型insufficient_credits余额不足以支付本次请求(包括搜索费用),系统会在搜索前拦截。不收费web_search_rate_limited网页搜索请求过于频繁,请稍后重试。不收费invalid_web_search_options搜索参数不合法,例如 country 不在支持列表中、include_domains 不是字符串数组、search_queries 与 search_prompt 同时指定。不收费- 普通请求的限流、模型权限、内容审核等检查都会在搜索前完成;被这些检查拦截的请求不会进行搜索。
- 搜索相关参数与工具(
:online后缀、plugins的 web 项目、web_search_options、上述搜索工具与web_search_preview)只由本平台处理,不会转发给模型。
从 OpenRouter 迁移
BazaarLink 的 API 与 OpenRouter 兼容 — 大多数集成只需改两个值即可切换:base URL 换成 https://api.bazaarlink.ai/v1、API 密钥换成 sk-bl- 开头的 BazaarLink 密钥。
- base URL:https://openrouter.ai/api/v1 → https://api.bazaarlink.ai/v1
- API 密钥:sk-or-... → sk-bl-...(在 /keys 创建)
- 模型 ID:同样使用 provider/model 格式(例如 anthropic/claude-sonnet-4.6);完整列表见 GET /v1/models
- models 候选列表、流式输出、工具调用、结构化输出的 request 形状相同
身份验证
所有 API 请求都需要在 Authorization 标头中提供您的 API 密钥。
Authorization: Bearer sk-bl-YOUR_API_KEY从 仪表板取得您的 API 密钥。请妥善保管密钥 — 请勿在用户端程式码中暴露它。
选填标头
设计原则
BazaarLink 围绕三个核心原则设计:
1. 统一介面
一个 API、一个 SDK、数百个模型。只需更改模型 ID,无需修改程式码,即可在 OpenAI、Anthropic、Google Gemini、Meta Llama 等之间切换。
2. 价格优化
BazaarLink 自动路由到您所选模型最具成本效益的供应商。您只需为实际使用量付费,以美元计费并提供完整发票支援。
3. 请求处理方式
上游来源出现问题时,请求可以改试其他可用来源;若没有可用来源,请求会返回错误。
多模态
BazaarLink 支援多模态输入 — 将图片、音讯和档案与文字一起传送至支援的模型。内容会直接传送至上游供应商。
支援的模态
示例:
传送图片
使用 content 阵列格式搭配 image_url 部分。支援格式:PNG、JPEG、WebP 及 GIF(包含动态 GIF)。单一讯息可包含多张图片,每张为独立的 image_url 部分:
限制
BazaarLink 有两种独立限制:按请求频率计算的速率限制,以及按账户花费计算的点数限制。超过速率限制会收到 HTTP 429;点数用尽则会收到 HTTP 402。
速率限制
速率限制以使用者为单位(非密钥),以每分钟请求数(RPM)计算。无每日上限。等级由帐户点数余额自动决定。
超过速率限制时,您会收到附有 Retry-After 标头的 429 回应。重试时请使用指数退避策略。
响应标头
响应可能包含 x-request-id、非流式响应的 x-generation-id、x-ratelimit-*、适用时的 retry-after,以及 auto 或 auto:free 路由的 x-auto-resolved-model。
x-request-id: 85e6f35c71a31f19-SJC
x-generation-id: 85e6f35c71a31f19-SJC
x-ratelimit-limit: 200
x-ratelimit-remaining: 198
x-ratelimit-reset: 1740000060
retry-after: 5
x-auto-resolved-model: openai/gpt-4o点数限制
收到 402 代表账户余额或密钥花费上限已归零,而非请求过于频繁。此类响应不会带速率限制标头;若在流式传输过程中触发,会以 SSE 错误事件回传,而非直接改变 HTTP 状态码。
IP 白名单
每个 API 密钥都可以设置独立的 IP 白名单,只有来自指定来源 IP 的请求才能使用此密钥。
什么情况下适合使用
适合部署在具有固定出口 IP 的生产环境服务器或企业内网服务。如果应用程序从家庭网络、移动网络或其他会变化的地址发出请求,请先确认出口 IP 稳定,否则可能会把自己锁在外面。
如何设置
前往 /keys ,打开该密钥的“…”菜单,选择“IP 白名单”,输入项目后保存。
也可以使用 PATCH /api/v1/keys/:id,搭配登录 session 或 Management API key 设置:
项目格式
在 UI 中每行输入一个值;使用 API 时,将相同值放入 `allowedCidrs` 数组。可接受裸 IPv4 地址、IPv4 CIDR,或 IPv6 字面值(仅精确匹配)。
203.0.113.7
198.51.100.0/24
2001:db8::1运作方式
留空(发送空的 [] 数组)代表允许所有来源 IP。这是默认值,现有密钥的行为保持不变。
来源 IP 取自 `cf-connecting-ip` 标头。
白名单非空但无法解析来源 IP 时,请求会被拒绝(fail-closed)。
个人紧急熔断
针对您所有 API 密钥的固定 1 分钟 / 1 小时 USD 支出上限。当时间窗口阈值触发后,新请求将收到 HTTP 429;窗口于整点边界自动重置。
帐户安全
除了帐户密码,BazaarLink 也支持两步验证,为登录多加一层保护。
启用两步验证(TOTP)
- 前往「设定」页面,找到「两步验证(TOTP)」区块,点击「启用两步验证」。
- 用验证器 App(例如 Google Authenticator)扫描画面上的 QR code,或手动输入下方显示的密钥。
- 输入验证器生成的 6 位验证码并确认,即完成启用。
启用后系统会显示 8 组备用码(仅显示这一次),每组 10 位、限用一次;请立即抄下或复制,保存在手机以外的安全地方,手机丢失或无法使用验证器时可用备用码登录。
其他帐户防护
搭配下列功能,可以进一步降低密钥外泄或误用造成的损失:
- IP 白名单 — 将 API 密钥限制在指定的来源 IP 才能使用。
- 个人紧急熔断 — 对单一分钟与单一小时的花费各自设定上限,超过即自动暂停。
- 密钥花费上限 — 创建或更新 API 密钥时,设定每日、每周或每月的花费上限。
图片生成
透过 /v1/chat/completions 带 modalities:["image"],或 OpenAI DALL·E 相容的 /v1/images/generations 生成图片。
curl -N https://api.bazaarlink.ai/v1/chat/completions \
-H "Authorization: Bearer $BAZAARLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-5.4-image-2","messages":[{"role":"user","content":"a red cat on a sofa"}],"modalities":["image","text"],"stream":true}'视频生成
非同步三步骤流程(submit → poll → content)。视频生成需要 30 秒到 5 分钟。
curl https://api.bazaarlink.ai/v1/videos \
-H "Authorization: Bearer $BAZAARLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"bytedance/seedance-2.0","prompt":"a bird flying over mountains","duration":3}'
# → 202 { "id": "vjob_xxx", "status": "pending" }PDF 输入
直接在讯息中传送 PDF 文件,给原生支援 PDF 输入的模型(例如 Claude、Gemini)分析、摘要或回答问题。BazaarLink 会把档案直接转送给模型 — 算一般 input tokens,不额外收费、不额外处理。
支援的格式
- PDF 文件(含文字、图片、表格、扫描件)
- Base64 资料 URL(`data:application/pdf;base64,...`)
- 多页文件
- 仅限无密码保护的 PDF
影片输入
传送视频档案给支援视频输入的模型,用来分析内容、生成说明或回答场景与事件相关问题。可用直接 URL 或 base64 数据 URI — URL 适合公开可存取的视频;base64 用于本机档案或私有视频。
支援的格式
MP4(H.264)MPEGMOVWebMOAuth PKCE
OAuth 2.0 PKCE(Proof Key for Code Exchange)让公开用户端应用程式(浏览器 SPA、行动 App)能够代表个别用户呼叫 API,无需在用户端储存长效的伺服器密钥。
何时使用 OAuth PKCE
- 建构需要每位用户计费的浏览器 SPA 或行动 App
- 多租户 SaaS — 每位终端用户支付自己的 API 使用费用
- 无法在用户端储存共用密钥(公开用户端)
- 需要每位用户各自独立、可撤销的密钥(不会自动过期),而非单一共用 API 密钥
你的用户会看到什么
请在你自己的登录界面向用户说明这些步骤:
- 在你的应用内选择“使用 BazaarLink 登录”(或你自己命名的按钮)。
- 浏览器打开 BazaarLink 授权页。若尚未登录,会先登录,登录后自动回到这一页。
- 页面会显示你的应用网址,以及允许后会发生的事:为该应用创建一把新的 API 密钥、用量从 BazaarLink 余额扣款、可随时撤销。用户可为密钥命名并设置每月额度上限(均为选填)。
- 点击“允许”后回到你的应用;点击“拒绝”则不会创建密钥、你的应用也不会收到通知,用户会看到“已拒绝访问”页面。
- 之后若要撤销,打开“API 密钥”页面(https://bazaarlink.ai/keys),停用或删除以你的应用命名的那把密钥。
工作方式
步骤 1 — 发起认证 — 产生随机的 code_verifier(长随机字串)及其 SHA-256 杂凑值作为 code_challenge,然后将用户重新导向至 BazaarLink 认证页面。
https://bazaarlink.ai/auth?callback_url=https://yourapp.com/callback&code_challenge=CODE_CHALLENGE&code_challenge_method=S256授权网址参数
- callback_url(必填)— 用户点击允许后回到的网址,规则见下方。
- code_challenge(必填)— code_verifier 的 SHA-256 再做 base64url 编码(43 字符,不含 = 补位)。
- code_challenge_method(必填)— 必须是 S256。
- state(选填)— 你自己的不透明防 CSRF 值,1 到 256 个可见 ASCII 字符。BazaarLink 会原样在授权码之后以 &state=… 带回。格式不正确的 state 会让授权页显示“授权请求无效”。
- key_label(选填)— 最多 100 个字符。会预填授权页的密钥名称(用户仍可修改)。过长或空白的标签会被忽略。
- 无回调的工具(CLI/桌面程序)— 省略 callback_url。用户允许后,页面会显示一次性授权码(5 分钟内有效、只能用一次),让用户输入到你的工具;换 key 的方式与跳转得到的授权码完全相同。页面无法显示是哪个应用在请求,请提醒用户只在自己启动的工具里输入。
不支持
- workspace_id 与 required_workspace_id — 不支持。密钥一律属于用户自己的账号。
- code_challenge_method=plain — 不支持(只收 S256)。
callback_url 规则
- 必须是 https://。http:// 只接受 localhost、127.0.0.1 与 [::1](任何端口),此时授权页会显示本机开发警告。
- 不可含片段(#),网址内不可含账号密码,最长 2048 字符。
- 授权页会显示你的 callback 主机名,让用户看得出是哪个应用在请求授权。
- 用户点击允许后,浏览器会被重定向到你的 callback_url 并附上 code=…(若你有带 state,也会附上 state=…;既有的查询字符串会保留)。授权码 10 分钟内有效且只能使用一次。
步骤 2 — 交换授权码取得 API 密钥 — 用户授权后,BazaarLink 会将用户重定向到您的 callback_url 并附上一次性授权码。授权码 10 分钟内有效且只能使用一次;code_verifier 错误会让它立刻作废。请 POST code、code_verifier 与 code_challenge_method(三者均必填),即可获取该用户的 API 密钥。
步骤 3 — 使用用户专属密钥 — 返回的密钥是普通的 BazaarLink API 密钥,属于授权的那位用户 — 用量从该用户的余额扣款,不会算在你头上。
curl https://bazaarlink.ai/api/v1/chat/completions \
-H "Authorization: Bearer sk-bl-..." \
-H "Content-Type: application/json" \
-d '{"model": "google/gemini-3.5-flash", "messages": [{"role": "user", "content": "Hello"}]}'JavaScript 示例(浏览器)
/auth 页面与 POST /api/v1/auth/keys 由 https://bazaarlink.ai 提供(不是 api.bazaarlink.ai)。获取的密钥在 https://bazaarlink.ai/api/v1 与 https://api.bazaarlink.ai/v1 两个 base URL 上都可使用。
若用户在授权时设置额度上限,该上限为每月额度,按账号的月周期重置。
错误
错误格式为 OpenAI 风格 {"error":{"message","type","code"}}。POST /api/v1/auth/keys 可能返回:
- 400 invalid_code_challenge_method — 未带 code_challenge_method、为 plain,或不是 S256。
- 400 — JSON 内容无效,或缺少 code/code_verifier。
- 403 invalid_code — 授权码不存在、已过期或已使用、code_verifier 错误,或该账号已不被允许。以上情况刻意返回相同信息,调用方无法区分。code_verifier 错误也会让授权码作废:请用户重新授权。
- 429 rate_limited — 同一 IP 10 分钟内交换超过 30 次(见 Retry-After 标头)。
- 429 key_total_cap — 该账号已持有 200 把 API 密钥的上限。
- 405 — 只接受 POST。
从你的服务器创建授权码(管理密钥)
个人管理密钥(Management Key)的拥有者可以不经过浏览器授权页,直接用 POST /api/v1/auth/keys/code 创建授权码(与 OpenRouter 兼容)。授权码会绑定该管理密钥的拥有者,因此交换到的是该拥有者账号下的标准密钥,额度、周期、到期时间与名称都由这里决定。适用于你自己的工具已持有管理密钥、想替某个 App 发一把受限密钥的情况。交换步骤(POST /api/v1/auth/keys)与上面相同。
- callback_url(必填)与 code_challenge + code_challenge_method=S256(必填)— 规则与授权网址相同。
- key_label(选填)— 最多 100 个字符,密钥名称。默认为“App: <你的 callback 主机名>”。
- limit(选填)— 美元额度上限,0 或以上;0 或未带代表不限额。
- usage_limit_type(选填)— daily、weekly 或 monthly:额度多久重置一次。只在有 limit 时生效;默认 monthly。
- expires_at(选填)— 密钥到期时间:未来的 ISO 8601 UTC 时间且须含秒,例如 2026-12-31T23:59:59Z。只到分钟的格式会被拒绝。未带代表密钥一直有效,直到被撤销。
- workspace_id — 不支持(400)。spawn_agent 与 spawn_cloud 会被接受但忽略。
响应:{ "data": { "id", "app_id", "created_at" } }。id 就是要拿去交换的一次性授权码(10 分钟内有效、只能用一次)。BazaarLink 没有 App 注册机制,app_id 是由你的 callback 地址推导出的固定整数:同一地址永远得到相同的 app_id。
- 401 unauthorized — 没带 Bearer 密钥,或密钥不存在。
- 403 management_key_required — 该密钥不是个人管理密钥(标准密钥与组织管理密钥都会被拒绝)。
- 403 account_not_allowed — 该密钥的拥有者已被停权或删除。
- 400 — invalid_callback_url、invalid_code_challenge_method、invalid_code_challenge、invalid_expires_at、workspace_not_supported,或内容格式错误。
- 429 rate_limited — 同一拥有者每小时超过 30 个授权码,或同一 IP 每小时超过 120 个(见 Retry-After)。
你拿到的密钥
- 一把标准的 BazaarLink API 密钥(sk-bl-…),与在“API 密钥”页面创建的相同,不会自动过期。
- 用量从用户的 BazaarLink 余额扣款。若用户在授权页设置额度上限,该上限为每月额度。
- 两个 base URL 都可使用:https://bazaarlink.ai/api/v1 与 https://api.bazaarlink.ai/v1。
- 会计入账号 200 把密钥的上限,并出现在用户的“API 密钥”列表中,用户可随时停用或删除。
- 被停权或已删除的账号无法授权应用;停权前发出的授权码在交换时会被拒绝(403 invalid_code)。
你会得到什么
- 授权码 + PKCE 流程(公开用户端应用程式)
- 每用户计费:各用户用自己的余额支付自己的用量
- 每位用户一把独立密钥,列在该用户的“API 密钥”页面,用户可随时撤销
管理 API 密钥
管理密钥(Management Key)专用于程式化管理 API 密钥:可建立、列出、更新、停用与删除标准密钥,但无法呼叫 AI 模型。
建立管理密钥
前往「Management API Keys」页面,点击「Create」即可 — 这是独立页面,不是在普通 API 密钥页面里选类型。
列出密钥
建立子密钥
更新密钥
撤销密钥
DELETE https://api.bazaarlink.ai/v1/keys/:id
Authorization: Bearer sk-bl-YOUR_MGMT_KEY
# Returns 204 No Content on success查询余额
查询用量
GET https://api.bazaarlink.ai/v1/usage?period=month
Authorization: Bearer sk-bl-YOUR_MGMT_KEY
# period: day | week | month | year应用程式识别
透过请求标头识别您的应用程式,让系统追踪使用量、显示在仪表板上,并在未来提供更细致的分析。
可用标头
| Header | Description |
|---|---|
| HTTP-Referer | 您的网站 URL,用于用量追踪和分析(选填) |
| X-Title | 您的应用程式名称,显示在仪表板中(选填) |
错误代码
错误回应格式
错误 envelope 因端点而异。若存在 error.type,请结合 HTTP 状态码判断;error.code 可能是字符串或数字状态码,也可能省略;error.message 仅用于显示。
{
"error": {
"message": "Insufficient credits. Please top up to continue.",
"type": "invalid_request_error",
"code": "insufficient_credits"
}
}HTTP 状态与 error.code
错误 envelope 因端点而异。若存在 error.type,请结合 HTTP 状态码判断;error.code 可能是字符串或数字状态码,也可能省略;error.message 仅用于显示。
机器可读的账务代码
同样是 402,也可能代表不同的账务控制。请依下列稳定代码显示正确的处理方式。
详细错误代码
API 请求失败时,error.code 会告诉你更具体的原因。即使两个错误都是 HTTP 400,处理方式也可能不同:例如 unknown_model 表示模型名称有误,image_too_large 则表示图片太大。请根据下表查找原因和对应的处理方向。
内容审查
所有请求在发送到模型之前,都会先经过自动化内容审查。不符合使用规范的请求会被拒绝,不会送达模型,并返回 403 错误。
会被拦截的内容类别
审查依据我们的使用规范(Acceptable Use Policy)进行,主要拦截以下类别的内容:
- 性剥削内容
- 暴力威胁
- 违法行为的操作指导
- 生物危害相关内容
403 响应格式
请求被审查拦截时,会收到以下格式的错误响应:
{
"error": {
"message": "Your prompt was blocked by content moderation.",
"type": "invalid_request_error",
"code": "content_filter"
}
}被拦截的请求不会计费——你不会为被拒绝的请求付费。
误判申诉
如果你认为某次请求被误判拦截,请联系支持团队并附上请求时间与(如方便的话)request id,我们会协助复查。
隐私说明
每一笔请求都会经过自动化内容审查。
判定为违规的请求,我们会保留其内容作为合规举证之用。
其他请求不会保留完整提示词内容。
速率限制、预算与紧急刹车
这些控制可能拒绝原本有效的请求。它们与供应商故障不同,需要不同的恢复操作。
错误 envelope 因端点而异。若存在 error.type,请结合 HTTP 状态码判断;error.code 可能是字符串或数字状态码,也可能省略;error.message 仅用于显示。
视频与媒体资源状态
视频验证通常返回数字 code 400;任务不存在为 404、模型退役为 410、视频内容尚未完成为 409、视频 byte range 无效为 416。重试前请先轮询至完成或修正 Range 标头。
重试策略
只有在不修改请求也可能恢复的错误才应重试。若有 Retry-After,请依指定秒数等待;否则使用带 jitter 的指数退避。限制重试次数,也不要同时叠加 SDK 自动重试与手动重试。
错误处理
串流错误格式
在任何 token 串流之前发生的错误,会以标准 HTTP 错误回应(JSON body)回传。
串流一旦开始,HTTP 回应已经是 200。客户端必须解析每个 SSE data frame;只要出现顶层 error,或 choices[0].finish_reason === "error",就应视为失败且回应不完整。
若流式输出开始后才失败,BazaarLink 可能发送最后一个 SSE 事件,其中包含顶层 error 对象,之后发送 data: [DONE]。请将该响应视为不完整,不要把部分输出当作已完成的结果。
data: {"error":{"message":"The request could not be completed.","type":"upstream_error","code":502}}
data: [DONE]
// Branch on error.code; error.type can vary by failure path.工具呼叫
工具呼叫(也称为函式呼叫)让模型可以呼叫您定义的外部函式。模型会决定何时呼叫工具并产生结构化参数 — 您的程式码负责执行函式并将结果回传以继续对话。
支援的模型
大多数前沿模型都支援工具呼叫。以下是一些热门选择:
定义工具
每个工具是一个描述模型可呼叫函式的 JSON 物件。parameters 栏位使用 JSON Schema。
tool_choice 选项
完整流程
工具呼叫是一个多轮流程:(1) 带工具发送请求 → (2) 模型回传 tool_calls → (3) 执行函式 → (4) 回传结果 → (5) 模型生成最终回应。
平行工具呼叫
某些模型可以在单一回应中呼叫多个工具。处理每个工具呼叫并回传所有结果:
流式传输中的工具呼叫
流式传输时,工具呼叫会拆成多个 delta 依序送出——用每个片段的 index 把参数字符串组合起来,等 finish_reason 变成 "tool_calls" 才代表这次工具呼叫已经收完整。
简易 Agent 循环
只要模型还在要求工具就持续呼叫,直到它回传最终答案为止的通用模式——用 max_iterations 避免无限循环。
函数定义最佳实践
- 函数命名要具体:用 get_weather_forecast,不要只写 weather。
- description 要写清楚函数的用途与适用时机——模型只靠这段文字判断该不该呼叫。
- 参数尽量用 enum 限制可能值,并在 description 附上示例,降低模型生成错误参数的概率。
- 只把真正必要的字段标记为 required,选填字段应该真的可以省略。
结构化输出
强制模型返回符合 Schema 的有效 JSON。这对于建立需要程式化解析模型输出的可靠应用程式至关重要。
方法 1:response_format(JSON Schema)
以强制严格的 JSON Schema 合规性:
提示
- 使用清晰、描述性的属性名称 — 模型会将其作为上下文。
- 为 Schema 属性添加描述来引导模型。
- 设定 strict: true 以保证 Schema 合规(可能略微增加延迟)。
- 保持 Schema 简单 — 深度巢状的 Schema 可能降低输出品质。
- 使用不同模型测试 — 某些模型处理复杂 Schema 的能力更强。
助手预填
在消息数组最后加入一条未完成的 assistant 消息,向兼容的模型路由请求接续生成。
讯息转换
The client-supplied transforms field is ignored and removed before an upstream request. It cannot enable or disable message transformations. BazaarLink may apply context handling under its own server-side rules; shorten the input or select a model with a larger context window when needed.
transforms values such as middle-out; they do not change how this request is routed or processed.零资料保留
BazaarLink 预设不储存您的讯息内容。本页说明您的资料处理方式,适用于处理敏感资料的应用程式。
目前的资料处理方式
- 讯息内容:预设不储存,在记忆体中处理后立即丢弃
- 计费元资料:token 数量、时间戳记、模型 ID
- 使用日志:请求统计,不含讯息内容
- 上游转发:讯息转发至上游供应商,受其隐私政策约束
提示快取
提示快取可以重用之前计算过的 prompt tokens,显著降低成本并减少延迟,特别适合有大量重复系统提示的应用程式。
运作方式
是否需要额外设定取决于供应商。OpenAI 系列模型的长重复前缀会自动快取,不需要改请求内容。Claude(Anthropic)模型只有在请求里带明确的 cache_control 标记时才会快取——BazaarLink 不会替你加这个标记,没带就永远不会被快取。BazaarLink 会原封不动转发你送出的快取标记,并在使用量回应中回报实际的快取读写 token 数。
推理 Tokens
推理模型(如 DeepSeek R1、o1 系列)在生成最终答案之前,会先在内部进行思考。这些思考过程消耗的 tokens 称为推理 tokens,会分开计费。
在回应中读取推理 Tokens
思考模式控制
部分模型支援切换「思考」模式。思考模式在输出最终答案前产生内部推理 token,以更多 token 为代价提升输出品质。
| 模型系列 | 参数 | 预设值 |
|---|---|---|
| qwen3-* | enable_thinking: boolean | false(平台预设值) |
| openai/gpt-5.5, gpt-5.6-sol, gpt-5.4 | reasoning_effort: "low" | "medium" | "high" | medium |
| deepseek/deepseek-r1 | — | 永远启用(无法关闭) |
统一 reasoning 物件(新格式)
BazaarLink 也支援统一的 reasoning 物件,以单一一致的 API 适用所有模型系列:
| 栏位 | 数值 | 适用模型 |
|---|---|---|
| reasoning.effort | "xhigh" | "high" | "medium" | "low" | "none" | OpenAI o-series, Grok |
| reasoning.max_tokens | integer | Anthropic Claude, Gemini |
| reasoning.exclude | boolean | 从回应中隐藏思考内容(模型仍会推理) |
读取思考内容
推理模型可以在答案之外返回思考内容。下列模型默认开启思考:没有带任何推理参数的请求,会以思考模式运行、返回思考内容,并按实际使用的思考 tokens 计费。发送 reasoning: { exclude: true } 或 include_reasoning: false 即可关闭。其他模型只有在你明确要求时才会返回思考内容:发送 reasoning_effort、reasoning 对象、include_reasoning: true、thinking 或 enable_thinking。
默认开启思考的模型: gemini-4-argon, deepseek-v4.1-flash, deepseek-v4.1-flash-1017
如何要求思考内容
在请求中带上下列任意一项:reasoning_effort(low、medium 或 high)、reasoning 对象(effort、max_tokens)、include_reasoning: true、thinking: { type: "enabled" } 或 enable_thinking: true。发送 reasoning.exclude: true 或 include_reasoning: false 则关闭思考内容(模型仍会推理)。
| 字段 | 位置 | 说明 |
|---|---|---|
| reasoning | choices[].message.reasoning | 思考内容(字符串) |
| reasoning_details | choices[].message.reasoning_details | 思考内容的条目列表,每个条目只有 type 和 text |
| reasoning | choices[].delta.reasoning | 流式输出时,思考内容分段发送(delta.reasoning 和 delta.reasoning_details),先于 delta.content 中的答案文字 |
用 GET /v1/models 查询各模型支持的强度:每个推理模型都列出 reasoning.supported_efforts、reasoning.default_effort 和 reasoning.mandatory(例如 gemini-4-argon 支持 high、medium、low)。
示例:gemini-4-argon
/v1/responses:以 reasoning: { effort, summary: "auto" } 请求,思考内容会放在 output 数组的 reasoning 条目中;/v1/messages:发送 thinking: { type: "enabled", budget_tokens } 即可收到 thinking 块。
延迟与效能
优化 AI API 的回应延迟对用户体验至关重要。以下是 BazaarLink 架构中影响延迟的关键因素及最佳化建议。
影响延迟的因素
- 模型大小:较大的模型(70B+)通常生成速度较慢
- 提供商负载:不同时段不同供应商的负载有所差异
- Token 数量:max_tokens 越大,完成时间越长
- 串流 vs 非串流:串流(stream: true)可更快取得第一个 token
- 上下文长度:超长 context 会增加前置处理时间
最佳化建议
- 优先使用串流(stream: true)以改善感知延迟
- 对延迟敏感的场景选择较小的模型(flash/mini/haiku)
- 启用提示快取以降低重复请求的延迟
可用性优化
上游发生错误时,请求可以改试其他可用来源;若没有来源能处理,请求会返回错误。熔断器会限制重复尝试,平台也会监测供应来源状态。
可用性机制
- 熔断器:自动侦测并隔离故障供应商
- 上游来源出现问题时,请求可以改试其他可用来源;若没有可用来源,请求会返回错误。
- 供应商健康监控:持续追踪各供应商的错误率和延迟
- 重试逻辑:暂时性错误(5xx)自动重试
熔断器配置
安全护栏
为 API 请求加上内容安全机制,过滤有害内容、执行合规政策。BazaarLink 目前只在组织(Organization)层级提供可自定义的内容过滤防护;个人(非组织)API 密钥没有对应设定,内容安全完全依赖各上游模型供应商自己内建的安全系统。
规划中功能(尚未提供,个人与组织密钥皆无)
目前行为
个人 API 密钥:所有上游供应商都有自己的内容安全系统,触发内容过滤的模型回应会回传 finish_reason: "content_filter",BazaarLink 不做额外过滤。组织 API 密钥:org_admin 可以在「内容过滤防护」设置自定义规则(阻挡/遮蔽/记录),套用在文字送到模型之前。
Cursor IDE 集成
把 BazaarLink 设成 Cursor 的 OpenAI Override URL,立即在 Cursor 内调用所有模型。支持 Responses API 自动转换、工具格式规范化,并用 bz- 前缀规避 Cursor 对 Claude 模型的拦截。
快速设置
在 Cursor 打开 设置 → 模型,然后:
- 把 Override OpenAI Base URL 设为 https://api.bazaarlink.ai/v1
- 把 Override OpenAI API Key 设为你的 sk-bl-... BazaarLink 密钥
- 输入你想用的 model 名称 — Claude 模型请看下方 bz- 前缀规则。
bz- 前缀(用于 Claude 模型)
Cursor 在 client side 看到 claude- 开头的模型名称会强制走它自己的 Anthropic 集成,完全略过你的 Override URL。要让 Cursor 把请求送到 BazaarLink,在模型名称前面加 bz-。我们的 server 会去掉前缀后再用 alias map 解析剩下的部分。
点号和连字号的版本都会被规范化:bz-claude-sonnet-4.6 和 bz-claude-sonnet-4-6 会解析到同一个模型。
CURSOR_MODEL_MAP 环境变量(运营者覆写)
如果你是自架 BazaarLink,设这个环境变量可以把任何 Cursor 端的模型名称重新映射到目录的 canonical id:
CURSOR_MODEL_MAP=gpt-claude-sonnet:anthropic/claude-sonnet-4.6,gpt-opus:anthropic/claude-opus-4.7这样 Cursor 端输入的 gpt-claude-sonnet 会在 server 端被映射成 anthropic/claude-sonnet-4.6。当你想让 Cursor 以为某个模型是 GPT 家族(才会走 Override URL),实际上你想用 Claude 提供服务时很有用。
自动处理的事项
当请求送到 /v1/chat/completions 时,BazaarLink 会自动套用以下兼容性转换 — 你的 client 端不用做任何事:
- 自动检测 Responses API body — 如果 body 有 input 而没有 messages,会自动转成 Chat Completions 格式(Cursor 对 GPT 家族模型会送 Responses API 格式)。
- 包装扁平的 tool 定义 — Cursor Agent 送的是 { name, description, parameters } 没有 function 包装。我们会包好,避免 Anthropic 回 Tool '' not found in provided tools。
- 矫正错误格式的 tool_choice — Cursor 送的是 { type: "auto" }(对象形式,没 function)。OpenAI 规范要求 auto/none/required 用字符串形式,所以我们强制转换。
- 送到非 OpenAI 供应商时剥除 OpenAI 专用字段 — parallel_tool_calls、logprobs、top_logprobs、logit_bias、service_tier、user 在转发前会被移除(否则 Anthropic 会回 400)。
- 把 max_output_tokens 对应成 max_tokens,同时移除 Responses-API 专用字段(previous_response_id、truncation、background、store)。reasoning 字段在原生 Chat Completions body 会保留。
Cursor Agent 模式
工具调用走的是标准 Chat Completions tool-call 流程。Cursor 送 tools(Shell、Read、Write、Grep 等)和 tool_choice: "auto";BazaarLink 转发给你选的供应商,由供应商决定要不要调用工具。工具调用以标准 OpenAI tool_calls deltas 形式回传;Cursor 在本地执行并继续对话。不管你选 gpt-4o(原生 OpenAI)还是 bz-claude-sonnet-4.6,运作方式都一样。
模型路由
BazaarLink 使用 provider/model-name 格式将请求路由到正确的上游供应商。这让您可以透过单一 API 端点存取主流模型。
模型 ID 格式
{provider}/{model-name}
# Examples
openai/gpt-5.4-mini
anthropic/claude-sonnet-4.6
google/gemini-3-flash-preview
deepseek/deepseek-v4.1-flash路由优先顺序
当您发送请求时,BazaarLink 依以下顺序解析上游供应商:
- 精确匹配 — 寻找与完整模型 ID 匹配的模型路由
- 供应商万用字元 — 回退至 provider/* 路由(例如 openai/*)
- 全域万用字元 — 回退至 * 万用字元路由
- 默认供应商密钥 — 仅限已收录模型,使用已启用且标记为默认的供应商密钥
在 模型页面浏览所有可用模型。
自动路由
Auto Router v3 会先把请求评分为 14 个任务层级之一,再使用该层级当前设置的主要模型与备用链。付费与免费路由表可在后台分别管理。
- auto — 使用付费路由表;成功完成请求的实际模型按公开价格计费。
- auto:free — 使用免费路由表;免费额度内扣款为 0。额度用完后,有余额的账户可能转为付费 auto,除非关闭付费 fallback。
如何使用
将 model 设为 "auto"(付费)或 "auto:free"(免费)以启用自动路由:
curl https://api.bazaarlink.ai/v1/chat/completions \
-H "Authorization: Bearer $BAZAARLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"Review this TypeScript function"}]}'v3 如何选择 tier
通用 tier 为 simple、standard、complex、reasoning;专用 tier 为 coding、vision、image、video、data、search、social、email、calendar、trading。若分数落在低置信度边界,系统会提升一级,避免低估任务难度。
- 层级评分:根据 messages、tools、长度、关键字与结构特征,选出 14 个 tier 之一
- 硬规则覆盖:图片输入、形式推理及特定专用任务可直接指定 tier
- 查询路由:按模式读取该 tier 当前的 primary 与最多 5 个 fallback;停用的 tier 直接返回 503
- 执行顺序:先尝试 primary,再按后台设置顺序尝试 fallback
- 回应追踪:解析后的模型会在回应本体和 X-Auto-Resolved-Model 标头中回传
当前实际使用的模型表
下表直接读取推理服务与后台使用的同一份实时设置。管理员可随时调整每个 tier 的主要模型、备用顺序与启用状态,无需重新部署。
auto
auto:free
部分模型提供受限速的免费额度。免费资格由平台按模型授予 — 直接用原本的模型 ID 调用即可;:free 后缀只是可选别名(对付费模型自行加上 :free 不会变免费)。
模型变体
独立模型 ID
:free、:extended 和 :thinking 等目录变体可表示具有不同能力或目录价格的条目。上游路由和客户价格由 BazaarLink 目录及服务器端规则决定。
:free
:extended
:thinking:nitro
:floor
:exacto:online免费模型
部分模型提供受限速的免费额度。免费资格由平台按模型授予 — 直接用原本的模型 ID 调用即可;:free 后缀只是可选别名(对付费模型自行加上 :free 不会变免费)。
- 直接调用原模型 ID(例如 deepseek/deepseek-v4-flash),免费额度内的请求自动免费。
- 免费用量按用户限制每分钟请求数(RPM)与每日上限,额度随账户等级(未充值 / 已充值)调整。
- 超过免费额度且账户有余额时,请求会自动以列出的付费价格继续。发送 X-Free-Fallback: false 可关闭自动转付费、改收 429。无余额时,超额请求返回 429。
- GET /v1/models 会为每个提供免费额度的模型列出 :free 条目;auto:free 永远路由到免费模型。
当前提供免费额度的模型
直接用这些模型 ID 调用即可享有免费额度。列表随上架调整,建议以 API 查询为准。
qwen/qwen3.7-flash
reflection/beam-free
nvidia/nemotron-3.5-lightning-free
reflection/beam
stealth/glyph-cluster
deepseek/deepseek-v4-flash-0731free免费额度上限
每日额度 = 上表每日请求额度 × 你的账户等级倍率,各免费模型分开计算;auto:free 另有以 IP 为单位的并行上限。个别模型可由平台单独设定更严或更宽的限制,实际值以模型页的「免费额度」区块为准。 免费额度以“单位”计算,并非单纯的请求次数:单次请求消耗的单位数会随 prompt 的 context 长度增加。因此在相同的每日额度下,长 context 请求的实际可用次数会明显少于短 prompt。
超出免费额度之后
免费额度用完后,账户仍有余额时,超额请求会按该模型的付费价格计费;如希望超额时返回 429,请发送 X-Free-Fallback: false 标头或在密钥设置中关闭付费转换。余额不足时,超额请求会返回 429。
当请求真的被这样降级时,响应会带上 x-bl-free-fallback: daily 或 x-bl-free-fallback: rpm 头部,标示是哪个上限触发的,让你在请求当下就能检测到这次切换,而不必等到账单才知道。没有降级的请求不会带这个头部。
# Return 429 instead of switching to paid routing
-H "X-Free-Fallback: false"组织管理
如果多人共用 BazaarLink,可以建立一个组织,把成员分到不同 Team,统一管理 API 密钥、可用模型、预算与账务。组织持有共用余额,Team 和成员可以另外设置每月花费上限。
三层预算系统
每次 API 请求都会检查个人、Team 和组织限制。达到每月预算或余额不足时返回 HTTP 402;支出紧急刹车返回 HTTP 429。
- 成员月度预算(OrgMember.monthlyBudget)
- Team 月度预算(Team.monthlyBudget)
- 组织 Credits 余额(Organization.credits)
费用报表
进入某个组织的管理后台后,打开「报表」即可查看四种每月费用分析:
- 总览:月度总花费、毛利率、每日趋势折线图
- 按 Team:各 Team 花费、占比、模型明细、预算使用率
- 按模型:各 AI 模型花费、平均单价($/1M tokens)
- 按成员:各成员花费(仅 org_admin 可看)
所有维度均支援 CSV 汇出,含 BOM(Excel 直接开启不乱码)。
建立与管理组织
- 前往「设置」,在组织区块建立新组织
- 建立后点击组织名称,进入该组织的管理后台
- 在管理后台建立 Team,并按需设置成本中心代码和每月预算
- 邀请成员(填入 email、指定角色与 Team)
- 为成员建立 API 密钥,密钥的用量自动归属到对应的 Team / 成员
- 前往「报表」页面查看按 Team / 模型 / 成员分组的月度花费
成员角色
组织还可以管理什么?
除了成员和 Team,组织管理后台还集中提供以下功能:
- API 密钥:按组织、Team 或成员建立密钥,查看归属并限制可用模型
- 内容过滤防护:在文字发送给模型前阻挡、遮蔽或记录敏感内容
- Allowed Models:限制整个组织、特定 Team、成员或 API 密钥可调用的模型
- 预算与紧急刹车:设置每月上限,以及分钟/小时支出保护
- 报表与账务:查看花费、模型用量、Team 分摊、余额、信用额度和付款资料
- 变更与安全记录:跟踪设置变更、内容过滤命中和其他安全事件
内容过滤防护
这是组织自己的文字检查规则。使用组织 API 密钥发送请求时,系统会先检查文字,再决定是否发送给模型。org_admin 可在“设置 → 内容过滤防护”中启用、编辑和测试规则。
- block(阻挡):整个请求返回 HTTP 403,不会发送给模型
- redact(遮蔽):把匹配文字替换成 [REDACTED],再将处理后的内容发送给模型
- flag(记录):请求照常发送,但把命中项目写入组织审计记录
- 可使用内置的敏感信息和 Prompt Injection 模板,也可新增关键词或正则规则
- 最多 100 条规则;正则规则会先检查安全性,也可使用测试文字预览结果
Management API (v1)
Management API 可用于列出组织、建立 Team、加入成员或调整预算,不必手动操作网页。`/v1/orgs` 负责组织与成员管理;费用报表使用下方独立的 `/api/orgs/:orgId/reports/*` 路径。
组织(Organizations)
/v1/orgs列出呼叫者所属的所有组织,包含角色与 joinedAt。
/v1/orgs/:orgId取得组织详细资料,包括团队与成员数量。
curl https://api.bazaarlink.ai/v1/orgs \
-H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"Teams
/v1/orgs/:orgId/teams列出团队及其成员数,依名称排序。
/v1/orgs/:orgId/teams/v1/orgs/:orgId/teams/:teamId部分更新 — 仅传送要变更的字段。
/v1/orgs/:orgId/teams/:teamId# Create a team
curl https://api.bazaarlink.ai/v1/orgs/{orgId}/teams \
-X POST \
-H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Engineering", "costCenterCode": "ENG-001", "monthlyBudget": 500}'成员(Members)
/v1/orgs/:orgId/members列出所有成员,包含巢状的 user(id/name/email)与团队资讯。
/v1/orgs/:orgId/members若 email 无对应 BazaarLink 帐号则回传 404;已是成员则回传 409。预设角色:member。
/v1/orgs/:orgId/members/:memberId部分更新 role、teamId 或 monthlyBudget。
/v1/orgs/:orgId/members/:memberId若移除对象为最后一位 org_admin,回传 400。
Reports API
Reports API 是组织报表页面实际使用的数据来源,也可用于内部仪表板、每月对账或自动下载 CSV。org_admin 可查看所有报表;billing_viewer 可查看总览、Team 和模型数据,但不能查看逐一成员的花费。支持登录 Session 或 Bearer Management Key。
请传入 year 和 month(1–12)。overview 与 by-team 缺省时使用当前月份;by-model、by-member 和 export 则要求两者都必须提供。建议每次都明确传入两个参数。
错误响应对照
允许模型(白名单)
限制您的组织、团队或个别成员可调用的模型。适用于阻挡昂贵或未审核的模型、强制统一模型规格,或将团队限定于单一供应商。
运作方式
- 三个独立层级 — 组织、团队、成员 — 各自维护一份清单(数据库中以 String[] 存储)。
- 三层皆为空时,所有模型皆可使用(默认行为)。
- 当一个或多个层级非空时,实际生效清单为各非空层级的交集 — 模型必须在所有受限层级都被允许才能通过。
- 变更于数秒内生效(60 秒内存缓存 + 5 分钟 Redis 缓存;更新时两者皆会清除)。
格式规则
- 精确匹配 — 例如 openai/gpt-4o(仅限此精确模型)。
- 供应商通配符 — 例如 openai/*(openai/ 前缀下的任何模型)。
- 仅限小写。每份清单最多 200 项,每项最多 100 字符。
管理位置
Org Portal → Allowed Models。org_admin 可编辑组织 / 团队 / 成员清单;team_admin 可编辑自己的团队及其下成员。
拦截时的错误响应
调用未允许的模型会返回 HTTP 403,body 如下:
管理 API
所有端点皆接受 Web Session 或 Bearer Management Key(sk-bl-...)。PATCH 会替换整份清单;传 [] 即可清空。
支出熔断(Spend Kill Switch)
双窗口支出上限,当上游成本飙升时阻挡后续请求。设计用于在失控脚本、无限循环或密钥被盗滥用造成实际损失之前及时拦截。
运作方式
- Redis 中按 scope 追踪两个固定窗口:1 分钟与 1 小时上游成本(USD)。
- 任一窗口的支出达到阈值时,该 scope 的后续请求皆会被拒绝,直到窗口于整点边界重置为止。
- 默认值:每分钟 $5、每小时 $20;默认不启用,需自行开启。
- 计数器存于 Redis 并设有 TTL — 自动恢复,组织 / 团队 / 成员等级触发后无需手动重置。
Scope(成员覆盖团队,团队覆盖组织)
每一层皆可设定自身阈值。解析顺序为 成员 → 团队 → 组织 → 平台默认 — 每个字段(cbEnabled、cbMinuteUsd、cbHourlyUsd)以第一个非 null 值为准。
- 组织层级 — 适用于该组织下的所有 key。在 Org Portal → Circuit Breaker 设定。
- 团队层级 — 适用于标记到该团队的所有 key。对这些 key 覆盖组织设定。
- 成员层级 — 仅适用于标记到该成员的 key。覆盖团队与组织设定。
触发行为
触发时请求会快速失败(不会发出上游调用)。响应为 HTTP 429,body 如下:
审计日志
每次触发事件与每次设定变更都会被记录:
- 触发事件 — 动作 org.cb.tripped / team.cb.tripped / org_member.cb.tripped。每个 scope+window 每小时去重为一笔,避免持续触发刷爆日志。
- 设定变更 — 动作 org.cb.update / team.cb.update / org_member.cb.update。记录变更前后的值与执行者。
管理 API
组织管理员可透过 API 读取与更新设定。所有端点皆接受 Web Session 或 Bearer Management Key(sk-bl-...)。PATCH body 可只送部分字段;传 null 会清空该字段并回退至上层设定。
API 密钥轮换
定期更换 API 密钥有助于安全。请先创建新密钥、更新并验证应用,再撤销旧密钥;此流程不保证零停机。
轮换步骤
- 建立新的 API 密钥
- 更新您的应用程式或环境变数使用新密钥
- 确认新密钥正常运作
- 停用或删除旧密钥
活动汇出
将完整 API 使用历史下载为 CSV,用于财务审计、成本分析或合规报告。
CSV 汇出
登入后前往「使用记录」页面,点击右上角的「Export CSV」按钮,即可下载完整历史记录为 CSV 档案。无需呼叫 API。
CSV 栏位
JSON 用量查询(API)
如需程式化存取,可透过 API 查询按期间、模型或密钥分组的聚合统计:
用量统计
透过 API 查询详细的使用量统计,包括 token 消耗、成本分析和请求历史记录。
回应栏位说明
| Field | Type | Description |
|---|---|---|
| model | string | Model ID used (e.g., openai/gpt-4o) |
| provider | string | 固定值:bazaarlink(BazaarLink) |
| prompt_tokens | number | Input tokens consumed |
| completion_tokens | number | Output tokens generated |
| total_tokens | number | Total tokens (prompt + completion) |
| reasoning_tokens | number | Reasoning tokens (for thinking models) |
| cached_tokens | number | Prompt tokens served from cache |
| cost | number | 本次请求向客户收取的美元金额 |
| duration_ms | number | End-to-end latency in milliseconds |
| throughput | number | Generation speed in tokens/sec |
| finish_reason | string | stop | length | content_filter | error |
| status | number | BazaarLink 响应状态码 |
| app_name | string | null | Application name (X-Title header) |
| key_name | string | API key name used for the request |
回报问题
透过回报问题、错误或建议帮助我们改善 BazaarLink。我们积极监控所有回馈管道。
如何回报
应包含的资讯
- 请求 ID(来自回应 id 栏位)
- 使用的模型和传送的参数
- 预期行为与实际行为
- 时间戳记和问题频率
- 错误讯息或 HTTP 状态码
社交数据(
:social)当问题与社交平台有关时,在模型名称后加上
:social。模型回答前,BazaarLink 会先获取该平台上相符的帖子、个人资料或评论,作为参考资料提供给模型。若平台数据未能及时获取,请求会回退到普通网页搜索,确保您仍能得到回答。示例
curl https://bazaarlink.ai/api/v1/chat/completions \ -H "Authorization: Bearer $BAZAARLINK_API_KEY" \ -H "Content-Type: application/json" \ --max-time 60 \ -d '{ "model": "gpt-5.4-mini:social", "messages": [{ "role": "user", "content": "X 上最近有哪些关于 GPT-6 的帖子?" }] }'注意事项
:social请求可能需要 20 至 40 秒才开始回答;超过 40 秒会回退到网页搜索。请将客户端超时设置为至少 60 秒。:online为普通网页搜索,速度不受影响。:online共用同一份每日免费搜索额度(没有余额时每天 5 次,有余额或订阅时每天 10 次,于 UTC 00:00 重置)。超过额度后,每次查询会按 Data API 价格表(见GET /v1/data/catalog)计费,并加上模型本身的 token 费用。回退到网页搜索的查询,计费方式与:online相同。:social只会读取部分社交平台,名单取决于当前启用的设置,最新名单见/solutions/data-api#social-suffix。列在 Data API 目录、但不在该名单上的平台不会被:social读取,与这些平台或没有指定平台有关的查询,会由网页搜索回答。POST /api/v1/chat/completions、/api/v1/messages和/api/v1/responses,流式与非流式均可,引用来源与:online相同。:online与:social不能同时用在同一个模型名称上(会返回 400invalid_web_search_options)。