BasicRouter 文件
快速入門
BasicRouter 為生產團隊提供一個穩定的 API,用於模型存取、路由、備援、使用量追蹤與基於積分的計費。LLM token 供應來自可信賴的企業雲端原廠帳號,閘道內建隱私保護、高穩定性與請求可追溯性。
https://api.basicrouter.ai/apihttps://api.basicrouter.ai/api/v1https://api.basicrouter.ai/api/v1Authorization: Bearer <key>建立 API 密鑰
在控制台中建立 BasicRouter API 密鑰。請將密鑰保存在您的伺服器上,切勿在瀏覽器或行動用戶端程式碼中暴露。
建議的密鑰策略:
| 密鑰類型 | 建議用途 |
|---|---|
| 開發密鑰 | 本地開發、預備環境、測試與原型。 |
| 生產密鑰 | 僅用於後端生產環境工作負載。 |
| 整合密鑰 | 用於 Cursor、Claude Code、Codex、Hermes 或 OpenClaw 等工具的專用密鑰。 |
| 客戶/租戶密鑰 | 為企業客戶、租戶流量或業務單位提供可選的密鑰隔離。 |
當團隊存取權限變更時請輪替密鑰。撤銷不再使用的密鑰。
將您的 SDK 指向 BasicRouter
大多數 OpenAI 相容用戶端只需要新的 base URL 與 API 密鑰。
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.BASICROUTER_API_KEY,
baseURL: "https://api.basicrouter.ai/api/v1"
});
傳送聊天補全
curl --request POST \
--url https://api.basicrouter.ai/api/v1/chat/completions \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "claude-sonnet-5",
"messages": [
{ "role": "user", "content": "Explain BasicRouter in one sentence." }
]
}'
查看使用量與餘額
curl --request GET \
--url https://api.basicrouter.ai/api/v1/billing/balance \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
模型發現
使用模型頁面或模型 API 來檢視可用的文字模型。模型中繼資料包含供應商、服務提供商、模態、上下文長度、支援的 API 家族、支援的能力、可用性、帳號層級限制與積分定價。
端點: GET /v1/models
用途:列出當前帳號可用的模型。
curl --request GET \
--url https://api.basicrouter.ai/api/v1/models \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
能力矩陣
| 能力 | 說明 | 常見使用者 |
|---|---|---|
streaming | 支援伺服器推送事件串流。 | 聊天應用、程式碼代理、即時 UX。 |
tool_calling | 支援工具或函式呼叫。 | 代理、工作流程自動化、程式碼助手。 |
structured_outputs | 支援結構描述限制或 JSON 輸出。 | 資料萃取、工作流程自動化、企業應用。 |
json_mode | 可回傳 JSON 格式輸出。 | 輕量級結構化回應。 |
vision | 接受圖像輸入。 | 多模態聊天、UI 分析、文件截圖。 |
prompt_caching | 支援快取輸入或上下文重用。 | 長上下文代理、重複的系統提示。 |
reasoning | 在可用時支援明確的推理控制。 | 複雜規劃、程式碼、分析工作流程。 |
logprobs | 支援 token 機率輸出。 | 評估、排序、進階 NLP 工作流程。 |
API 家族相容性矩陣
| API 家族 | 文字 | 視覺輸入 | 工具呼叫 | 結構化輸出 | 串流 | 備註 |
|---|---|---|---|---|---|---|
| OpenAI Chat Completions | 是 | 視模型而定 | 視模型而定 | 視模型而定 | 是 | OpenAI 相容代理與 SDK 的最佳預設。 |
| OpenAI Responses | 是 | 視模型而定 | 視模型而定 | 視模型而定 | 是 | 建議用於較新的 OpenAI 風格代理工作流程。 |
| Anthropic Messages | 是 | 視模型而定 | 視模型而定 | 視模型而定 | 是 | 最適合 Claude 相容用戶端與 Claude Code。 |
| BasicRouter image generation | 否 | 視模型而定 | 否 | 否 | 否 | 使用非同步任務輪詢或 webhook。 |
| BasicRouter video generation | 否 | 視模型而定 | 否 | 否 | 否 | 使用非同步任務輪詢或 webhook。 |
驗證
每個 API 請求都使用 bearer token。請將密鑰儲存在伺服器端環境變數中,在團隊存取權限變更時輪替,並記錄請求 ID 以供除錯。
| 標頭 | 值 | 備註 |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | 每個請求都需要。 |
Content-Type | application/json | JSON 請求主體需要。 |
密鑰安全建議
- 將 API 密鑰保存在伺服器上。切勿在瀏覽器或行動用戶端程式碼中暴露密鑰。
- 為開發、預備、生產與第三方整合使用不同的密鑰。
- 在可用時依環境、服務、客戶或租戶為密鑰設定範圍。
- 在員工離職、供應商存取權限變更或疑似洩漏後輪替密鑰。
- 將密鑰儲存在密鑰管理器或環境變數中,而非原始碼中。
程式碼代理
BasicRouter 可與支援 OpenAI 相容或 Anthropic 相容 API 端點的程式碼代理與 AI
開發工具搭配使用。使用如 mwf/coding-auto 等路由別名,讓 BasicRouter
能路由到最佳可用的程式碼模型,而無需開發者變更工具設定。
一般 OpenAI 相容設定
將此設定用於 Cursor、Codex、Hermes、OpenClaw、Continue、Aider、Cline、 基於 LangChain 的代理、基於 LlamaIndex 的代理,以及自訂的 OpenAI 相容代理執行環境。
export OPENAI_BASE_URL="https://api.basicrouter.ai/api/v1"
export OPENAI_API_KEY="$BASICROUTER_API_KEY"
export OPENAI_MODEL="mwf/coding-auto"
一般 Anthropic 相容設定
將此設定用於 Claude 相容用戶端與預期 Anthropic Messages 格式的工具。
export ANTHROPIC_BASE_URL="https://api.basicrouter.ai/api/anthropic"
export ANTHROPIC_API_KEY="$BASICROUTER_API_KEY"
export ANTHROPIC_MODEL="mwf/coding-auto"
建議的代理模型
| 使用情境 | 建議別名 | 需求 |
|---|---|---|
| 一般程式碼 | mwf/coding-auto | 工具呼叫、串流、強大的程式碼能力。 |
| 快速程式碼聊天 | mwf/coding-fast | 低延遲與串流。 |
| 大型儲存庫分析 | mwf/coding-long | 長上下文與穩定輸出。 |
| 成本敏感的程式碼助手 | mwf/low-cost | 較低價格與可接受的程式碼品質。 |
| UI 截圖/視覺程式碼 | mwf/vision-chat | 視覺輸入與文字輸出。 |
Cursor 快速指南
使用 OpenAI 相容端點。
Base URL: https://api.basicrouter.ai/api/v1
API Key: BASICROUTER_API_KEY
Model: mwf/coding-auto
建議步驟:
- 開啟 Cursor 設定。
- 新增或啟用 OpenAI 相容 API 密鑰設定。
- 將 OpenAI base URL 覆寫設為
https://api.basicrouter.ai/api/v1。 - 新增自訂模型,如
mwf/coding-auto、mwf/coding-fast或mwf/coding-long。 - 使用支援串流與工具呼叫的模型以獲得最佳代理行為。
疑難排解:
| 問題 | 建議修正 |
|---|---|
| 模型未顯示 | 手動將模型名稱新增為自訂模型。 |
| 工具呼叫失敗 | 在模型頁面使用具有 tool_calling: true 的模型。 |
| 串流中斷 | 使用退避重試或使用具有備援的路由別名。 |
| 401 錯誤 | 檢查 API 密鑰與 base URL。 |
| 404 模型錯誤 | 確認該模型已為帳號啟用。 |
Claude Code 快速指南
使用 Anthropic 相容閘道端點。
export ANTHROPIC_BASE_URL="https://api.basicrouter.ai/api/anthropic"
export ANTHROPIC_API_KEY="$BASICROUTER_API_KEY"
export ANTHROPIC_MODEL="mwf/coding-auto"
BasicRouter 支援此 Anthropic 相容路徑,用於 Claude Code 與 Anthropic SDK 相容性:
POST /api/v1/messages
建議需求:
| 需求 | 原因 |
|---|---|
| Anthropic Messages 相容請求結構 | Claude Code 預期 Anthropic 風格訊息。 |
| 串流支援 | Claude Code 依賴串流 UX。 |
| 工具呼叫支援 | 代理程式碼工作流程所需。 |
| 長上下文 | 對儲存庫層級任務有用。 |
| 穩定備援 | 對長時間執行的程式碼工作階段有用。 |
Codex 快速指南
將 BasicRouter 作為自訂 OpenAI 相容模型提供商使用。
範例提供商設定:
[model_providers.basicrouter]
name = "BasicRouter"
base_url = "https://api.basicrouter.ai/api/v1"
env_key = "BASICROUTER_API_KEY"
wire_api = "responses"
model_provider = "basicrouter"
model = "mwf/coding-auto"
環境變數:
export BASICROUTER_API_KEY="br_xxx"
建議模型:
| 模型 | 使用情境 |
|---|---|
mwf/coding-auto | 預設程式碼代理模型。 |
mwf/coding-long | 大型儲存庫上下文。 |
mwf/coding-fast | 快速迭代與小幅變更。 |
疑難排解:
| 問題 | 建議修正 |
|---|---|
| 驗證錯誤 | 確認 env_key 指向 BASICROUTER_API_KEY。 |
| 找不到模型 | 在 BasicRouter 控制台新增別名或使用直接模型 ID。 |
| Responses API 錯誤 | 僅對支援 Responses 的模型與端點使用
wire_api = "responses"。 |
| 僅支援 Chat Completions 的模型 | 若用戶端支援,切換為 chat 相容的 wire API。 |
Hermes 快速指南
使用 OpenAI 相容端點,除非您的 Hermes 部署已設定為其他協定。
export OPENAI_BASE_URL="https://api.basicrouter.ai/api/v1"
export OPENAI_API_KEY="$BASICROUTER_API_KEY"
export OPENAI_MODEL="mwf/coding-auto"
建議模型策略:
| Hermes 工作負載 | 模型 |
|---|---|
| 一般程式碼生成 | mwf/coding-auto |
| 低延遲任務執行 | mwf/coding-fast |
| 長上下文儲存庫掃描 | mwf/coding-long |
| 成本敏感的背景任務 | mwf/low-cost |
OpenClaw 快速指南
使用 OpenAI 相容端點進行 OpenAI 風格代理執行環境設定。
export OPENAI_BASE_URL="https://api.basicrouter.ai/api/v1"
export OPENAI_API_KEY="$BASICROUTER_API_KEY"
export OPENAI_MODEL="mwf/coding-auto"
若 OpenClaw 支援多個提供商,請將 BasicRouter 設定為 OpenAI 相容提供商,並使用 BasicRouter 路由別名進行模型選擇。
{
"provider": "openai-compatible",
"base_url": "https://api.basicrouter.ai/api/v1",
"api_key_env": "BASICROUTER_API_KEY",
"model": "mwf/coding-auto"
}
代理相容性檢查清單
| 能力 | 所需用途 |
|---|---|
| 串流 | 良好的終端機/編輯器 UX。 |
| 工具呼叫 | 代理程式碼、檔案編輯、命令執行。 |
| 長上下文 | 大型儲存庫與多檔案變更。 |
| 結構化輸出 | 規劃、任務分解、自動化工作流程。 |
| 視覺輸入 | UI 截圖分析與設計轉程式碼工作流程。 |
| 備援 | 生產穩定性與長時間執行的任務。 |
使用控制台
BasicRouter 控制台是 API 存取、模型可用性、路由策略、使用量可見性與帳單管理的營運控制平面。它為帳號管理員提供密鑰、模型、請求、積分與帳號層級控制的集中檢視,用於生產模型流量。
管理 API 密鑰
從控制台建立、輪替、撤銷與標記 API 密鑰。為開發、預備、生產與個別服務使用不同的密鑰,以便使用量可被稽核並依環境或應用隔離。
| 做法 | 說明 |
|---|---|
| 區隔環境 | 為開發、預備與生產流量使用不同的 API 密鑰。 |
| 使用描述性標籤 | 依應用、服務、環境或整合為密鑰加上標籤。 |
| 定期輪替 | 在存取權限變更或憑證可能已暴露時輪替密鑰。 |
| 避免用戶端暴露 | 僅將 API 密鑰保存在伺服器端系統。切勿在瀏覽器或行動用戶端程式碼中暴露密鑰。 |
| 監控密鑰使用量 | 依密鑰檢視請求量、積分消耗與錯誤模式。 |
模型列表
使用模型頁面檢視帳號可用的模型。每個模型項目可能包含供應商、服務提供商、模態、支援的 API 家族、上下文長度、能力旗標、可用性狀態與定價資訊。
| 篩選器 | 用途 |
|---|---|
| 供應商 | 依模型供應商篩選,如 OpenAI、Anthropic、Google、Qwen、DeepSeek 或其他提供商。 |
| 提供商 | 依服務提供商或雲端提供商篩選。 |
| 模態 | 依文字、圖像、影片、嵌入、音訊或多模態支援篩選。 |
| 能力 | 依串流、工具呼叫、結構化輸出、視覺、提示快取或推理支援篩選。 |
| 可用性 | 識別當前帳號可用的模型。 |
對於生產應用,在啟用流量前請驗證模型能力。部分參數與功能視模型而定,可能無法在所有 API 家族中支援。
使用量與日誌
使用量與日誌檢視提供 API 流量的營運可見性。團隊可以檢視請求量、選定的模型、解析的路由目標、積分消耗、延遲、錯誤碼與請求 ID。
- 疑難排解失敗的請求。
- 識別高成本工作負載。
- 比較跨應用與環境的模型使用量。
- 驗證路由與備援行為。
- 調查延遲或提供商可用性問題。
- 聯繫支援時提供請求 ID。
每個 API 回應包含或暴露 BasicRouter 請求 ID。請將此 ID 儲存在您的應用日誌中,以提升生產除錯與支援升級效率。
備援
備援是 BasicRouter 的韌性機制。當主要模型或路由策略失敗時,系統會自動切換到備援模型以繼續處理請求。這讓您的應用保持回應能力並將服務中斷風險降至最低。
備援就像安全網,即使發生模型故障、配額限制或網路波動,也能讓您的應用順利運行。
為何備援很重要
在生產環境中,模型服務可能遇到許多無法預測的問題:
- 模型服務故障:上游 API 暫時不可用或逾時。
- 效能波動:模型高負載導致回應緩慢或失敗。
- 路由失敗:智慧路由選擇的所有候選模型都不可用。
備援透過提供可靠的備援路徑來保持您的應用可用。
核心優勢
| 優勢 | 說明 |
|---|---|
| 高可用性 | 自動故障轉移讓服務持續運行並減少中斷影響。 |
| 透明切換 | 系統自動切換模型 — 無需變更應用程式碼。 |
| 彈性設定 | 支援每個請求與帳號層級設定,以適應不同使用情境。 |
| 成本最佳化 | 選擇更具成本效益的模型作為備援以控制緊急成本。 |
| 集中管理 | 在帳號層級設定一次,即自動套用至每個請求。 |
全域備援模型設定
BasicRouter 支援從控制台後端設定全域備援模型。所有請求在失敗時自動使用此模型作為備援。
如何設定:
- 前往 BasicRouter 策略設定頁面。
- 找到預設備援模型設定。
- 從下拉清單中選擇您的全域備援模型。
- 儲存設定以立即套用。
全域設定的優勢:
- 無需程式碼變更:設定一次即全域套用,無需在每個請求上重複設定。
- 集中管理:在一處管理備援策略,便於調整與監控。
- 簡化維護:降低程式碼複雜度與設定錯誤的機率。
- 彈性覆寫:請求層級備援設定具有優先權,可為特定情境覆寫全域設定。
請求層級備援設定
對於特定業務情境,您可以在個別請求上指定備援模型以覆寫全域設定。
使用 router.fallBackModels 參數指定備援模型:
{
"model": "claude-sonnet-4",
"messages": [
{
"role": "user",
"content": "Explain what quantum computing is"
}
],
"router": {
"fallBackModels": ["glm-5.2"]
}
}
優先權規則
當存在多個備援設定時,優先權從高到低為:
- 請求層級
router.fallBackModels:在個別請求上指定的備援模型。 - 全域預設備援模型:在控制台設定的全域備援模型。
- 無備援:若兩者皆未設定,請求失敗時回傳錯誤。
- 若所有備援模型都失敗,系統會回傳最後嘗試模型的失敗原因。
- 發生備援時,回應會指出實際使用的模型,便於監控與分析。
帳號管理
依帳號類型而定,控制台可能包含帳號層級模型啟用、經銷商或分銷商控制、帳單設定與存取設定。管理員可使用這些控制,使模型存取、使用量可見性與帳單責任與應用、客戶帳號或業務單位一致。
生產營運檢查清單
| 項目 | 建議 |
|---|---|
| API 密鑰 | 使用具有清晰標籤的專用生產密鑰。 |
| 模型 | 確認模型可用性、定價、上下文長度與所需能力。 |
| 路由 | 為關鍵工作負載設定路由別名或備援策略。 |
| 日誌 | 確保請求 ID 被擷取到應用日誌中。 |
| 帳單 | 確認錢包餘額、方案狀態與積分扣費規則。 |
| 速率限制 | 檢視帳號層級 RPM、TPM、併發與媒體任務限制。 |
| 警示 | 監控使用量成長、積分餘額、錯誤與提供商可用性。 |
帳單與積分
BasicRouter 在文字、圖像、影片與其他支援的模型工作負載中使用基於積分的計費模型。積分為多模型與多提供商使用量提供統一單位,讓團隊能跨模態與 API 家族一致地管理消耗。
詳細的模型定價可在模型頁面或透過模型中繼資料 API 取得。定價可能因模型、提供商、模態、解析度、token 類型、輸出長度、任務時長、帳號類型與商業協議而異。
儲值與錢包
帳號可新增按量付費錢包積分以獲得彈性使用量。除非帳號套用了自訂帳單規則,否則錢包積分會在月費方案積分與資源包消耗完畢後使用。
除非適用的商業條款另有規定,錢包積分不會過期。儲值按量付費錢包時會收取服務費。
月費方案與資源包
每個使用者或帳號可選擇一個有效的月費方案。月費方案為計費週期提供定義的使用量容量、商業條款與帳號層級存取設定。
使用者也可購買多個資源包以獲得額外使用量容量。資源包可將承諾使用量與按量付費錢包餘額分開,適用於大量文字、圖像、影片或專用工作負載使用量。
扣費順序
除非設定了自訂帳單規則,否則積分按以下順序扣費:
| 優先順序 | 積分來源 | 說明 |
|---|---|---|
| 1 | 月費方案 | 包含的月度使用量容量最先消耗。 |
| 2 | 資源包 | 額外購買的包在月費方案積分之後消耗。 |
| 3 | 按量付費錢包 | 錢包餘額在方案與資源包積分之後消耗。 |
對於具有自訂商業條款的帳號,扣費順序、過期規則、包含的使用量與定價可能不同。帳號專屬規則會顯示在控制台或透過商業協議提供。
自訂定價
可為每個使用者或帳號自訂定價。企業客戶、經銷商帳號、分銷商帳號與高用量客戶可能符合自訂定價資格。請聯繫業務團隊取得報價。
自訂定價可依帳號、模型、提供商、模態、地區、使用量或商業協議設定。啟用自訂定價時,控制台與帳單 API 會在可用時反映帳號專屬定價與扣費規則。
定價單位
不同模型模態使用不同的計量單位。BasicRouter 依據模型的定價規則將這些單位轉換為積分。
| 模態 | 常見計價基礎 |
|---|---|
| 文字 | 輸入 token、輸出 token、快取讀取 token、快取寫入 token、推理 token 或模型專屬 token 類別。 |
| 圖像 | 模型、解析度、生成圖像數量、輸入圖像使用量、編輯模式或品質設定。 |
| 影片 | 模型、輸出解析度、生成秒數、寬高比、輸入圖像或影片使用量與任務類型。 |
| 嵌入 | 輸入 token 或嵌入記錄數量。 |
| 音訊 | 輸入時長、輸出時長、轉錄長度或模型專屬音訊單位。 |
定價單位可能因模型而異。在生產環境中啟用模型前,請務必參考模型詳情頁或定價中繼資料。
使用量歸因
BasicRouter 使用量可依帳號、API 密鑰、模型、模態或時間範圍檢視。這讓團隊能將成本歸因於應用、環境、客戶或內部業務單位。
| 維度 | 說明 |
|---|---|
| API 密鑰 | 依應用、服務或環境分組使用量。 |
| 模型 | 依選定模型比較成本與量。 |
| 解析後模型 | 檢視路由或備援後實際使用的模型。 |
| 模態 | 區分文字、圖像、影片、嵌入與音訊使用量。 |
| 時間範圍 | 檢視每日、每月或自訂報告週期。 |
| 中繼資料 | 依自訂請求中繼資料(如客戶 ID、租戶 ID、使用者 ID 或環境)分組使用量。 |
積分餘額
查看您帳號中可用的積分數量。餘額分為三個按順序扣費的錢包:月費方案積分、購買的資源包與按量付費錢包。另提供合併資源總額(月費方案 + 資源包,不含按量付費),以便將包含使用量與儲值支出分開追蹤。
若要以程式方式取得此資訊,請參見 API 參考中的
GET /v1/billing/balance。
使用量詳情
檢視個別使用量記錄的分頁時間序列清單,用於報告、監控與內部成本分攤。每筆記錄顯示模型、模型類型(文字、圖像或影片)、扣減的積分,以及每筆扣費從哪個錢包提取的明細。結果可篩選至特定時間範圍。
若要以程式方式取得此資訊,請參見 API 參考中的
GET /v1/usage。
交易紀錄
使用交易紀錄檢視積分變動,包含儲值、方案分配、資源包授予、使用量扣費、調整與管理修正。
若要以程式方式取得此資訊,請參見 API 參考中的
GET /v1/billing/transactions。
失敗請求與退款
驗證錯誤、身分驗證錯誤與權限錯誤通常不予計費,因為未發生模型執行。到達上游模型或產生部分輸出的請求可能會消耗積分,視模型、提供商與回應狀態而定。
對於非同步圖像與影片任務,計費行為取決於任務是否已被接受、啟動、完成、失敗或取消。任務詳情回應在已消耗積分時包含使用量資訊。
儲值、月費方案、資源包與已消耗積分不可退費,除非適用的商業協議另有規定或法律要求。
API 參考
通用慣例
Base URL
所有端點皆在 /v1 前綴下提供。
驗證
對 /v1/* 端點的呼叫使用 API Key 驗證(非 JWT)。API Key
透過以下標頭傳遞:
| 標頭 | 格式 | 說明 |
|---|---|---|
Authorization | Bearer <api_key> | OpenAI 風格。Anthropic 相容端點也接受 x-api-key 與
anthropic-version: 2023-06-01。 |
缺少或無效的密鑰回傳 401。
餘額預檢
所有模型呼叫端點在執行前執行餘額預檢:
- 餘額不足回傳
Insufficient credit,對應為:- OpenAI 協定:HTTP
400,code = insufficient_quota - Anthropic 協定:HTTP
402,type = billing_error
- OpenAI 協定:HTTP
- 部分端點也會為每個模型估算最低成本以進行第二次預檢。
POST https://api.basicrouter.ai/api/v1/chat/completions
OpenAI Chat Completions 相容端點。支援串流與非串流、工具呼叫、JSON 模式與多模態輸入。
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
model | String | 是 | 模型名稱。 |
messages | Message[] | 是 | 對話訊息。 |
stream | Boolean | 否 | Stream mode, default false. |
temperature | Double | 否 | 取樣溫度。 |
max_tokens | Integer | 否 | 最大輸出 token 數。 |
top_p | Double | 否 | 核取樣。 |
presence_penalty | Double | 否 | — |
frequency_penalty | Double | 否 | — |
tools | Tool[] | 否 | 工具定義。 |
tool_choice | String|Object | 否 | auto / none / required / specific
function. |
response_format | Object | 否 | {type, json_schema:{name,schema,strict}};
text/json_object/json_schema. |
parallel_tool_calls | Boolean | 否 | — |
metadata | Map | 否 | 透傳中繼資料。 |
Message 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
role | String | system / user / assistant /
tool. |
content | String|Array | Plain text or multimodal content block array
([{type:"text",text},{type:"image_url",image_url:{url}}]). |
tool_call_id | String | Links to the tool_calls when role=tool. |
tool_calls | ToolCall[] | Present when role=assistant makes tool calls. |
| 欄位 | 類型 | 說明 |
|---|---|---|
type | String | 固定 function。 |
function | Object | 函式定義。 |
function.name | String | 函式名稱。 |
function.description | String | 函式說明。 |
function.parameters | Object | 輸入的 JSON Schema。 |
curl --request POST \
--url https://api.basicrouter.ai/api/v1/chat/completions \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "glm-5.2",
"messages": [{"role": "user", "content": "Describe Hangzhou in one sentence."}],
"stream": false,
"temperature": 0.7
}'
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1721380000,
"model": "glm-5.2",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "Hangzhou is ..."},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 12, "completion_tokens": 18, "total_tokens": 30}
}
回應欄位(非串流):
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 補全 ID。 |
object | String | 固定 chat.completion。 |
created | Long | 建立時間戳記(秒)。 |
model | String | 模型名稱。 |
choices | Choice[] | {index, message:{role, content, tool_calls?}, finish_reason}. |
usage | Object | {prompt_tokens, completion_tokens, total_tokens}. |
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 工具呼叫 ID。 |
type | String | 固定 function。 |
function | Object | 函式呼叫詳情。 |
function.name | String | 函式名稱。 |
function.arguments | Object | 函式引數。 |
串流回應範例:
data: {"object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant","content":"..."}}]}
data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"..."}}]}
data: [DONE]
POST https://api.basicrouter.ai/api/v1/responses
OpenAI Responses 相容端點。使用 input 代替 messages,使用
instructions 代替系統訊息,並使用 text 區塊代替
response_format。
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
model | String | 是 | 模型名稱。 |
input | String|Array | 是 | 純字串(使用者訊息)或訊息物件陣列。 |
instructions | String | 否 | 系統提示。 |
stream | Boolean | 否 | 預設 false。 |
max_output_tokens | Integer | 否 | 最大輸出 token 數。 |
temperature | Double | 否 | 預設 1。 |
top_p | Double | 否 | — |
tools | Tool[] | 否 | Top-level {type, name, description, parameters}. |
tool_choice | String|Object | 否 | auto/none/required/{type,name}. |
text | Object | 否 | {format:{type, name, schema, strict}};
text/json_object/json_schema. |
metadata | Map | 否 | — |
previous_response_id | String | 否 | 多輪對話的前一回應 ID。 |
parallel_tool_calls | Boolean | 否 | — |
curl --request POST \
--url https://api.basicrouter.ai/api/v1/responses \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "glm-5.2",
"input": "Describe Hangzhou in one sentence.",
"instructions": "Be concise.",
"stream": false
}'
{
"id": "resp_xxx",
"object": "response",
"model": "glm-5.2",
"status": "completed",
"created_at": 1721380000,
"output": [
{
"id": "msg_xxx",
"type": "message",
"role": "assistant",
"content": [{"type": "output_text", "text": "Hangzhou is ..."}],
"status": "completed"
}
],
"usage": {"input_tokens": 12, "output_tokens": 18, "total_tokens": 30}
}
回應欄位(非串流):
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 回應 ID。 |
object | String | Fixed response. |
model | String | 模型名稱。 |
status | String | e.g. completed. |
created_at | Long | 建立時間戳記(秒)。 |
output | Array | Output items. Message items:
{id, type:"message", role, content:[{type:"output_text",
text}], status}. Tool-call items:
{type:"function_call", id, name, call_id, arguments, status}. |
usage | Object | {input_tokens, output_tokens, total_tokens}. For Claude models,
input_tokens includes cache_read and
output_tokens includes cache_write. |
串流遵循 Responses API 事件:
| 事件 | 說明 |
|---|---|
response.created | 回應串流的開始。 |
response.output_text.delta | 增量文字輸出更新。 |
response.completed | 回應串流的結束。 |
POST https://api.basicrouter.ai/api/v1/messages
Anthropic Messages 相容端點。接受 x-api-key 與
anthropic-version: 2023-06-01 標頭。內容區塊支援
text、image、tool_use、tool_result、
thinking 與 redacted_thinking。
| 欄位 | 類型 | 必填 | JSON 欄位 | 說明 |
|---|---|---|---|---|
model | String | 是 | model | 模型名稱。 |
messages | Message[] | 是 | messages | 對話訊息。 |
system | String|Array | 否 | system | 系統提示,字串或 [{type,text}]。 |
maxTokens | Integer | 是 | max_tokens | 最大輸出 token 數。 |
stream | Boolean | 否 | stream | 串流。 |
temperature | Double | 否 | temperature | — |
topP | Double | 否 | top_p | — |
topK | Integer | 否 | top_k | — |
tools | Tool[] | 否 | tools | 工具定義(input_schema)。 |
toolChoice | Object | 否 | tool_choice | — |
metadata | Map | 否 | metadata | — |
thinking | Object | 否 | thinking | 擴充思考設定。 |
stopSequences | Object | 否 | stop_sequences | — |
anthropicBeta | Object | 否 | anthropic_beta | Beta 功能標頭。 |
| 欄位 | 類型 | 說明 |
|---|---|---|
role | String | 訊息角色,例如 user / assistant。 |
content | String|ContentBlock[] | 純文字或內容區塊陣列。 |
| 欄位 | 類型 | 說明 |
|---|---|---|
type | String | One of text, image, tool_use,
tool_result, thinking,
redacted_thinking. |
text | String | 類型為 text 時出現。 |
source | Object | 類型為 image 時出現。 |
圖像區塊範例:
{ "type": "image", "source": { "type": "base64", "media_type": "...", "data": "..." } }
{ "type": "image", "source": { "type": "url", "url": "..." } }
| 欄位 | 類型 | 說明 |
|---|---|---|
name | String | 函式名稱。 |
description | String | 函式說明。 |
input_schema | Object | 輸入的 JSON Schema。 |
cache_control | Object | 可選的快取控制。 |
curl --request POST \
--url https://api.basicrouter.ai/api/v1/messages \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "Content-Type: application/json" \
--data '{
"model": "claude-sonnet-4.6",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Describe Hangzhou in one sentence."}]
}'
{
"id": "msg_xxx",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4.6",
"content": [{"type": "text", "text": "Hangzhou is ..."}],
"stop_reason": "end_turn",
"usage": {"input_tokens": 12, "output_tokens": 18}
}
回應欄位(非串流):
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 訊息 ID。 |
type | String | 固定 message。 |
role | String | 固定 assistant。 |
model | String | 模型名稱。 |
content | ContentBlock[] | Response content blocks (e.g. {type:"text", text},
{type:"tool_use", ...}). |
stop_reason | String | e.g. end_turn, tool_use, max_tokens. |
usage | Object | {input_tokens, output_tokens}. |
| 事件 | 說明 |
|---|---|
message_start | 訊息串流的開始。 |
content_block_start | 新內容區塊的開始。 |
content_block_delta | 內容區塊的增量更新。 |
content_block_stop | 內容區塊的結束。 |
message_delta | 訊息的增量更新。 |
message_stop | 訊息串流的結束。 |
GET https://api.basicrouter.ai/api/v1/models
回傳所有上線、已啟用的 API 模型。
curl --request GET \
--url https://api.basicrouter.ai/api/v1/models \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
{
"object": "list",
"data": [
{
"id": "glm-5.2",
"object": "model",
"display_name": "glm-5.2",
"created": 1721380000,
"owned_by": "Zai",
"input_modalities": ["text", "image"],
"output_modalities": ["text"],
"context_length": 128000
}
]
}
每個模型項目(data[])欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 模型 ID。 |
object | String | Fixed model. |
display_name | String | 顯示名稱。 |
created | Long | 建立時間戳記(秒)。 |
owned_by | String | Owner / vendor. |
input_modalities | String[] | e.g. ["text","image"]. |
output_modalities | String[] | e.g. ["text"]. |
context_length | Integer | 最大上下文長度。 |
GET https://api.basicrouter.ai/api/v1/models/{model}
Returns a single model with the same shape as a list entry. Returns HTTP 404 when the model does not exist.
curl --request GET \
--url https://api.basicrouter.ai/api/v1/models/gpt-5.5 \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
Success response: a single model object with the same fields as a
/v1/models list entry.
當模型不存在時,回傳 HTTP 404:
{"error": {"message": "The model 'xxx' does not exist", "type": "invalid_request_error", "code": "invalid_model_error"}}
GET https://api.basicrouter.ai/api/v1/image-models
在呼叫
/v1/image-generations
前,查詢圖像模型支援的解析度、比例與最大數量。無需驗證。
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 模型 ID。 |
object | String | 固定 image_model。 |
displayName | String | 顯示名稱。 |
description | String | 模型說明。 |
icon | String | 圖示 URL。 |
created | Long | 建立時間戳記(秒)。 |
maxCount | Integer | 每次請求最大圖像數。 |
fileMax | Integer | 最大參考圖像數。 |
resolutions | String[] | 支援的解析度,例如 ["720p","1080p"]。 |
ratios | String[] | 支援的寬高比,例如 ["1:1","3:2"]。 |
curl --request GET \
--url https://api.basicrouter.ai/api/v1/image-models \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
{
"object": "list",
"data": [
{
"id": "gpt-image-2",
"object": "image_model",
"displayName": "GPT Image 1",
"description": "...",
"icon": "...",
"created": 1721380000,
"maxCount": 4,
"fileMax": 10,
"resolutions": ["720p", "1080p"],
"ratios": ["1:1", "3:2"]
}
]
}
GET https://api.basicrouter.ai/api/v1/video-models
在呼叫 /v1/video-generations 前,查詢影片模型支援的
videoType 值、時長範圍、解析度與比例。無需驗證。
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 模型 ID。 |
object | String | 固定 video_model。 |
displayName | String | 顯示名稱。 |
description | String | 模型說明。 |
icon | String | 圖示 URL。 |
created | Long | 建立時間戳記(秒)。 |
allowedVideoTypes | VideoTypeOption[] | Supported videoType list. |
videoDurationMin | Integer | 每個片段最小秒數。 |
videoDurationMax | Integer | 每個片段最大秒數。 |
videoDurationSuggest | Integer[] | 建議的時長步進,例如 [5,8,10]。 |
resolutions | String[] | 支援的解析度。 |
ratios | String[] | 支援的寬高比。 |
resolutionOptions | ResolutionOption[] | 結構化的解析度+寬高比+尺寸組合。 |
fileMax | Integer | 最大參考資產數。 |
VideoTypeOption 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
code | Integer | 傳遞給 /v1/video-generations 的 videoType 值。 |
name | String | 本地化類型名稱(文生影片 / 圖生影片 / ...)。 |
curl --request GET \
--url https://api.basicrouter.ai/api/v1/video-models \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
{
"object": "list",
"data": [
{
"id": "sora-2",
"object": "video_model",
"displayName": "Sora 2",
"description": "...",
"icon": "...",
"created": 1721380000,
"allowedVideoTypes": [
{"code": 1, "name": "text-to-video"},
{"code": 2, "name": "image-to-video"},
{"code": 3, "name": "image-to-video (first/last frame)"}
],
"videoDurationMin": 5,
"videoDurationMax": 10,
"videoDurationSuggest": [5, 8, 10],
"resolutions": ["1080p", "720p"],
"ratios": ["16:9", "9:16"],
"fileMax": 5
}
]
}
POST https://api.basicrouter.ai/api/v1/image-generations
非同步提交圖像生成任務。立即回傳 taskId;透過輪詢
GET /v1/image-generations/{taskId} 或透過 callbackUrl webhook
取得結果。
model、支援的 resolution / ratio 值、
count 上限以及參考圖像上傳限制(fileMax)必須先從
GET /v1/image-models
取得。僅接受該模型規格宣告的值。
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
text | String | 是 | 提示詞。 |
model | String | 是 | 模型名稱。 |
imageUrls | String[] | 否 | 參考圖像 URL(圖生圖)。 |
count | Integer | 否 | 圖像數量(≥0)。 |
resolution | String | 否 | 解析度(參見 /v1/image-models)。 |
ratio | String | 否 | 寬高比。 |
callbackUrl | String | 否 | 任務級 webhook URL。 |
curl --request POST \
--url https://api.basicrouter.ai/api/v1/image-generations \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "seedream-4.5",
"text": "A cat drinking water by the river",
"count": 1,
"resolution": "2k",
"ratio": "1:1",
"imageUrls": []
}'
{
"code": 200,
"message": "image task is commit",
"data": {"taskId": "img_xxx"}
}
錯誤回應:
// Insufficient credit
{ "code": 500, "message": "Insufficient credit" }
// Model not found
{ "code": 404, "message": "Model not found: xxx" }
GET https://api.basicrouter.ai/api/v1/image-generations/{taskId}
輪詢圖像生成任務。status 為 pending / success /
failed。images 是圖像 URL 陣列的 JSON 字串;text
帶有模型附加的任何文字描述(例如 Gemini 多模態輸出),否則為 null。
curl --request GET \
--url https://api.basicrouter.ai/api/v1/image-generations/img_xxx \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
{
"code": 200,
"message": "success",
"data": {
"taskId": "img_xxx",
"status": "success",
"errorMessage": null,
"images": "[\"https://.../1.png\"]",
"text": null
}
}
回應 data 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
taskId | String | 任務 ID。 |
status | String | pending / success / failed. |
errorMessage | String | 失敗原因,成功時為 null。 |
images | String | JSON 字串化的圖像 URL 陣列,例如
"[\"https://.../1.png\"]"。 |
text | String | 模型附加的文字描述(例如 Gemini 多模態輸出);否則為 null。 |
找不到任務:
{ "code": 500, "message": "task not found" }
若提交時提供了 callbackUrl,伺服器會透過 webhook 推送最終的
success / failed 結果,data 結構相同。
完整範例(提交 + 輪詢)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class ImageGenerationExample {
private static final String BASE = "https://api.basicrouter.ai/api/v1";
private static final String API_KEY = System.getenv("BASICROUTER_API_KEY");
public static void main(String[] args) throws Exception {
HttpClient http = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10)).build();
// 1. Submit the task.
String body = "{"
+ "\"model\":\"seedream-4.5\","
+ "\"text\":\"A cat drinking water by the river\","
+ "\"count\":1,"
+ "\"resolution\":\"2k\","
+ "\"ratio\":\"1:1\","
+ "\"imageUrls\":[]"
+ "}";
HttpResponse<String> submit = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/image-generations"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body)).build(),
HttpResponse.BodyHandlers.ofString());
String taskId = extract(submit.body(), "taskId");
System.out.println("taskId = " + taskId);
// 2. Poll until terminal status.
String status = "pending";
while ("pending".equals(status)) {
Thread.sleep(15_000L);
HttpResponse<String> poll = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/image-generations/" + taskId))
.header("Authorization", "Bearer " + API_KEY).GET().build(),
HttpResponse.BodyHandlers.ofString());
status = extract(poll.body(), "status");
System.out.println("status = " + status);
}
if (!"success".equals(status)) {
throw new RuntimeException("image generation failed: " + status);
}
// images is a JSON-stringified array of URLs.
String images = extract(pollResult(http, taskId), "images");
System.out.println("images = " + images);
}
// Minimal JSON field extractor — use Jackson/Gson in production.
private static String extract(String json, String field) {
int i = json.indexOf("\"" + field + "\":");
if (i < 0) return null;
i += field.length() + 3;
if (json.charAt(i) == '\"') {
int end = json.indexOf('\"', i + 1);
return json.substring(i + 1, end);
}
int end = i;
while (end < json.length() && "0123456789.".indexOf(json.charAt(end)) >= 0) end++;
return json.substring(i, end);
}
private static String pollResult(HttpClient http, String taskId) throws Exception {
return http.send(HttpRequest.newBuilder(URI.create(BASE + "/image-generations/" + taskId))
.header("Authorization", "Bearer " + API_KEY).GET().build(),
HttpResponse.BodyHandlers.ofString()).body();
}
}
import os
import time
import requests
BASE = "https://api.basicrouter.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['BASICROUTER_API_KEY']}"}
# 1. Submit the task.
resp = requests.post(
f"{BASE}/image-generations",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"model": "seedream-4.5",
"text": "A cat drinking water by the river",
"count": 1,
"resolution": "2k",
"ratio": "1:1",
"imageUrls": [],
},
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print(f"taskId = {task_id}")
# 2. Poll until terminal status.
while True:
time.sleep(15)
poll = requests.get(f"{BASE}/image-generations/{task_id}", headers=HEADERS)
poll.raise_for_status()
data = poll.json()["data"]
status = data["status"]
print(f"status = {status}")
if status != "pending":
break
if status != "success":
raise RuntimeError(f"image generation failed: {data.get('errorMessage')}")
# images is a JSON-stringified array of URLs.
import json
images = json.loads(data["images"])
print(f"images = {images}")
POST https://api.basicrouter.ai/api/v1/video-generations
非同步提交一個影片生成任務。立即回傳 taskId;透過輪詢
GET /v1/video-generations/{taskId} 或設定 callbackUrl webhook
取得結果。
支援的 model、允許的 videoType 值、時長範圍
(videoDurationMin/Max)、支援的 resolution /
ratio,以及參考素材上傳上限 (fileMax) 必須先從
GET /v1/video-models 取得。僅接受該模型
allowedVideoTypes 中列出的 videoType 代碼。
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
text | String | 是 | 提示詞。 |
model | String | 是 | 模型名稱。 |
videoType | Integer | 是 | 1 文生影片 / 2 圖生影片(首幀)/ 3 圖生影片(首尾幀)/ 4 圖生影片(參考)/ 5 全部參考。 |
imageUrls | String[] | 否 | 圖像素材 URL。 |
videoUrls | VideoUrl[]|String[] | 否 | 影片素材 URL。 |
audioUrls | String[] | 否 | 音訊素材 URL。 |
resolution | String | 否 | 解析度。 |
ratio | String | 否 | 寬高比。 |
duration | Long | 否 | 秒數(>0)。 |
callbackUrl | String | 否 | 任務級 webhook URL。 |
各 videoType 的範例:
1. 文生影片(videoType=1)
僅從文字提示詞生成影片;不需要參考素材。
curl --request POST \
--url https://api.basicrouter.ai/api/v1/video-generations \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 1,
"text": "A cat jumping on a bed",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0"
}'
2. 圖生影片 - 首幀(videoType=2)
在 imageUrls 中提供單一起始幀;模型從該幀開始生成影片。
curl --request POST \
--url https://api.basicrouter.ai/api/v1/video-generations \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 2,
"text": "Happily shaking head",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0",
"imageUrls": ["https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/first-frame.png"]
}'
3. 圖生影片 - 首尾幀(videoType=3)
在 imageUrls 中同時提供首幀與尾幀(順序:
[首幀, 尾幀]);模型會在兩幀之間生成過渡影片。
curl --request POST \
--url https://api.basicrouter.ai/api/v1/video-generations \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 3,
"text": "Put on the hat",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0",
"imageUrls": [
"https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/first-frame.png",
"https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/last-frame.png"
]
}'
4. 圖生影片 - 參考(videoType=4)
在 imageUrls 中提供一張或多張參考圖像;模型將其風格/內容作為參考
(不強制作為首/尾幀)來生成影片。
curl --request POST \
--url https://api.basicrouter.ai/api/v1/video-generations \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 4,
"text": "Two cats playing together",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "kling-v3-omni-video",
"imageUrls": [
"https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/ref-1.png",
"https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/ref-2.png"
]
}'
5. 全部參考(videoType=5)
混合圖像 / 影片 / 音訊參考素材。在提示詞中依位置引用素材: imageUrls 的第
1 項為 @图片 1, videoUrls 的第 1 項為 @视频 1,
audioUrls 的第 1 項為 @音频 1。
videoUrls 亦接受純 URL 字串。
curl --request POST \
--url https://api.basicrouter.ai/api/v1/video-generations \
--header "Authorization: Bearer $BASICROUTER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 5,
"text": "Use the first-person framing of @视频 1 and @音频 1 as background music. First-person tea ad; start frame is @图片 1 ... end frame is @图片 2.",
"model": "seedance-2.0",
"imageUrls": [
"https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic1.jpg",
"https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic2.jpg"
],
"videoUrls": ["https://ark-project.tos-cn-beijing.volces.com/doc_video/r2v_tea_video1.mp4"],
"audioUrls": ["https://ark-project.tos-cn-beijing.volces.com/doc_audio/r2v_tea_audio1.mp3"],
"resolution": "1080p",
"ratio": "16:9",
"duration": 11
}'
提交回應(全部五種類型):
{
"code": 200,
"message": "success",
"data": {"taskId": "vid_xxx"}
}
GET https://api.basicrouter.ai/api/v1/video-generations/{taskId}
輪詢影片生成任務。status 為 pending / success /
failed;videoUrl 為生成的影片 URL,
lastFrameUrl 為尾幀 URL(圖生影片場景)。
curl --request GET \
--url https://api.basicrouter.ai/api/v1/video-generations/vid_xxx \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
{
"code": 200,
"message": "success",
"data": {
"status": "success",
"videoUrl": "https://.../out.mp4",
"lastFrameUrl": null,
"message": null
}
}
回應 data 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
status | String | pending / success / failed. |
videoUrl | String | 生成的影片 URL。 |
lastFrameUrl | String | 尾幀 URL(圖生影片場景);否則為 null。 |
message | String | 失敗原因,成功時為 null。 |
若提交時提供了 callbackUrl,伺服器會透過 webhook 推送最終結果,
data 結構相同。
完整範例(提交 + 輪詢)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class VideoGenerationExample {
private static final String BASE = "https://api.basicrouter.ai/api/v1";
private static final String API_KEY = System.getenv("BASICROUTER_API_KEY");
public static void main(String[] args) throws Exception {
HttpClient http = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10)).build();
// 1. Submit the task (videoType=1: text-to-video).
String body = "{"
+ "\"videoType\":1,"
+ "\"text\":\"A cat jumping on a bed\","
+ "\"resolution\":\"480p\","
+ "\"ratio\":\"16:9\","
+ "\"duration\":4,"
+ "\"model\":\"seedance-2.0\""
+ "}";
HttpResponse<String> submit = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/video-generations"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body)).build(),
HttpResponse.BodyHandlers.ofString());
String taskId = extract(submit.body(), "taskId");
System.out.println("taskId = " + taskId);
// 2. Poll until terminal status. Video tasks take longer — poll every 20s.
String status = "pending";
String lastBody = null;
while ("pending".equals(status)) {
Thread.sleep(20_000L);
HttpResponse<String> poll = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/video-generations/" + taskId))
.header("Authorization", "Bearer " + API_KEY).GET().build(),
HttpResponse.BodyHandlers.ofString());
lastBody = poll.body();
status = extract(lastBody, "status");
System.out.println("status = " + status);
}
if (!"success".equals(status)) {
throw new RuntimeException("video generation failed: " + status);
}
String videoUrl = extract(lastBody, "videoUrl");
System.out.println("videoUrl = " + videoUrl);
}
// Minimal JSON field extractor — use Jackson/Gson in production.
private static String extract(String json, String field) {
int i = json.indexOf("\"" + field + "\":");
if (i < 0) return null;
i += field.length() + 3;
if (json.charAt(i) == '\"') {
int end = json.indexOf('\"', i + 1);
return json.substring(i + 1, end);
}
int end = i;
while (end < json.length() && "0123456789.".indexOf(json.charAt(end)) >= 0) end++;
return json.substring(i, end);
}
}
import os
import time
import requests
BASE = "https://api.basicrouter.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['BASICROUTER_API_KEY']}"}
# 1. Submit the task (videoType=1: text-to-video).
resp = requests.post(
f"{BASE}/video-generations",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"videoType": 1,
"text": "A cat jumping on a bed",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0",
},
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print(f"taskId = {task_id}")
# 2. Poll until terminal status. Video tasks take longer — poll every 20s.
while True:
time.sleep(20)
poll = requests.get(f"{BASE}/video-generations/{task_id}", headers=HEADERS)
poll.raise_for_status()
data = poll.json()["data"]
status = data["status"]
print(f"status = {status}")
if status != "pending":
break
if status != "success":
raise RuntimeError(f"video generation failed: {data.get('message')}")
print(f"videoUrl = {data['videoUrl']}")
if data.get("lastFrameUrl"):
print(f"lastFrameUrl = {data['lastFrameUrl']}")
GET https://api.basicrouter.ai/api/v1/billing/balance
回傳帳戶餘額,分為三個錢包:月度方案、資源包與隨用隨付積分。
curl --request GET \
--url https://api.basicrouter.ai/api/v1/billing/balance \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
{
"totalCredit": 128.50,
"totalResourceCredit": 30.00,
"wallets": {
"monthlyPlan": {"id": "pkg_xxx", "credit": 50.00, "name": "Monthly plan"},
"resourcePacks": [
{"id": "rp_xxx", "credit": 30.00, "name": "Video resource pack"}
],
"payAsYouGo": 48.50
}
}
回應欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
totalCredit | BigDecimal | 總餘額。 |
totalResourceCredit | BigDecimal | 資源包餘額總和。 |
wallets.monthlyPlan | WalletDetail | 月度方案(無則為 null)。 |
wallets.resourcePacks | WalletDetail[] | 資源包列表。 |
wallets.payAsYouGo | BigDecimal | 隨用隨付餘額。 |
WalletDetailVO 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
id | String | 錢包 ID。 |
credit | BigDecimal | 餘額積分。 |
name | String | 錢包名稱。 |
GET https://api.basicrouter.ai/api/v1/usage
分頁回傳模型呼叫帳務明細,依價格(priceSnapshotId)快照劃分,
按訂單建立時間遞減排序。僅回傳正常扣費記錄(reason = model usage)。
查詢參數:
| 參數 | 類型 | 必填 | 預設 | 說明 |
|---|---|---|---|---|
page | Integer | 否 | 1 | 頁碼,從 1 開始。 |
size | Integer | 否 | 20 | 每頁大小(依 priceSnapshotId 分頁)。 |
startTime | LocalDateTime | 否 | — | 起始時間,格式 yyyy-MM-ddTHH:mm:ss,依快照
orderCreatedAt 篩選。 |
endTime | LocalDateTime | 否 | — | 結束時間,格式 yyyy-MM-ddTHH:mm:ss。 |
curl --request GET \
--url "https://api.basicrouter.ai/api/v1/usage?page=1&size=20&startTime=2026-07-01T00:00:00&endTime=2026-07-31T23:59:59" \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
回應包裝:
{
"code": 0,
"message": "success",
"data": { ... }
}
| 欄位 | 類型 | 說明 |
|---|---|---|
records | UsageDetailVO[] | 當前頁記錄。 |
total | Long | 總數。 |
current | Long | 當前頁。 |
size | Long | 每頁大小。 |
pages | Long | 總頁數。 |
UsageDetailVO 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
priceSnapshotId | String | 價格快照 ID。 |
taskId | String | 任務 ID。 |
credit | BigDecimal | 扣費金額。 |
model | String | 模型名稱。 |
modelType | String | text / image / video. |
inputTokens | Long | 輸入 token 數;圖像/影片模型為 null。 |
outputTokens | Long | 輸出 token 數。 |
totalTokens | Long | 總 token 數。 |
cacheReadTokens | Long | 快取讀取 token 數。 |
cacheWriteTokens | Long | 快取寫入 token 數。 |
imageCount | Integer | 圖像數量;為圖像模型設定。 |
imageResolution | String | 圖像解析度,例如 720P。 |
imageRatio | String | 圖像寬高比,例如 1:1。 |
videoResolution | String | 影片解析度,例如 1080p。 |
videoRatio | String | 影片寬高比,例如 16:9。 |
videoDurationSec | Long | 影片時長(秒)。 |
orderCreatedAt | LocalDateTime | 訂單建立時間(快照 orderCreatedAt)。 |
creditDetails | CreditDetailItem[] | 此快照下的訂單明細(來自 credit_order_t)。 |
CreditDetailItem 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
credit | BigDecimal | 此訂單扣費金額。 |
deductionSource | String | 扣費來源(Balance / Monthly Package /
Resource Package)。 |
packageName | String | 套餐名稱;無套餐時為 null。 |
空值慣例:僅填入與各 modelType 相關的欄位;其餘為 null。
text 填入 token 欄位; image 填入
imageCount/imageResolution/imageRatio; video 填入
videoResolution/videoRatio/videoDurationSec。
回應範例:
{
"code": 200,
"message": "success",
"data": {
"records": [
{
"priceSnapshotId": "snap_9f3c1a2b",
"taskId": "task_5e8a1c33",
"credit": 0.0342,
"model": "glm-5.2",
"modelType": "text",
"inputTokens": 1280,
"outputTokens": 642,
"totalTokens": 1922,
"cacheReadTokens": 0,
"cacheWriteTokens": 0,
"imageCount": null,
"imageResolution": null,
"imageRatio": null,
"videoResolution": null,
"videoRatio": null,
"videoDurationSec": null,
"orderCreatedAt": "2026-07-18T14:23:11",
"creditDetails": [
{
"credit": 0.0342,
"deductionSource": "balance",
"packageName": ""
}
]
},
{
"priceSnapshotId": "snap_a12f77c0",
"taskId": "task_c71e44a2",
"credit": 1.8000,
"model": "seedance-2.0",
"modelType": "video",
"inputTokens": null,
"outputTokens": null,
"totalTokens": null,
"cacheReadTokens": null,
"cacheWriteTokens": null,
"imageCount": null,
"imageResolution": null,
"imageRatio": null,
"videoResolution": "1080p",
"videoRatio": "16:9",
"videoDurationSec": 8,
"orderCreatedAt": "2026-07-17T22:41:09",
"creditDetails": [
{
"credit": 1.5000,
"deductionSource": "Monthly Package",
"packageName": "基础月度套餐"
},
{
"credit": 0.3000,
"deductionSource": "Resource Package",
"packageName": "byteplus视频资源包"
}
]
}
],
"total": 128,
"current": 1,
"size": 20,
"pages": 7
}
}
GET https://api.basicrouter.ai/api/v1/billing/transactions
分頁回傳當前使用者已支付(status=2)的儲值交易, 按
created_at 遞減排序。
| 參數 | 類型 | 必填 | 預設 | 說明 |
|---|---|---|---|---|
page | Integer | 否 | 1 | 頁碼。 |
size | Integer | 否 | 20 | 每頁大小。 |
startTime | String | 否 | — | 起始時間,yyyy-MM-dd HH:mm:ss,含邊界。 |
endTime | String | 否 | — | 結束時間,yyyy-MM-dd HH:mm:ss,含邊界。 |
curl --request GET \
--url "https://api.basicrouter.ai/api/v1/billing/transactions?page=1&size=20&startTime=2026-07-01%2000:00:00&endTime=2026-07-31%2023:59:59" \
--header "Authorization: Bearer $BASICROUTER_API_KEY"
回應包裝:
{
"code": 0,
"message": "success",
"data": { ... }
}
| 欄位 | 類型 | 說明 |
|---|---|---|
records | TransactionVO[] | 當前頁交易。 |
total | Long | 總數。 |
current | Long | 當前頁。 |
size | Long | 每頁大小。 |
pages | Long | 總頁數。 |
TransactionVO 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
orderNo | String | 訂單編號。 |
thirdPartyOrderNo | String | 第三方訂單編號。 |
amount | BigDecimal | 訂單金額。 |
actualAmount | BigDecimal | 實際支付金額。 |
discount | BigDecimal | 折扣金額。 |
paymentMethod | String | 支付方式(wechat / alipay / ustd /
stripe / wallyt 等)。 |
TransactionVO 欄位:
| 欄位 | 類型 | 說明 |
|---|---|---|
serviceFeeAmount | BigDecimal | 服務費金額。 |
paymentChannel | String | 支付平台。 |
source | String | 訂單來源(recharge / package_purchase 等)。 |
packageName | String | 套餐名稱(套餐購買時設定;純儲值為 null)。 |
createdAt | LocalDateTime | 建立時間。 |
{
"code": 200,
"message": "success",
"data": {
"records": [
{
"orderNo": "R20260718abc123",
"thirdPartyOrderNo": "wx_pay_xxx",
"amount": 50.00,
"actualAmount": 48.50,
"discount": 1.50,
"paymentMethod": "wechat",
"serviceFeeAmount": 0.00,
"paymentChannel": "wechat",
"source": "recharge",
"packageName": null,
"createdAt": "2026-07-18T14:23:11"
}
],
"total": 28,
"current": 1,
"size": 20,
"pages": 2
}
}
營運
錯誤
BasicRouter 回傳穩定的錯誤代碼,方便應用程式一致地處理重試、後援、帳務問題與除錯。
相容供應商的端點會盡可能保留原始 API 家族的錯誤結構。BasicRouter 原生端點使用 BasicRouter 錯誤物件。
HTTP 狀態與錯誤代碼對應
| HTTP 狀態 | 錯誤類型 | 範例代碼 | 重試 |
|---|---|---|---|
| 400 | invalid_request_error | invalid_request, unsupported_parameter,
invalid_messages, invalid_image_url | 否 |
| 401 | authentication_error | missing_api_key, invalid_api_key | 否 |
| 402 | billing_error | insufficient_credits, payment_required,
quota_exceeded | 否 |
| 403 | permission_error | model_access_denied, endpoint_access_denied,
key_scope_denied | 否 |
| 404 | not_found_error | model_not_found, response_not_found,
task_not_found | 否 |
| 408 | timeout_error | gateway_timeout, provider_timeout | 是 |
| 409 | conflict_error | idempotency_conflict, task_already_cancelled | 視情況 |
| 422 | validation_error | schema_validation_failed, unsupported_modality | 否 |
| 429 | rate_limit_error | account_rpm_exceeded, account_tpm_exceeded,
provider_rate_limited | 是 |
| 500 | internal_error | internal_error | 是 |
| 502 | provider_error | provider_bad_gateway, provider_invalid_response | 是 |
| 503 | service_unavailable | model_unavailable, provider_unavailable,
insufficient_capacity | 是 |
| 504 | timeout_error | provider_timeout, gateway_timeout | 是 |
常見錯誤代碼
| 代碼 | 含義 | 建議操作 |
|---|---|---|
missing_api_key | 未提供 API 金鑰。 | 加上 Authorization 標頭。 |
invalid_api_key | API 金鑰無效或已撤銷。 | 建立或輪替 API 金鑰。 |
model_not_found | 模型 ID 不存在或未為該帳戶啟用。 | 檢查模型頁面或呼叫 GET /v1/models。 |
model_access_denied | API 金鑰或帳戶沒有該模型的存取權限。 | 啟用模型或聯繫管理員。 |
unsupported_parameter | 請求包含所選端點或模型不支援的參數。 | 移除該參數或改用相容的模型。 |
unsupported_modality | 所選模型不支援該輸入或輸出模態。 | 改用支援該模態的模型。 |
account_rpm_exceeded | 超過帳戶每分鐘請求數上限。 | 退避重試或申請提高上限。 |
account_tpm_exceeded | 超過帳戶每分鐘 token 數上限。 | 退避重試、減少 token 數,或申請提高上限。 |
provider_rate_limited | 上游供應商對請求進行限流。 | 重試或啟用後援。 |
insufficient_credits | 帳戶積分不足。 | 錢包儲值、購買資源包,或升級方案。 |
provider_timeout | 上游供應商未及時回應。 | 重試或啟用後援。 |
model_unavailable | 模型暫時不可用。 | 重試或使用路由別名。 |
content_policy_error | 請求或輸出被安全策略攔截。 | 修改輸入或改用合適的工作流程。 |
支援
取得 BasicRouter 協助
查找常見的 API、帳務、路由與整合問題解答。若為生產環境問題,請提供請求 ID、 API 金鑰標籤、端點、模型與時間戳,以便團隊快速追蹤該請求。
常見問題
點擊問題以展開解答。
聯絡
為您的請求選擇最適合的收件匣。
適用於事故、限流、帳務問題、生產環境路由問題、SDK 遷移、供應商相容性、 端點設計問題、企業方案、承諾用量,或自訂供應商路由需求。











