BazaarLinkBazaarLink
登入
文件API 參考SDK 參考Agent 應用AI Skills

API 參考

BazaarLink API 總覽

BazaarLink 在不同模型與供應商之間提供統一且相容 OpenAI 的請求與回應格式。你只需整合一次,就能切換模型,不必重寫應用程式。

客戶端路由欄位會被忽略
若請求包含 provider(整個物件)、transforms、route、頂層 service_tier 或 preset,這些欄位會在送往上游前移除,無法選擇上游或價格層級。Chat Completions 與 Responses 端點支援 models 陣列作為本地備援清單:BazaarLink 會自行路由每個模型並依該模型的 BazaarLink 客戶價格計費,清單不會轉發給上游。客戶提供的 :nitro、:floor 與 :exacto 後綴會被忽略;:eco 仍是 BazaarLink 的經濟方案,並在內部對應至 BazaarLink 的 :floor。:free 仍是獨立的目錄模型變體。
網路搜尋附加費用
使用 plugins、:online 或 web_search_options 要求網路搜尋時,現有行為維持不變,且可能產生上游附加費用;費用會計入該請求所用的金鑰,也就是 BazaarLink 平台金鑰或您的 BYOK 金鑰。

OpenAPI 規格

完整的 BazaarLink API 使用 OpenAPI 規格記錄,並提供 YAML 與 JSON 格式:

你可以將這些規格匯入 Swagger UI、Postman 或其他相容 OpenAPI 的程式碼產生器,用來探索 API 或產生用戶端函式庫。

請求

對話完成請求格式

對話完成的請求本文會傳送至以下端點:

POST/v1/chat/completions

如需完整的支援欄位清單,請參閱 參數。

請求結構
// Definitions of subtypes are below
type Request = {
  // Required by BazaarLink Chat Completions
  model: string;                    // Use an id or alias from GET /v1/models
  messages: Message[];             // Must contain at least one message

  // Generation
  stream?: boolean;
  temperature?: number;
  max_tokens?: number;             // Positive integer
  max_completion_tokens?: number;  // Alias mapped to max_tokens upstream
  n?: number;
  seed?: number;
  stop?: string | string[];

  // Sampling
  top_p?: number;
  top_k?: number;
  frequency_penalty?: number;
  presence_penalty?: number;
  repetition_penalty?: number;
  min_p?: number;
  top_a?: number;
  // Sampling values are forwarded without range validation; models may clamp or ignore them.

  // Token probabilities
  logit_bias?: Record<number, number>;
  logprobs?: boolean;
  top_logprobs?: number;

  // Stable end-user identifier for abuse prevention
  user?: string;

  // Tool calling
  tools?: Tool[];
  tool_choice?: ToolChoice;
  parallel_tool_calls?: boolean;

  // Structured output
  response_format?: ResponseFormat;
  structured_outputs?: boolean;

  // Plugin configuration — forwarded to upstreams that support plugins.
  plugins?: Plugin[];

  // Multimodal and image-generation options
  modalities?: Array<"text" | "image">;
  image_config?: Record<string, unknown>;
  input_audio?: InputAudio;

  // Provider-specific reasoning controls
  reasoning_effort?: "low" | "medium" | "high";
  reasoning?: ReasoningConfig;
  thinking?: ThinkingConfig;
  enable_thinking?: boolean;

};

// Message types
type Message =
  | SystemMessage
  | UserMessage
  | AssistantMessage
  | ToolMessage;

type SystemMessage = {
  role: "system";
  content: string | ContentPart[];
  name?: string;
};

type UserMessage = {
  role: "user";
  content: string | ContentPart[];
  name?: string;
};

type AssistantMessage = {
  role: "assistant";
  content?: string | ContentPart[] | null;
  name?: string;
  tool_calls?: ToolCall[];
};

type ToolMessage = {
  role: "tool";
  content: string;
  tool_call_id: string;
  name?: string;
};

// Multimodal content parts
type ContentPart =
  | TextContentPart
  | ImageContentPart
  | FileContentPart
  | AudioContentPart
  | VideoContentPart;

type TextContentPart = {
  type: "text";
  text: string;
};

type ImageContentPart = {
  type: "image_url";
  image_url: {
    url: string;                    // Remote URL or base64 data URI
    detail?: string;
  };
};

type FileContentPart = {
  type: "file";
  file: {
    filename?: string;
    file_data: string;              // Base64 data URI
  };
};

type AudioContentPart = {
  type: "input_audio";
  input_audio: InputAudio;
};

type InputAudio = {
  data: string;                     // Raw base64 without a data URI prefix
  format: string;                   // For example "wav" or "mp3"
};

type VideoContentPart = {
  type: "video_url";
  video_url: {
    url: string;                    // Remote URL or base64 data URI
  };
};

// Tool calling subtypes
type FunctionDescription = {
  name: string;
  description?: string;
  parameters: object;               // JSON Schema object
};

type Tool = {
  type: "function";
  function: FunctionDescription;
};

type ToolChoice =
  | "none"
  | "auto"
  | "required"
  | {
      type: "function";
      function: {
        name: string;
      };
    };

type ToolCall = {
  id: string;
  type: "function";
  function: {
    name: string;
    arguments: string;
  };
};

// Structured output
type ResponseFormat =
  | {
      type: "json_object";
    }
  | {
      type: "json_schema";
      json_schema: {
        name: string;
        strict?: boolean;
        schema: object;
      };
    };

// Upstream plugin configuration
type Plugin = {
  id: string;
  enabled?: boolean;
  [key: string]: unknown;
};

// Reasoning controls vary by model family
type ReasoningConfig = {
  effort?: "low" | "medium" | "high";
  max_tokens?: number;
  exclude?: boolean;
};

type ThinkingConfig = {
  type?: "enabled" | "disabled";
  budget_tokens?: number;
};

結構化輸出

強制模型返回符合 Schema 的有效 JSON。這對於建立需要程式化解析模型輸出的可靠應用程式至關重要。

  • json_object — 基本 JSON 模式;模型會回傳有效的 JSON。
  • json_schema — 嚴格 Schema 模式;模型輸出必須符合提供的 JSON Schema。

外掛

BazaarLink 會將 plugins 陣列轉送至選定的上游路由。外掛可用性取決於模型與供應商;使用 :online 模型變體時也會啟用 web 外掛。

JSON
{
  "model": "openai/gpt-4o",
  "messages": [
    { "role": "user", "content": "What happened today?" }
  ],
  "plugins": [
    { "id": "web" }
  ]
}

選填標頭

透過請求標頭識別您的應用程式,讓系統追蹤使用量、顯示在儀表板上,並在未來提供更細緻的分析。

TypeScript
await fetch("https://api.bazaarlink.ai/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <BAZAARLINK_API_KEY>",
    "Content-Type": "application/json",
    "HTTP-Referer": "https://your-app.example",
    "X-Title": "Your App"
  },
  body: JSON.stringify({
    model: "openai/gpt-4o",
    messages: [{ role: "user", content: "Hello!" }]
  })
});

助手預填

在訊息陣列最後加入一則未完成的 assistant 訊息,向相容的模型路由要求接續生成。

運作方式
BazaarLink 會保留並轉送最後一則 assistant 訊息。接續行為由所選的上游模型與供應商實作,因此並非每條路由都保證支援。
TypeScript
const response = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4.6",
  messages: [
    { role: "user", content: "What is the meaning of life?" },
    // Intentional partial response; compatible routes continue from here.
    { role: "assistant", content: "My best answer is" }
  ]
});

回應

BazaarLink 將不同模型與供應商的完成回應正規化為統一、相容 OpenAI 的格式。

完成回應格式

choices 永遠是陣列。串流回應使用 delta,非串流回應使用 message;可取得時亦會回傳用量與成本明細。

回應結構
type Response = {
  id: string;
  object: "chat.completion" | "chat.completion.chunk";
  created: number;
  model: string;
  choices: Array<NonStreamingChoice | StreamingChoice>;
  usage?: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
    cost?: number;
    prompt_tokens_details?: {
      cached_tokens: number;
      cache_write_tokens?: number;
      audio_tokens?: number;
    };
    completion_tokens_details?: {
      reasoning_tokens?: number;
      image_tokens?: number;
    };
  };
};

type NonStreamingChoice = {
  index: number;
  finish_reason: string | null;
  message: {
    role: "assistant";
    content: string | null;
    tool_calls?: ToolCall[];
  };
};

type StreamingChoice = {
  index: number;
  finish_reason: string | null;
  delta: {
    role?: string;
    content?: string | null;
    tool_calls?: ToolCall[];
  };
};

結束原因

finish_reason 使用 BazaarLink 正規化後的 stop、length、tool_calls、content_filter、error 等值。

JSON
{
  "finish_reason": "stop"
}

查詢成本與統計資料

使用回應 id 或 x-request-id 標頭中的不透明 BazaarLink 請求 ID 呼叫 GET /v1/generation;非串流回應也會在 x-generation-id 提供此 ID。統計資料可能延遲數秒;若收到 404,請短暫重試。

TypeScript
const generation = await fetch(
  "https://api.bazaarlink.ai/v1/generation?id=<GENERATION_ID>",
  {
    headers: {
      Authorization: "Bearer <BAZAARLINK_API_KEY>"
    }
  }
).then((response) => response.json());

Agent 註冊

功能開啟後,Agent 可使用未付費或 x402 付費註冊入口建立帳戶。

POSThttps://bazaarlink.ai/api/v1/agents/register

未付費註冊接受 name、可選的 description 與 referral_code。201 回應包含 API 金鑰、額度、7 天 claim token 與到期時間、升級網址、推薦碼、free_model auto:free、base URL 和文件連結。它使用既有的免費模型機制;免費網頁搜尋需要已驗證的電子郵件,因此未付費 Agent 無法使用。

POSThttps://bazaarlink.ai/api/v1/agents/register/x402

付費註冊先回傳 HTTP 402 需求:scheme exact、network eip155:196、asset USD-T0 和 payTo。Agent 帶著 X-PAYMENT 重送後,會收到相同註冊欄位以及 payment { txHash, network, amountUsd }。付費 Agent 遵循一般付費帳戶規則;既有帳戶可使用 /api/x402/topup 加值。

人類可在 7 天 token 有效期間透過 /claim 接管未付費 Agent。註冊限制為每個 IP 每 24 小時一次,並受雲端供應商上限約束;拒絕的請求會回傳含 Retry-After 的 429。

POSThttps://bazaarlink.ai/api/x402/topup

對話完成

主要端點。與 OpenAI Chat Completions API 相容。

POST/v1/chat/completions

請求內文

model必填
string
使用 GET /v1/models 列出的 id 或 alias,例如「claude-sonnet-4.6」或「anthropic/claude-sonnet-4.6」。
messages必填
Message[]
包含 role 和 content 的訊息物件陣列
stream
boolean
若為 true,返回 Server-Sent Events 串流。預設:false
temperature
number
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
max_tokens
integer
要生成的最大 token 數量
max_completion_tokens
integer
max_tokens 的別名(OpenAI o 系列相容)。兩者皆支援,以提供的為準
top_p
number
核取樣概率質量。預設:1
top_k
integer
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
frequency_penalty
number
懲罰重複的 token。範圍:[-2, 2]。預設:0
presence_penalty
number
基於存在情況懲罰 token。範圍:[-2, 2]。預設:0
repetition_penalty
number
降低輸入中 token 重複的機率。範圍:(0, 2]。預設:1
min_p
number
相對最高機率 token 的最低入選機率。範圍:[0, 1]。預設:0
top_a
number
基於最高機率 token 的動態 Top-P。範圍:[0, 1]。預設:0
seed
integer
整數隨機種子,用於確定性取樣。部分模型不保證
n
integer
產生的完成數量。預設:1
user
string
終端使用者識別碼,用於監控與濫用偵測。對計費無影響。僅限 OpenAI 系列模型 —— 見下方說明。
stop
string | string[]
停止序列 — 遇到時停止生成
logit_bias
object
將 token ID 映射到偏差値 [-100, 100],在取樣前加到機率。僅限 OpenAI 系列模型 —— 見下方說明。
logprobs
boolean
回傳每個輸出 token 的對數機率。僅限 OpenAI 系列模型 —— 見下方說明。
top_logprobs
integer
每個位置回傳概率最高的 N 個候選 token(需配合 logprobs: true)。範圍:0–20。僅限 OpenAI 系列模型 —— 見下方說明。
tools
Tool[]
模型可以呼叫的工具(函式)列表
tool_choice
string | object
控制工具使用:"auto"、"none" 或指定工具
parallel_tool_calls
boolean
啟用並行工具呼叫功能。預設:true。僅限 OpenAI 系列模型 —— 見下方說明。
response_format
object
強制結構化 JSON 輸出。請參閱結構化輸出章節
structured_outputs
boolean
在支援的 provider 上要求嚴格符合 JSON schema 的輸出。原樣轉發
reasoning
object
Provider 專屬的 reasoning/thinking 設定。原樣轉發
reasoning_effort
string
OpenAI o 系列風格的 reasoning 強度:"low"、"medium" 或 "high"。原樣轉發
user、logprobs、top_logprobs、logit_bias、parallel_tool_calls 只會傳到 OpenAI 系列模型
只要解析出來的模型不是 OpenAI 自家的,這五個參數就會從上游請求中被拿掉 —— 送到 anthropic/claude-*、google/gemini-* 或其他非 OpenAI 目標時,會回 200,參數被悄悄忽略,不會報錯。如果你設了其中任何一個卻沒看到效果,先檢查目標模型是不是 OpenAI 的。

請求結構 (TypeScript)

// Definitions of subtypes are below
type Request = {
  // Required by BazaarLink Chat Completions
  model: string;                    // Use an id or alias from GET /v1/models
  messages: Message[];             // Must contain at least one message

  // Generation
  stream?: boolean;
  temperature?: number;
  max_tokens?: number;             // Positive integer
  max_completion_tokens?: number;  // Alias mapped to max_tokens upstream
  n?: number;
  seed?: number;
  stop?: string | string[];

  // Sampling
  top_p?: number;
  top_k?: number;
  frequency_penalty?: number;
  presence_penalty?: number;
  repetition_penalty?: number;
  min_p?: number;
  top_a?: number;
  // Sampling values are forwarded without range validation; models may clamp or ignore them.

  // Token probabilities
  logit_bias?: Record<number, number>;
  logprobs?: boolean;
  top_logprobs?: number;

  // Stable end-user identifier for abuse prevention
  user?: string;

  // Tool calling
  tools?: Tool[];
  tool_choice?: ToolChoice;
  parallel_tool_calls?: boolean;

  // Structured output
  response_format?: ResponseFormat;
  structured_outputs?: boolean;

  // Plugin configuration — forwarded to upstreams that support plugins.
  plugins?: Plugin[];

  // Multimodal and image-generation options
  modalities?: Array<"text" | "image">;
  image_config?: Record<string, unknown>;
  input_audio?: InputAudio;

  // Provider-specific reasoning controls
  reasoning_effort?: "low" | "medium" | "high";
  reasoning?: ReasoningConfig;
  thinking?: ThinkingConfig;
  enable_thinking?: boolean;

};

// Message types
type Message =
  | SystemMessage
  | UserMessage
  | AssistantMessage
  | ToolMessage;

type SystemMessage = {
  role: "system";
  content: string | ContentPart[];
  name?: string;
};

type UserMessage = {
  role: "user";
  content: string | ContentPart[];
  name?: string;
};

type AssistantMessage = {
  role: "assistant";
  content?: string | ContentPart[] | null;
  name?: string;
  tool_calls?: ToolCall[];
};

type ToolMessage = {
  role: "tool";
  content: string;
  tool_call_id: string;
  name?: string;
};

// Multimodal content parts
type ContentPart =
  | TextContentPart
  | ImageContentPart
  | FileContentPart
  | AudioContentPart
  | VideoContentPart;

type TextContentPart = {
  type: "text";
  text: string;
};

type ImageContentPart = {
  type: "image_url";
  image_url: {
    url: string;                    // Remote URL or base64 data URI
    detail?: string;
  };
};

type FileContentPart = {
  type: "file";
  file: {
    filename?: string;
    file_data: string;              // Base64 data URI
  };
};

type AudioContentPart = {
  type: "input_audio";
  input_audio: InputAudio;
};

type InputAudio = {
  data: string;                     // Raw base64 without a data URI prefix
  format: string;                   // For example "wav" or "mp3"
};

type VideoContentPart = {
  type: "video_url";
  video_url: {
    url: string;                    // Remote URL or base64 data URI
  };
};

// Tool calling subtypes
type FunctionDescription = {
  name: string;
  description?: string;
  parameters: object;               // JSON Schema object
};

type Tool = {
  type: "function";
  function: FunctionDescription;
};

type ToolChoice =
  | "none"
  | "auto"
  | "required"
  | {
      type: "function";
      function: {
        name: string;
      };
    };

type ToolCall = {
  id: string;
  type: "function";
  function: {
    name: string;
    arguments: string;
  };
};

// Structured output
type ResponseFormat =
  | {
      type: "json_object";
    }
  | {
      type: "json_schema";
      json_schema: {
        name: string;
        strict?: boolean;
        schema: object;
      };
    };

// Upstream plugin configuration
type Plugin = {
  id: string;
  enabled?: boolean;
  [key: string]: unknown;
};

// Reasoning controls vary by model family
type ReasoningConfig = {
  effort?: "low" | "medium" | "high";
  max_tokens?: number;
  exclude?: boolean;
};

type ThinkingConfig = {
  type?: "enabled" | "disabled";
  budget_tokens?: number;
};

範例請求

curl https://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Explain quantum computing in one paragraph."}
    ],
    "temperature": 0.7,
    "max_tokens": 512
  }'

回應

{
  "id": "85e6f35c71a31f19-SJC",
  "object": "chat.completion",
  "created": 1740000000,
  "model": "openai/gpt-4o",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Quantum computing leverages quantum mechanics..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 28,
    "completion_tokens": 74,
    "total_tokens": 102,
    "cost": 0.0006480,
    "prompt_tokens_details": {
      "cached_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0
    }
  }
}

回應結構 (TypeScript)

BazaarLink 回傳標準化回應並移除上游專屬欄位。usage.cost 是此請求向客戶收取的美元金額。

超過 100 秒的長請求建議使用 stream:true。非串流請求約 12 秒後(預設值,可由部署設定調整)會先回應 200 並開始傳送 keepalive 空白;之後若出錯,會以 200 + error JSON 回傳。keepalive 是 JSON 本文前的空白,標準 JSON 解析器會忽略。

type Response = {
  id: string;
  object: "chat.completion" | "chat.completion.chunk";
  created: number;                 // Unix timestamp
  model: string;
  choices: (NonStreamingChoice | StreamingChoice)[];
  usage?: ResponseUsage;
};

type NonStreamingChoice = {
  index: number;
  finish_reason: "stop" | "length" | "tool_calls" | "content_filter" | null;
  message: {
    role: "assistant";
    content: string | null;
    tool_calls?: ToolCall[];
  };
};

type StreamingChoice = {
  index: number;
  finish_reason: string | null;
  delta: {
    role?: string;
    content?: string | null;
    tool_calls?: ToolCall[];
  };
};

type ResponseUsage = {
  prompt_tokens: number;
  completion_tokens: number;
  total_tokens: number;
  cost: number;                      // USD amount charged to the customer for this request
  prompt_tokens_details?: {
    cached_tokens: number;           // Tokens served from prompt cache (reduced cost)
    cache_write_tokens?: number;     // Tokens written to cache in this request
    audio_tokens?: number;
  };
  completion_tokens_details?: {
    reasoning_tokens?: number;       // Thinking/reasoning tokens (e.g. o3, Qwen3, DeepSeek R1)
    image_tokens?: number;
  };
};

type ToolCall = {
  id: string;
  type: "function";
  function: { name: string; arguments: string };
};

圖片生成

BazaarLink 提供兩條圖片生成路徑:(A) /v1/chat/completions 並帶 modalities: ["image"] — 原生路徑,支援 SSE stream 與混合 text+image 輸出,推薦新整合使用。(B) /v1/images/generations — OpenAI DALL·E 相容請求格式,回應為 SSE event stream(避免慢速模型撞 100s 上游超時)。兩條路徑的 SSE 事件協定一致,端點選擇純粹是請求形狀偏好。圖片編輯(修改既有圖片)走 POST /v1/images/edits — 與 OpenAI images.edit 相容,用 multipart/form-data 上傳來源圖。可編輯的模型 modality 是 text+image->image(例如 qwen/qwen-image-3);純生成模型是 text->image —— 各模型的 modality 可在 GET /v1/models 查。

Response format

/v1/images/generations 預設回傳 OpenAI 相容的同步 JSON(2026-07-25 起)——client.images.generate() 不需任何包裝即可使用。傳 stream: true 可改用 SSE 事件串流,適合生成時間較長的模型取得進度。

A. /v1/chat/completions (原生,推薦)

POST/v1/chat/completions

The canonical streaming path. Recommended for any new integration.

curl -N https://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BL_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
  }'

圖生圖(image-to-image):在 content 陣列帶 image_url 部件即可,支援 data URI 或 https 圖片網址(不接受 http://),最多 8 張、單張 data URI 約 10MB 內;帶圖的那則訊息必須同時含 text 部件(編輯指令)。部分模型另支援 image_config(例如 {"strength": 0.7},0–1,值越低越貼近原圖),原樣透傳給上游。

curl -N https://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-image-2",
    "messages": [{"role":"user","content":[
      {"type":"image_url","image_url":{"url":"data:image/png;base64,..."}},
      {"type":"text","text":"change the background to a night city"}
    ]}],
    "modalities": ["image"],
    "stream": true
  }'

圖片編輯(OpenAI 相容)

POST/v1/images/edits

OpenAI SDK 的 client.images.edit() 可直接使用(multipart 上傳、同步 JSON 回應,回傳 data: [{ url }])。限制同圖生圖:最多 8 張、單張 10MB;mask 與 response_format=b64_json 暫不支援。

curl https://api.bazaarlink.ai/v1/images/edits \
  -H "Authorization: Bearer $BL_API_KEY" \
  -F model="openai/gpt-5.4-image-2" \
  -F image=@cat.png \
  -F prompt="change the background to a night city"

B. /v1/images/generations (DALL·E 相容)

POST/v1/images/generations

OpenAI DALL-E request shape. Sync JSON ({ created, data: [{ url }] }) is the default and works with client.images.generate() out of the box; pass stream: true to get the SSE event stream documented below instead.

curl https://api.bazaarlink.ai/v1/images/generations \
  -H "Authorization: Bearer $BL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-1",
    "prompt": "a red cat on a sofa",
    "size": "1024x1024"
  }'
model必填
string
模型 ID,例如 google/gemini-2.5-flash-image
prompt必填
string
文字提示
size
string
輸出尺寸 (自動映射)
n
integer
產生張數(預設 1)
# Streaming variant — progressive delivery for long generations
curl -N https://api.bazaarlink.ai/v1/images/generations \
  -H "Authorization: Bearer $BL_API_KEY" \
  -H "Accept: text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{"model":"openai/gpt-5.4-image-2","prompt":"a red cat on a sofa","stream":true}'

SSE event protocol

忽略 SSE 註解列及未知或 ping 事件;處理文件列出的 image、usage 與 done 事件。

: keep-alive

event: image
data: {"index": 0, "url": "https://api.bazaarlink.ai/v1/images/proxy/<token>"}

event: image-cached     # bazaarlink Redis-backed proxy URL (1 hr TTL)
data: {"index": 0, "url": "https://api.bazaarlink.ai/v1/images/proxy/<token>"}

event: usage            # final cost / token count
data: {"promptTokens": 12, "completionTokens": 7080, "cost": 0.226, "durationMs": 163400, "imageCount": 1}

event: done
data: {}

支援的圖片模型

Model IDModalityi2i (edits)

影片生成

非同步三步驟流程(submit → poll → content)。影片生成需要 30 秒到 5 分鐘,無法套用 chat-completions 的同步請求/回應語意 — 因此 BazaarLink 把影片獨立到 /v1/videos 路徑,採用 job-id 模式:submit 拿到 vjob_* ID → poll 狀態 → 完成後 fetch bytes。將 video model 透過 /chat/completions 或 /images/generations 呼叫會回 400(code: wrong_endpoint_for_video)。費用於 completed 時依實際 usage.cost 結算。

影片任務類型

同一個端點涵蓋多種任務,實際執行哪一種由你傳入的欄位決定 —— 同一個模型可以做圖生影、首尾幀、影片接續。並非每個模型都支援每種任務,不支援時回傳 400。

文生影片
prompt
只給文字提示,從零生成,不需輸入素材。
圖生影片
frame_images: [ 首幀 ]
圖片就是畫面本身:當作第一幀讓它動起來,內容忠於原圖。例:一張貓的照片 → 那隻貓在同一個場景裡轉頭。
首尾幀生影片
frame_images: [ 首幀, 尾幀 ]
給起點與終點兩張圖,模型補出中間的運動過渡。
影片接續
input_video
延續一段既有影片。要求的 duration 必須大於來源影片的長度。
參考生影片
input_references: [ 參考圖 ]
圖片是「參考」不是畫面:模型保留主體/風格,生成全新場景。例:一張貓的照片 +「在森林裡跳舞」→ 全新影片,貓的長相保留但場景與動作都是新的(可放 1–9 張參考圖)。與圖生影片的差別:圖生影片忠於原圖;參考生影片是「照著這個角色演新戲」。
影片編輯
input_video + prompt
編輯一段既有影片 —— 換場景、風格或動作。計費 = 輸入影片秒數 + 輸出秒數。

1. 提交任務(立即回 vjob_xxx)

POST/v1/videos
model必填
string
模型 ID,例如 bytedance/seedance-2.0
prompt必填
string
文字提示
duration
integer
秒數(依模型限制)
resolution
string
解析度:480p / 720p / 1080p 等
generate_audio
boolean
是否產生音軌(true/false)
frame_images
array
首/尾幀圖片(圖生影、首尾幀)。物件 { type: "image_url", image_url: { url }, frame_type: "first_frame" | "last_frame" } 或純 URL 字串。
input_references
array
參考生影片用的參考圖 —— 引導主體/風格,非精確幀。
input_video
string|object
影片接續與影片編輯的來源影片 URL,必須是上游可公開存取的網址。
aspect_ratio
string
寬高比,例如 16:9 或 9:16。當輸入圖已決定比例時會被忽略。
watermark
boolean
加上浮水印,預設 false。
callback_url
string
任務進入終態時呼叫的 webhook 網址——僅限 HTTPS,會做 SSRF 檢查。v1 無簽章;請視為提示,並用 GET /videos/{id} 回查確認。
curl https://api.bazaarlink.ai/v1/videos \
  -H "Authorization: Bearer $BL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bytedance/seedance-2.0",
    "prompt": "a bird flying over mountains",
    "duration": 3,
    "resolution": "720p",
    "generate_audio": false
  }'
# → 202 { "id": "vjob_xxx", "status": "pending" }
Note
提交時會依最壞情況估算預留額度。工作完成後,usage.cost 是此請求向客戶收取的美元金額。

2. 輪詢狀態

GET/v1/videos/{id}
curl -H "Authorization: Bearer $BL_API_KEY" \
  https://api.bazaarlink.ai/v1/videos/vjob_xxx
Note
每次 GET 間隔需 ≥ 8 秒才會實際打上游(避免 rate limit)
Note
若 status=failed,reserve 金額全額退回用戶。

3. 取得影片內容 (MP4)

GET/v1/videos/{id}/content
curl -H "Authorization: Bearer $BL_API_KEY" \
  -o output.mp4 \
  https://api.bazaarlink.ai/v1/videos/vjob_xxx/content

使用須知

  • 各模型支援的畫質不同 —— 送不支援的值會回 400 並列出可用畫質。
  • 輸入的圖片/影片必須是公開可存取的 URL。防盜鏈的網站(例如部分 wiki)會失敗。
  • 輸入素材會經過上游內容審核,偶爾可能被誤擋。
  • 影片接續時,要求的 duration 必須大於來源影片長度。
  • 輸出寬高比會跟隨輸入圖 —— 方形圖會產生方形影片。
  • 影片編輯的計費為:輸入影片秒數 + 生成輸出秒數。
  • 影片編輯/接續的 input_video 必須是公開網址。你在這裡生成的影片是憑 API 金鑰才能存取的,上游抓不到,所以來源影片請放到公開可讀的網址。
  • Webhook 沒有簽章——採取行動前請用 GET /videos/{id} 回查狀態與金額,且其中的 unsigned_urls 是絕對網址(跟輪詢回應的相對路徑不同)。

支援的影片模型

Model IDModalityTasks
alibaba/wan3.0-image-to-videotext+image->video—
alibaba/wan3.0-video-edittext+video->video—
alibaba/wan3.0-reference-to-videotext+image+video->video—
alibaba/wan3.0-text-to-videotext->video—
bytedance/seedance-2.5text+image+audio+video->video—
minimax/hailuo-3-maxtext+image->videot2v, i2v
openai/sora-2-protext+image->videot2v, i2v
bytedance/seedance-2.0-fasttext+image+audio+video->videot2v, i2v
bytedance/seedance-2.0text+image+audio+video->videot2v, i2v
bytedance/seedance-1-5-protext+image->videot2v, i2v
google/veo-3.1text+image->videot2v, i2v

影片輸入

傳送影片檔案給支援影片輸入的模型,用來分析內容、生成說明或回答場景與事件相關問題。可用直接 URL 或 base64 資料 URI — URL 適合公開可存取的影片;base64 用於本機檔案或私有影片。

支援的格式

MP4(H.264)MPEGMOVWebM
response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{
        "role": "user",
        "content": [
            {
                "type": "video_url",
                "video_url": {"url": "https://example.com/video.mp4"},
            },
            {"type": "text", "text": "What is happening in this video?"},
        ],
    }],
)

完整 API 參考 →

PDF 輸入

直接在訊息中傳送 PDF 文件,給原生支援 PDF 輸入的模型(例如 Claude、Gemini)分析、摘要或回答問題。BazaarLink 會把檔案直接轉送給模型 — 算一般 input tokens,不額外收費、不額外處理。

支援的格式

  • PDF 文件(含文字、圖片、表格、掃描件)
  • Base64 資料 URL(`data:application/pdf;base64,...`)
  • 多頁文件
  • 僅限無密碼保護的 PDF
import base64

with open("document.pdf", "rb") as f:
    pdf_data = base64.b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6",
    messages=[{
        "role": "user",
        "content": [
            {
                "type": "file",
                "file": {
                    "filename": "document.pdf",
                    "file_data": f"data:application/pdf;base64,{pdf_data}",
                },
            },
            {"type": "text", "text": "Summarize this document."},
        ],
    }],
)

Responses API

相容 OpenAI Responses API 格式的端點,支援無狀態多輪對話、工具呼叫與多模態輸入。適用於使用 OpenAI Python SDK ≥ 1.x 的 client.responses.create() 的 Agent 框架。

POST/v1/responses
Note
使用與 Chat Completions 相同的身份驗證與模型路由邏輯。

請求內文

model必填
string
使用 GET /v1/models 列出的 id 或 alias,例如「claude-sonnet-4.6」或「anthropic/claude-sonnet-4.6」。
input必填
string | Item[]
使用者輸入 — 純字串(單則訊息)或輸入項目陣列(多輪 / 多模態對話)。
instructions
string
系統層級指令,等同於 system 角色的訊息。每次請求都必須重新傳送。
stream
boolean
若為 true,回傳 Responses API SSE 串流事件,包含 response.created、response.output_text.delta、response.completed 等事件類型。
max_output_tokens
integer
最大輸出 Token 數量(o 系列推理模型包含推理 Token)。
temperature
number
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
top_p
number
核取樣概率質量。預設:1
tools
Tool[]
工具(函式)定義,格式與 Chat Completions 相同的 JSON Schema(接受扁平的 Responses 格式,也接受巢狀格式)。不支援 OpenAI 專屬的內建託管工具(web_search_preview、file_search、computer_use_preview);網頁搜尋可透過 plugins: [{id:"web"}] 啟用,僅部分模型路由支援。
tool_choice
string | object
控制工具使用:"auto"、"none" 或指定工具
parallel_tool_calls
boolean
啟用並行工具呼叫功能。預設:true。僅限 OpenAI 系列模型 —— 見下方說明。
response_format
object
強制結構化 JSON 輸出。請參閱結構化輸出章節
previous_response_id
string
本端點是無狀態的——傳入非 null 值會直接回 400(invalid_prompt),不是被接受後忽略。請改用無狀態模式:在 input 陣列中帶入完整對話歷史。

請求結構 (TypeScript)

type ResponsesRequest = {
  model: string;                    // Listed id or alias from GET /v1/models
  input: string | InputItem[];      // string or multi-turn array

  // Optional
  instructions?: string;            // System-level message
  stream?: boolean;                 // Default: false
  max_output_tokens?: number;
  temperature?: number;
  top_p?: number;
  tools?: Tool[];
  tool_choice?: "auto" | "none" | "required" | object;
  parallel_tool_calls?: boolean;    // Default: true
  previous_response_id?: string;    // Not supported — use full input array
};

type InputItem =
  | { type?: "message"; role: "user" | "assistant" | "system" | "developer"; content: string | ContentBlock[] }
  | { type: "function_call_output"; call_id: string; output: string }   // tool result
  | { type: "function_call"; call_id: string; name: string; arguments: string };

type ContentBlock =
  | { type: "input_text"; text: string }
  | { type: "input_image"; image_url: string; detail?: "auto" | "low" | "high" };

範例請求

curl https://api.bazaarlink.ai/v1/responses \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "instructions": "You are a helpful assistant.",
    "input": "What is the capital of Taiwan?"
  }'

回應格式

BazaarLink ????????????????????????? BazaarLink ?? ID ? x-request-id ?????? ID ?? GET /v1/generation????????? x-generation-id ???? ID?usage.cost ??????????????????????????????? 404???????

// Non-streaming response object
type ResponsesResponse = {
  id: string;             // Opaque BazaarLink request id; format may change
  object: "response";
  created_at: number;
  completed_at: number;
  status: "completed" | "failed" | "incomplete";
  model: string;
  output: OutputItem[];
  usage: {
    input_tokens: number;   // equivalent to prompt_tokens
    output_tokens: number;  // equivalent to completion_tokens
    total_tokens: number;
    cost?: number;          // USD amount charged to the customer for this request
  } | null;
  error: null | { code: string; message: string };
};

type OutputItem =
  | {
      type: "message";
      id: string;
      role: "assistant";
      status: "completed";
      content: Array<{ type: "output_text"; text: string; annotations: [] }>;
    }
  | { type: "function_call"; id: string; call_id: string; name: string; arguments: string; status: "completed" };

從 Chat Completions 遷移

將 messages 改為 input(字串或陣列),以 instructions 取代 system 角色訊息,並從 output[0].content[0].text 讀取回應內容(原為 choices[0].message.content)。

# Chat Completions (before)
response = client.chat.completions.create(
    model="openai/gpt-5.4-mini",
    messages=[
        {"role": "system", "content": "You are helpful."},
        {"role": "user",   "content": "Hello"},
    ]
)
text = response.choices[0].message.content

# Responses API (after)
response = client.responses.create(
    model="openai/gpt-5.4-mini",
    instructions="You are helpful.",
    input="Hello"
)
text = response.output[0].content[0].text

限制事項

  • previous_response_id 或 store: true 會被拒絕並回傳 400(錯誤碼 invalid_prompt)——不是被接受後忽略。請一律使用無狀態模式,在 input 陣列中帶入完整對話歷史。
  • 不支援 OpenAI 專屬的內建託管工具(web_search_preview、file_search、computer_use_preview)。網頁搜尋可透過 plugins: [{id:"web"}] 啟用,僅部分模型路由支援。
  • background: true 會被接受但忽略,請求一律同步執行到完成為止。

Messages(Anthropic 相容)

? Claude SDK ??? Anthropic ?? Messages API?? SDK ?? BazaarLink ??? BazaarLink API ???????????????????? BazaarLink ?????

POST/v1/messages
Note
支援 Bearer token 或 x-api-key header(相容 Anthropic SDK)。最大請求 body 為 10 MB。

請求內文

model必填
string
使用 GET /v1/models 列出的 id 或 alias,例如「claude-sonnet-4.6」或「anthropic/claude-sonnet-4.6」。
max_tokens必填
integer
生成的最大 token 數(正整數)。
messages必填
Message[]
對話訊息陣列(不可為空)。
system
string
選填的 system prompt。
stream
boolean
若為 true,返回 Server-Sent Events 串流。預設:false
temperature
number
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
top_p
number
核取樣概率質量。預設:1
top_k
integer
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
stop_sequences
string[]
自訂停止序列字串陣列。
tools
Tool[]
模型可以呼叫的工具(函式)列表
tool_choice
string | object
控制工具使用:"auto"、"none" 或指定工具

範例請求

from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.bazaarlink.ai/v1",
    api_key="sk-bl-YOUR_KEY"
)

response = client.messages.create(
    model="anthropic/claude-opus-4.6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}]
)
print(response.content[0].text)

回應

BazaarLink ????????????????????????? BazaarLink ?? ID ? x-request-id ?????? ID ?? GET /v1/generation????????? x-generation-id ???? ID?usage.cost ? usage.bz_cost ???????????????????????????????? 404???????

{
  "id": "85e6f35c71a31f19-SJC",
  "type": "message",
  "role": "assistant",
  "model": "anthropic/claude-opus-4.6",
  "content": [
    { "type": "text", "text": "Hello! How can I help you today?" }
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 10,
    "output_tokens": 12,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0,
    "cost": 0.00042,
    "bz_cost": 0.00042
  }
}

??????????????? HTTP ???????? error.type ???error.code ???????? HTTP ???????????????????????

模型

列出所有可用模型及其定價和能力資訊。 此端點不需要身份驗證。

GET/v1/models
# Text models (default)
curl https://api.bazaarlink.ai/v1/models

# Complete catalog
curl "https://api.bazaarlink.ai/v1/models?output_modalities=all"

回應

{
  "data": [
    {
      "id": "openai/gpt-4o",
      "name": "GPT 4.1",
      "context_length": 1047576,
      "modality": "text+image+file->text",
      "pricing": {
        "prompt": "2.00",
        "completion": "8.00"
      }
    }
  ]
}
// /v1/models — Response Schema
type ModelsResponse = {
  data: Model[];
};

type Model = {
  id: string;                    // Model ID (e.g. "openai/gpt-4o")
  name: string;                  // Human-readable name
  context_length: number | null; // Max context window in tokens
  modality: string | null;       // e.g. "text->text", "text+image->text"
  architecture?: {
    input_modalities?: string[];
    output_modalities?: Array<
      "text" | "image" | "embeddings" | "audio" |
      "video" | "rerank" | "speech" | "transcription"
    >;
  };
  pricing: {
    prompt: string;              // Input price per 1M tokens (USD)
    completion: string;          // Output price per 1M tokens (USD)
  };
  description?: string | null;   // Model description
  top_provider?: {
    max_completion_tokens?: number;
  };
  supported_parameters?: string[]; // e.g. ["tools", "response_format", "reasoning"]
  pricing_tiers?: {               // Present only for models with input-length tiers
    above_prompt_tokens: number;  // Ascending; strict "greater than" threshold
    prompt: string;                // USD per token, override tier
    completion: string;            // USD per token, override tier
  }[];
};

依輸入長度分階定價

部分模型在 prompt 超過 token 門檻後會切換到不同的整張價目表,並非只有超過門檻的部分套用新價 — 而是整張價目表切換。門檻為嚴格不等式:輸入 token 數剛好等於 N 時仍套用 N 以下的那一階,僅當輸入 token 數大於 N 時才套用較高階。

pricing_tiers 是 pricing 的同層欄位,僅當模型有超出基礎價的覆寫階層時才會出現。項目依 above_prompt_tokens 遞增排序;prompt/completion 為每 token 的美元價(與 pricing.prompt/pricing.completion 同單位)。pricing.prompt 與 pricing.completion 永遠是基礎(最低)那一階。

大多數模型沒有分階定價 — 對這些模型,回應中會完全沒有 pricing_tiers 這個欄位。

{
  "id": "openai/gpt-4o",
  "name": "GPT 4.1",
  "pricing": {
    "prompt": "2.00",
    "completion": "8.00"
  },
  "pricing_tiers": [
    {
      "above_prompt_tokens": 128000,
      "prompt": "4.00",
      "completion": "16.00"
    }
  ]
}

可用模型 (146)

以下是目前 BazaarLink 上可用的模型,從資料庫動態載入:

Qwen
qwen/qwen3.8-max1000K ctx · $2.00/$6.00text+image+video->text
qwen/qwen3.7-plus1000K ctx · $0.32/$1.28text+image->text
qwen/qwen3.7-max1000K ctx · $1.48/$4.42text->text
qwen/qwen3.7-flash1000K ctx · $0.03/$0.13text+image+video->text
qwen/qwen3.5-35b-a3b262K ctx · $0.31/$1.25text+image+video->text
qwen/qwen3.5-9b262K ctx · $0.10/$0.15text+image+video->text
qwen/qwen3.5-27b262K ctx · $0.20/$1.56text+image+video->text
qwen/qwen3-next-80b-a3b-instruct262K ctx · $0.10/$1.10text->text
qwen/qwen3.5-397b-a17b262K ctx · $0.55/$3.50text+image+video->text
qwen/qwen3.6-plus1000K ctx · $0.33/$1.95text+image+video->text
qwen/qwen3-coder-flash128K ctx · $0.20/$0.97text->text
qwen/qwen3.5-122b-a10b262K ctx · $0.29/$2.40text+image+video->text
qwen/qwen3-vl-235b-a22b-instruct262K ctx · $0.21/$1.90text+image+video->text
qwen/qwen3.8-27b262K ctx · $0.45/$3.20text+image+video->text
qwen/qwen3-coder-plus128K ctx · $0.65/$3.25text->text
qwen/qwen3-max262K ctx · $0.78/$3.90text->text
qwen/qwen3.8-2.4t-a95b262K ctx · $2.00/$6.00text->text
qwen/qwen3-embedding-8b33K ctx · $0.01/$0.00text->embeddings
qwen/qwen3-embedding-4b33K ctx · $0.02/$0.00text->embeddings
qwen/qwen3.5-flash-02-231000K ctx · $0.07/$0.26text+image+video->text
qwen/qwen3-coder-30b-a3b-instruct262K ctx · $0.07/$0.28text->text
qwen/qwen3-vl-32b-instruct131K ctx · $0.10/$0.42text+image->text
qwen/qwen3-vl-8b-instruct262K ctx · $0.12/$0.46text+image->text
qwen/qwen3-coder-next262K ctx · $0.12/$0.80text->text
qwen/qwen3-vl-30b-a3b-instruct262K ctx · $0.15/$0.60text+image->text
qwen/qwen3.6-35b-a3b262K ctx · $0.10/$0.90text+image+video->text
qwen/qwen3.5-plus-02-151000K ctx · $0.26/$1.56text+image+video->text
qwen/qwen3.6-27b262K ctx · $0.29/$2.40text+image+video->text
qwen/qwen3-coder262K ctx · $0.30/$1.00text->text
qwen/qwen3.5-plus-202604201000K ctx · $0.30/$1.80text+image+video->text
qwen/qwen-2.5-72b-instruct33K ctx · $0.36/$0.40text->text
qwen/qwen-image-3 · $0.00/$0.00text+image->image
qwen/qwen-image-3-pro · $0.00/$0.00text+image->image
OpenAI
openai/gpt-5.3-codex400K ctx · $1.75/$14.00text->text
openai/gpt-6-luna1050K ctx · $0.10/$0.50text+image+file->text
openai/gpt-5.6-luna1050K ctx · $0.20/$1.20text+image+file->text
openai/gpt-5.4-mini400K ctx · $0.75/$4.50text+image->text
openai/gpt-6-sol1050K ctx · $2.00/$10.00text+image+file->text
openai/gpt-6.1-sol1050K ctx · $2.00/$10.00text+image+file->text
openai/gpt-5.41050K ctx · $2.50/$15.00text+image->text
openai/gpt-5.51050K ctx · $5.00/$30.00text+image->text
openai/gpt-6-astra1050K ctx · $10.00/$50.00text+image+file->text
openai/gpt-5.6-terra1050K ctx · $2.00/$12.00text+image+file->text
openai/sora-2-pro · $0.00/$0.00text+image->video
openai/text-embedding-3-small8K ctx · $0.02/$0.00text->embeddings
openai/gpt-oss-20b131K ctx · $0.03/$0.13text->text
openai/gpt-oss-120b131K ctx · $0.15/$0.60text->text
openai/gpt-oss-safeguard-20b131K ctx · $0.07/$0.30text->text
openai/text-embedding-ada-0028K ctx · $0.10/$0.00text->embeddings
openai/text-embedding-3-large8K ctx · $0.13/$0.00text->embeddings
openai/gpt-5.6-luna-pro1050K ctx · $0.20/$1.20text+image+file->text
openai/gpt-3.5-turbo16K ctx · $0.50/$1.50text->text
openai/gpt-5.6-sol1050K ctx · $4.00/$20.00text+image+file->text
openai/gpt-image-1-mini400K ctx · $2.50/$2.50text+image->image
openai/gpt-4o128K ctx · $2.50/$10.00text+image+file->text
openai/gpt-image-2.5-sunburst400K ctx · $8.00/$8.00text+image->image
openai/gpt-5.4-image-2272K ctx · $8.00/$15.00text+image+file->text+image
openai/gpt-image-2.5-flare400K ctx · $8.00/$8.00text+image->image
openai/gpt-image-1400K ctx · $10.00/$10.00text+image->image
Google
google/gemini-2.5-flash-lite1049K ctx · $0.10/$0.40text->text
google/gemini-3.1-flash-lite-preview1049K ctx · $0.25/$1.50text+image+video+audio->text
google/gemini-3.1-pro-preview1049K ctx · $2.00/$12.00audio+image+text+video->text
google/gemma-3-4b-it131K ctx · $0.05/$0.10text+image->text
google/gemini-2.5-flash1049K ctx · $0.30/$2.50text->text
google/gemini-3.5-flash-lite1000K ctx · $0.30/$2.50text+image+video+audio->text
google/gemini-3-flash-preview1000K ctx · $0.50/$3.00text+image+audio+video->text
google/gemini-3.6-flash1000K ctx · $1.50/$7.50text+image+video+audio->text
google/gemini-3.7-flash1000K ctx · $0.75/$3.75text+image+video+audio->text
google/gemini-3.8-flash1000K ctx · $0.75/$3.75text+image+video+audio->text
google/gemini-2.5-pro1049K ctx · $1.25/$10.00text->text
google/gemini-2.5-pro-preview-05-061049K ctx · $1.25/$10.00text->text
google/gemini-3.5-flash1000K ctx · $1.50/$9.00text+image+video+audio->text
google/gemma-4-26b-a4b-it262K ctx · $0.09/$0.34text+image+video->text
google/gemma-4-31b-it262K ctx · $0.09/$0.34text+image+video->text
google/gemini-embedding-00120K ctx · $0.15/$0.00text->embeddings
google/gemini-embedding-2-preview8K ctx · $0.20/$0.00text+image+file+audio+video->embeddings
google/gemini-2.5-flash-image33K ctx · $0.30/$2.50text+image->text+image
google/gemini-3.1-flash-image131K ctx · $0.50/$3.00text+image->text+image
google/gemini-3.1-flash-image-preview66K ctx · $0.50/$3.00text+image->text+image
google/gemini-2.5-pro-preview1049K ctx · $1.25/$10.00text+image+file+audio->text
google/gemini-3-pro-image131K ctx · $2.00/$12.00text+image->text+image
google/veo-3.1 · $0.00/$0.00text+image->video
Anthropic
anthropic/claude-sonnet-4.61000K ctx · $3.00/$15.00text+image+file->text
anthropic/claude-opus-4.61000K ctx · $5.00/$25.00text+image+file->text
anthropic/claude-haiku-4.5200K ctx · $1.00/$5.00text+image+file->text
anthropic/claude-sonnet-51000K ctx · $2.00/$10.00text+image+file->text
anthropic/claude-sonnet-5.51000K ctx · $2.00/$10.00text+image+file->text
anthropic/claude-sonnet-4.51000K ctx · $3.00/$15.00text+image+file->text
anthropic/claude-opus-5.51000K ctx · $4.00/$20.00text+image+file->text
anthropic/claude-opus-4.81000K ctx · $5.00/$25.00text+image+file->text
anthropic/claude-opus-4.71000K ctx · $5.00/$25.00text+image+file->text
anthropic/claude-opus-4.5200K ctx · $5.00/$25.00text+image+file->text
anthropic/claude-opus-51000K ctx · $5.00/$25.00text+image+file->text
anthropic/claude-fable-51000K ctx · $10.00/$50.00text+image+file->text
anthropic/claude-fable-5.11000K ctx · $10.00/$50.00text+image+file->text
anthropic/claude-sonnet-4200K ctx · $3.00/$15.00text+image+file->text
anthropic/claude-opus-4.1200K ctx · $15.00/$75.00text+image+file->text
DeepSeek
deepseek/deepseek-v4-flash1000K ctx · $0.20/$0.40text->text
deepseek/deepseek-v4-pro1000K ctx · $2.40/$4.80text->text
deepseek/deepseek-v4.1-flash1000K ctx · $0.30/$1.20text+image->text
deepseek/deepseek-chat-v3.1131K ctx · $0.25/$0.95text->text
deepseek/deepseek-chat164K ctx · $0.40/$1.30text->text
deepseek/deepseek-r1164K ctx · $0.70/$2.50text->text
deepseek/deepseek-v4-pro-08131000K ctx · $1.32/$3.96text->text
deepseek/deepseek-v4-flash-07311049K ctx · $0.44/$1.32text->text
deepseek/deepseek-r1-0528164K ctx · $0.50/$2.15text->text
deepseek/deepseek-v4-flash-0731free1049K ctx · $0.20/$0.40text->text
Zhipu AI
z-ai/glm-5v-turbo203K ctx · $1.20/$4.00text+image+video->text
z-ai/glm-5.3-flash1000K ctx · $0.15/$0.50text+image+video->text
z-ai/glm-4.6203K ctx · $0.43/$1.75text->text
z-ai/glm-5.3-flashx1000K ctx · $0.37/$1.25text+image+video->text
z-ai/glm-5.31024K ctx · $1.40/$4.40text->text
z-ai/glm-4.7-flash200K ctx · $0.06/$0.40text->text
z-ai/glm-4.5-air131K ctx · $0.13/$0.85text->text
z-ai/glm-4.6v131K ctx · $0.30/$0.90text+image+video->text
z-ai/glm-4.5v66K ctx · $0.60/$1.80text+image->text
z-ai/glm-4.5131K ctx · $0.60/$2.20text->text
xAI
x-ai/grok-build-0.1256K ctx · $1.00/$2.00text+image->text
x-ai/grok-4.31000K ctx · $1.25/$2.50text+image->text
x-ai/grok-4.6500K ctx · $2.00/$6.00text+image->text
x-ai/grok-4.5500K ctx · $2.00/$6.00text+image->text
x-ai/grok-imagine-image-2.0 · $0.00/$0.00text+image->image
x-ai/grok-4.202000K ctx · $1.25/$2.50text+image+file->text
x-ai/grok-4.7500K ctx · $1.60/$4.80text+image+file->text
Alibaba
alibaba/wan3.0-image-to-video · $0.00/$0.00text+image->video
alibaba/wan3.0-video-edit · $0.00/$0.00text+video->video
alibaba/wan3.0-reference-to-video · $0.00/$0.00text+image+video->video
alibaba/wan3.0-text-to-video · $0.00/$0.00text->video
xiaomi
xiaomi/mimo-v2.6-flash1049K ctx · $0.14/$0.28text+image+video+audio->text
xiaomi/mimo-v2.6-pro1049K ctx · $0.43/$0.87text+image+video+audio->text
xiaomi/mimo-v2.51050K ctx · $0.14/$0.28text+image+audio+video->text
xiaomi/mimo-v2.5-pro1050K ctx · $0.43/$0.87text->text
ByteDance
bytedance/seedance-2.5 · $0.00/$0.00text+image+audio+video->video
bytedance/seedance-2.0-fast · $0.00/$0.00text+image+audio+video->video
bytedance/seedance-2.0 · $0.00/$0.00text+image+audio+video->video
bytedance/seedance-1-5-pro · $0.00/$0.00text+image->video
bytedance-seed
bytedance-seed/seed-1.6-flash262K ctx · $0.07/$0.30text+image+video->text
bytedance-seed/seed-2.0-mini262K ctx · $0.10/$0.40text+image+video->text
bytedance-seed/seed-1.6262K ctx · $0.25/$2.00text+image+video->text
bytedance-seed/seed-2.0-lite262K ctx · $0.25/$2.00text+image+video->text
MiniMax
minimax/minimax-m31049K ctx · $0.30/$1.20text+image+video->text
minimax/minimax-m2.1205K ctx · $0.30/$1.20text->text
minimax/hailuo-3-max · $0.00/$0.00text+image->video
Moonshot AI
moonshotai/kimi-k31049K ctx · $3.00/$15.00text+image->text
moonshotai/kimi-k2-0905262K ctx · $0.60/$2.50text->text
typesafe-ai
typesafe-ai/jev32K ctx · $0.04/$0.00text->decisions

在 模型頁面瀏覽所有模型。

結構化評估(Jev)

Jev 會根據 JSON 狀態回答具名問題,並回傳 boolean、choice 或 score 類型的答案;適合將明確判準轉成程式可讀的評估結果。

僅供評估與判斷
Jev 不支援聊天。請將 Jev 請求送至 POST /v1/evaluations;若送至 POST /v1/chat/completions,會收到 HTTP 400。
POST/v1/evaluations

使用 BazaarLink API 金鑰呼叫以下端點。完整網址為 https://api.bazaarlink.ai/v1/evaluations。

欄位說明

model
string
選用。省略時預設為 typesafe-ai/jev;其他模型識別值會回傳 HTTP 400,錯誤代碼為 model_not_available。
state
string | object | array
必填,須為 JSON 字串、物件或陣列,作為待評估的狀態資料。序列化後的 state 與 questions 合計超過 32,000 tokens 時,會回傳 context_length_exceeded。
questions
record<string, Question>
必填,至少包含一個具名問題的物件。每個問題名稱會成為回應 answers 物件中的鍵。
type
boolean | choice | score
每個問題皆必填;可用 boolean、choice 或 score。
instructions
string | object | array
每個問題皆必填;可使用 JSON 字串、物件或陣列,描述要判斷的內容。
criteria
object | array
依 type 決定:boolean 可省略,若提供則為鍵名只能是 true 或 false 的物件;choice 必須是非空物件;score 必須是至少含兩項且順序有意義的陣列。

答案類型

  • boolean — criteria 可省略;如有提供,只接受 true 與 false 作為鍵。boolean 答案包含數值型的 probability。
  • choice — criteria 必須是非空物件,以選項名稱對應 JSON criteria。答案包含字串 choice;probabilities 以選項名稱為鍵。
  • score — criteria 必須是至少含兩項的有序陣列。答案包含數值 score;score 是依 criteria 陣列順序、在索引 0..N-1 上的期望值;probabilities 以相同索引的字串形式作為鍵。

請求範例

curl --fail-with-body https://api.bazaarlink.ai/v1/evaluations \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "typesafe-ai/jev",
  "state": "The support agent issued a full refund and apologised for the delay.",
  "questions": {
    "refunded": {
      "type": "boolean",
      "instructions": "Was a refund issued?"
    },
    "tone": {
      "type": "choice",
      "instructions": "Tone of the agent?",
      "criteria": {
        "apologetic": "The agent apologises",
        "neutral": "No emotional language",
        "hostile": "The agent is rude"
      }
    },
    "quality": {
      "type": "score",
      "instructions": "How complete was the resolution?",
      "criteria": [
        "poor",
        "partial",
        "complete"
      ]
    }
  }
}'

成功回應範例

範例回應包含 id、object、model、answers、usage、rounding 和 warnings。answers 以問題名稱為鍵。usage 包含 input_tokens、output_tokens 和 total_tokens;rounding 顯示 probabilityDecimals 和 scoreDecimals。warnings 是陣列,本例為空。answers 中的 choice probabilities 以選項名稱為鍵,score probabilities 則以 criteria 項目的索引字串為鍵。

{
  "id": "eval-a3d350e5-2705-4a9b-be7c-838fa4e4eb2b",
  "object": "evaluation",
  "model": "typesafe-ai/jev",
  "answers": {
    "refunded": {
      "type": "boolean",
      "probability": 0.99
    },
    "tone": {
      "type": "choice",
      "choice": "apologetic",
      "probabilities": {
        "apologetic": 1,
        "neutral": 0,
        "hostile": 0
      }
    },
    "quality": {
      "type": "score",
      "score": 1.98,
      "probabilities": {
        "0": 0,
        "1": 0.02,
        "2": 0.98
      }
    }
  },
  "usage": {
    "input_tokens": 394,
    "output_tokens": 74,
    "total_tokens": 468
  },
  "rounding": {
    "probabilityDecimals": 2,
    "scoreDecimals": 2
  },
  "warnings": []
}

聊天端點的錯誤回應

將 Jev 傳給聊天端點會收到 HTTP 400。以下欄位和值符合端點處理程式;message 以佔位文字表示,實際文字由伺服器提供。

{
  "error": {
    "message": "<server-generated message>",
    "type": "invalid_request_error",
    "code": 400
  }
}

串流

設定 stream: true 以接收 Server-Sent Events (SSE) 串流。每個事件包含一個回應片段。

from openai import OpenAI

client = OpenAI(
    base_url="https://api.bazaarlink.ai/v1",
    api_key="sk-bl-YOUR_API_KEY",
)

stream = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6",
    messages=[{"role": "user", "content": "Count to 10 slowly."}],
    stream=True,
)

for chunk in stream:
    content = chunk.choices[0].delta.content
    if content:
        print(content, end="", flush=True)

SSE 格式

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":"Hello"},"index":0}]}

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":" world"},"index":0}]}

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":{"prompt_tokens":10,"completion_tokens":4,"total_tokens":14}}

data: [DONE]
串流中的使用量
串流時,使用量資料會在 [DONE] 訊息之前的最後一個區塊中返回,該區塊的 choices 陣列帶有一個空 delta 與 finish_reason: "stop"。

Keep-alive 與收尾行為

串流可能包含 SSE 註解列及未知或 ping keep-alive 事件;請忽略這些內容並解析 data frame。最後一個 data frame 可能在 data: [DONE] 前帶有 usage。

: keepalive          <- SSE comment line — ignore, do NOT JSON.parse

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":"Hi"},"index":0}]}

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":{...}}

data: [DONE]

串流取消

串流請求可透過關閉客戶端連線來取消 — 例如呼叫 AbortController.abort() 或關閉 stream 物件。BazaarLink 收到取消訊號後會立刻停止轉發後續內容,並中止對上游供應商的請求。

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.bazaarlink.ai/v1",
  apiKey: "sk-bl-YOUR_API_KEY",
});

const controller = new AbortController();

const stream = await client.chat.completions.create(
  {
    model: "anthropic/claude-sonnet-4.6",
    messages: [{ role: "user", content: "Write a long story." }],
    stream: true,
  },
  { signal: controller.signal }
);

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}

// e.g. on a "Stop" button click:
controller.abort();
被中斷的串流不收費
如果串流在最後的 usage chunk 抵達前就結束 — 包含客戶端主動取消的情況 — 這筆請求就沒有可信的 token 用量依據,BazaarLink 會全額退還預扣的額度。取消前已送到你客戶端的內容不會計費。
不保證上游立即停止
關閉連線會讓 BazaarLink 立刻停止轉發並停止為後續 token 計費,但上游供應商是否會在自己的伺服器上瞬間停止生成,取決於該供應商本身 — 有些供應商斷線後仍會短暫繼續運算。

串流中途出錯

錯誤幀沒有 choices 欄位
如果串流已經開始後才發生失敗(例如上游連線中斷),您會收到一個 {error:{message,type,code}} 形狀的 SSE 資料幀,而不是平常的 {choices:[...]} —— HTTP 狀態不會改變,因為 header 早就送出了。讀取 choices[0].delta 前請先檢查是否有 error 欄位;計費只會算到已經串流出去的 token(適用部分計費)。
data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":"The capital of "},"index":0}]}

data: {"error":{"message":"The request could not be completed.","type":"upstream_error","code":502}}

data: [DONE]

嵌入向量

嵌入向量(Embeddings)是能捕捉語意的數值表示法——把文字轉換成向量(一串數字),可用於各種機器學習任務。BazaarLink 提供與 OpenAI Embeddings API 相容的統一端點,讓您透過同一組介面呼叫多家供應商的嵌入模型。

??????????? BazaarLink ?? ID??? ID ? x-request-id ?????? ID ?? GET /v1/generation????????? x-generation-id ???? ID?usage.cost ?????????????????????????????? 404 ??????

什麼是嵌入向量?

嵌入向量把文字轉換成高維度向量,語意相近的文字在向量空間裡的距離也會更接近——例如「貓」與「小貓」的嵌入會很相似,但「貓」與「飛機」會相距很遠。這種向量表示法讓機器能夠理解文字之間的關聯,是許多 AI 應用的基礎。

常見應用場景

場景
說明
RAG(檢索增強生成)打造能在生成答案前,先從知識庫中檢索相關內容的系統——嵌入向量能找出最相關的文件,放進 LLM 的上下文。
語意搜尋把文件和查詢都轉成嵌入向量,再用向量相似度找出最相關的文件——比單純比對關鍵字更能理解語意、效果更好。
推薦系統為商品、文章、影片等項目與使用者偏好產生嵌入向量,藉由向量比對推薦相近項目——即使沒有共同關鍵字也能找到語意相關的內容。
分群與分類透過分析嵌入向量的模式,把相似的文件分群或分類——嵌入向量相近的文件通常屬於相同主題或類別。
重複內容偵測透過比對嵌入向量的相似度找出重複或近似重複的內容——即使內容經過改寫或換句話說也能偵測到。
異常偵測找出嵌入向量明顯偏離資料集一般模式的內容,藉此辨識異常或離群的內容。
POST/v1/embeddings
Note
若上游來源不支援所需的嵌入模型,請求可以改試其他可用來源;若沒有來源支援該模型,請求會回傳錯誤。

參數

model必填
string
要使用的嵌入模型,例如 "openai/text-embedding-3-small"。
input必填
string | string[] | ContentItem[]
要嵌入的文字 —— 可為單一字串、一次批次呼叫用的字串陣列,或(支援的模型)混合 text 與 image_url 部分的 {content:[...]} 項目陣列。
dimensions
integer
要求的輸出向量維度。只有支援可變維度的模型才會採用(例如 OpenAI text-embedding-3 系列);原樣轉發給上游供應商,不支援的模型會忽略此參數。
encoding_format
string
要求的嵌入編碼格式,例如 "float" 或 "base64"。原樣轉發給上游供應商 —— 是否支援視模型而定。
provider
object
Unsupported. The entire object is ignored and removed before forwarding; it cannot select an upstream or price tier.

基本請求

from openai import OpenAI

client = OpenAI(
    base_url="https://api.bazaarlink.ai/v1",
    api_key="sk-bl-YOUR_API_KEY",
)

response = client.embeddings.create(
    model="openai/text-embedding-3-small",
    input="The quick brown fox jumps over the lazy dog",
)

print(response.data[0].embedding)  # 1536-dimensional vector

批次處理

傳送字串陣列,可在單一請求中嵌入多筆文字 —— 比逐筆呼叫更便宜也更快。

response = client.embeddings.create(
    model="openai/text-embedding-3-small",
    input=[
        "Machine learning is a subset of artificial intelligence",
        "Deep learning uses neural networks with multiple layers",
        "Natural language processing enables computers to understand text",
    ],
)

for i, item in enumerate(response.data):
    print(f"Embedding {i}: {len(item.embedding)} dimensions")

多模態輸入(圖片+文字)

支援圖片輸入的模型(output_modalities 含 "embeddings"、inputModalities 含 "image")接受 {content:[{type:"text",...}, {type:"image_url",...}]} 形式的輸入項目,讓您可以單獨嵌入圖片,或圖片與文字一起嵌入。

視模型而定
只有部分嵌入模型接受圖片輸入 —— 傳送 image_url 內容前,請先到 Models 頁面確認該模型支援的模態。純文字模型會拒絕這種格式。
import requests

response = requests.post(
    "https://api.bazaarlink.ai/v1/embeddings",
    headers={
        "Authorization": "Bearer sk-bl-YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "google/gemini-embedding-2-preview",
        "input": [{
            "content": [
                {"type": "text", "text": "A scenic boardwalk through a green meadow"},
                {"type": "image_url", "image_url": {"url": "https://example.com/boardwalk.jpg"}},
            ]
        }],
        "encoding_format": "float",
    },
)

embedding = response.json()["data"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}")

尋找嵌入模型

沒有專屬的嵌入模型清單端點 —— 呼叫 GET /v1/models,在前端篩選 output_modalities 包含 "embeddings" 的項目,或直接到 Models 頁面瀏覽。

限制

  • 不支援串流 —— 與 chat completions 不同,嵌入向量一律以完整回應形式回傳。
  • 每個模型都有輸入長度上限;超過上限的文字會在上游被截斷或拒絕。
  • 相同輸入的嵌入結果是確定性的(deterministic)—— 不涉及 temperature 或隨機性。

最佳實務

  • 依速度/品質/成本的取捨選擇模型 —— 較小的模型(如 qwen/qwen3-embedding-4b)較便宜也較快;較大的模型(如 openai/text-embedding-3-large)通常嵌入精準度較高。
  • 把多筆文字合併成一次請求,而不是逐筆呼叫 —— 減少往返次數與額外開銷。
  • 快取結果 —— 相同輸入的嵌入結果永遠不變,應該儲存起來而非重新產生。
  • 比對時用餘弦相似度(cosine similarity),不要用歐氏距離 —— 具尺度不變性,對高維向量效果更好。
  • 留意每個模型的上下文長度 —— 長文件在嵌入前可能需要先分段(chunking)。

專用參數

取樣參數影響 token 產生過程。BazaarLink 會將支援的參數傳遞給上游 provider;不支援的參數會被静默忽略。

取樣參數

純轉發——沒有本地預設值
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
temperature
number
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
top_p
number
核取樣概率質量。預設:1
top_k
integer
取樣參數會轉送且不做範圍驗證;模型可能自行限制或忽略超出支援範圍的值。
frequency_penalty
number
懲罰重複的 token。範圍:[-2, 2]。預設:0
presence_penalty
number
基於存在情況懲罰 token。範圍:[-2, 2]。預設:0
repetition_penalty
number
降低輸入中 token 重複的機率。範圍:(0, 2]。預設:1
min_p
number
相對最高機率 token 的最低入選機率。範圍:[0, 1]。預設:0
top_a
number
基於最高機率 token 的動態 Top-P。範圍:[0, 1]。預設:0
seed
integer
整數隨機種子,用於確定性取樣。部分模型不保證
max_tokens
integer
要生成的最大 token 數量
n
integer
產生的完成數量。預設:1
logit_bias
object
將 token ID 映射到偏差値 [-100, 100],在取樣前加到機率。僅限 OpenAI 系列模型 —— 見下方說明。
logprobs
boolean
回傳每個輸出 token 的對數機率。僅限 OpenAI 系列模型 —— 見下方說明。
top_logprobs
integer
每個位置回傳概率最高的 N 個候選 token(需配合 logprobs: true)。範圍:0–20。僅限 OpenAI 系列模型 —— 見下方說明。
response_format
object
強制結構化 JSON 輸出。請參閱結構化輸出章節
structured_outputs
boolean
在支援的 provider 上要求嚴格符合 JSON schema 的輸出。原樣轉發
reasoning
object
Provider 專屬的 reasoning/thinking 設定。原樣轉發
reasoning_effort
string
OpenAI o 系列風格的 reasoning 強度:"low"、"medium" 或 "high"。原樣轉發
stop
string | string[]
停止序列 — 遇到時停止生成
tools
Tool[]
模型可以呼叫的工具(函式)列表
tool_choice
string | object
控制工具使用:"auto"、"none" 或指定工具
parallel_tool_calls
boolean
啟用並行工具呼叫功能。預設:true。僅限 OpenAI 系列模型 —— 見下方說明。

信用額度

查詢當前信用額度餘額與累積 API 使用量。

GET/v1/credits
Auth
需要 Bearer token(標準 API key sk-bl-...)。

範例請求

curl https://api.bazaarlink.ai/v1/credits \
  -H "Authorization: Bearer sk-bl-YOUR_KEY"

回應

{
  "data": {
    "total_credits": 100.00,
    "total_usage": 12.34
  }
}

錯誤:401(金鑰無效或遺失)、403(帳號已停權)。

生成詳細資料

使用回應 id 或 x-request-id 標頭中的不透明 BazaarLink 請求 ID 呼叫 GET /v1/generation;非串流回應也會在 x-generation-id 提供此 ID。統計資料可能延遲數秒;若收到 404,請短暫重試。

GET/v1/generation?id=<generation-id>
Auth
需要 Bearer token(標準 API key)。必填 query 參數:id。

範例請求

curl "https://api.bazaarlink.ai/v1/generation?id=BAZAARLINK_REQUEST_ID" \
  -H "Authorization: Bearer sk-bl-YOUR_KEY"

回應

{
  "data": {
    "id": "85e6f35c71a31f19-SJC",
    "model": "openai/gpt-4o",
    "provider": "bazaarlink",
    "created_at": "2026-04-20T10:00:00.000Z",
    "app_name": "MyApp",
    "finish_reason": "stop",
    "status": 200,
    "duration_ms": 1234,
    "first_token_ms": 234,
    "throughput": 45.6,
    "usage": {
      "prompt_tokens": 100,
      "completion_tokens": 200,
      "total_tokens": 300,
      "prompt_tokens_details": { "cached_tokens": 50 },
      "completion_tokens_details": { "reasoning_tokens": 30 },
      "cost": 0.00123
    },
    "cost_breakdown": {
      "subtotal": 0.00123,
      "cache_discount": 0.00015,
      "total": 0.00108
    }
  }
}

錯誤:400(缺少 id)、401(auth)、404(找不到該 generation)。

API 金鑰資訊

查詢當前 API key 的 rate limit 層級與累計使用量(回應格式與業界慣用的金鑰查詢 API 相容)。

GET/v1/key
Auth
需要 Bearer token(標準 API key)。

回應

{
  "data": {
    "label": "Production Key",
    "limit": null,
    "limit_remaining": 100.00,
    "limit_reset": null,
    "expires_at": null,
    "is_free_tier": false,
    "is_management_key": false,
    "is_provisioning_key": false,
    "usage": 12.34,
    "usage_daily": 0.12,
    "usage_weekly": 0.45,
    "usage_monthly": 1.23,
    "requests": 1234,
    "requests_daily": 10,
    "requests_weekly": 50,
    "requests_monthly": 200,
    "rate_limit": { "requests": 600, "interval": "1m", "note": "Paid-tier rate limit." }
  }
}
Note
當信用餘額低於 $10 時,is_free_tier 為 true。統計區間以 UTC 為準:daily = 當日、weekly = 週一至週日、monthly = 當月 1 日至月底。若該 API key 有設定個別用量上限(透過建立/更新 key 時的 limit 參數),limit / limit_remaining / limit_reset 會反映該上限與對應週期的已用量;未設定時 limit 為 null,limit_remaining 退回帳號信用餘額。expires_at 為該 key 的到期時間(未設定則為 null)。is_management_key 與 is_provisioning_key 目前為同一概念的別名,皆表示這是一把管理金鑰。
BYOK
BazaarLink 目前沒有提供「自帶金鑰」(BYOK)方案,因此本端點不會回傳 byok_usage 相關欄位。

錯誤:401(auth)、404(找不到使用者,極少發生)。

錯誤代碼

錯誤回應格式

錯誤 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 僅供顯示。

代碼
名稱
說明
424依賴失敗您自行設定的 BYOK 金鑰被上游供應商拒絕;請在 BYOK 設定中檢查或輪替。此錯誤只會在 strict 模式出現
400請求無效請求格式錯誤、messages 陣列為空,或缺少必填欄位
401未授權API 金鑰遺失、無效或已停用
402需要付款帳戶點數不足、單一金鑰花費上限已達,或每週 / 每月預算上限已達
403禁止存取帳戶已停用或沒有此操作的權限
404找不到資源指定的模型、生成工作、金鑰或其他資源不存在
409狀態衝突資源尚未進入必要狀態,例如影片工作尚未完成
410資源已移除指定模型已退役,必須改用其他模型
413請求體過大請求 body 超過 10 MB;請縮小內容或分拆請求
416範圍無法滿足生成影片內容所要求的 byte range 無效
429請求過多已超過速率限制;請查看 Retry-After 標頭後再重試
500伺服器錯誤BazaarLink 內部錯誤
502閘道錯誤所有上游來源皆無法處理;請求會回傳錯誤。
503服務不可用此模型沒有設定上游提供者;請聯絡管理員
504閘道逾時上游連線或串流停滯並超過等待時間

機器可讀的帳務代碼

同樣是 402,也可能代表不同的帳務控制。請依下列穩定代碼顯示正確的處理方式。

代碼
說明
byok_key_invalid您自行設定的 BYOK 金鑰被上游供應商拒絕;請在 BYOK 設定中檢查或輪替。此錯誤只會在 strict 模式出現。
budget_cap_reached已達每週或每月的提醒型預算上限;提高或重設預算上限。
credit_limit_exceeded月結組織已用盡硬性信用額度;請聯絡帳務人員。
insufficient_credits預付用戶或組織無法保留足夠餘額;請先加值。
spend_limit_exceededAPI 金鑰已達每日、每週或每月花費上限。

詳細錯誤代碼

API 請求失敗時,error.code 會告訴你更具體的原因。即使兩個錯誤都是 HTTP 400,處理方式也可能不同:例如 unknown_model 表示模型名稱有誤,image_too_large 則表示圖片太大。請依下表找到原因與對應的處理方向。

模型與端點
模型查找、生命週期、定價、模態及端點相容性錯誤。
代碼
HTTP 狀態
unknown_model400
invalid_model_id400
model_not_found404
model_retired410
model_endpoint_mismatch400
embedding_on_chat_endpoint400
model_not_priced400
invalid_modality_for_model400
請求與安全
參數、上下文、工具、結構描述及內容安全拒絕。
代碼
HTTP 狀態
missing_required_field400
unsupported_param400
max_tokens_invalid400
context_too_long400
tool_use_unsupported400
malformed_tool_messages400
invalid_response_format_schema400
invalid_tools_definition400
content_moderation403
content_filter403
unknown_4xx400
圖片生成與編輯
圖片輸入、multipart 編輯、輸出及圖片管線錯誤。
代碼
HTTP 狀態
invalid_image_url400
input_images_not_supported400
invalid_content_type400
mask_not_supported400
unsupported_response_format400
missing_prompt400
missing_image400
too_many_images400
invalid_image_type400
image_too_large400
invalid_n400
pipeline_error502
no_images502
上游路由
經安全處理的供應商連線、驗證、限流及可用性錯誤。
代碼
HTTP 狀態
upstream_unreachable502
upstream_auth_failed502
upstream_rate_limited429
upstream_unavailable502/503
byok_key_invalid424

內容審查

所有請求在送往模型端之前,都會先經過自動化內容審查。不符合使用規範的請求會被拒絕,不會送達模型,並回傳 403 錯誤。

會被攔截的內容類別

審查依據我們的使用規範(Acceptable Use Policy)進行,主要攔截以下類別的內容:

  • 性剝削內容
  • 暴力威脅
  • 違法行為的操作指導
  • 生物危害相關內容

403 回應格式

請求被審查攔截時,會收到以下格式的錯誤回應:

{
  "error": {
    "message": "Your prompt was blocked by content moderation.",
    "type": "invalid_request_error",
    "code": "content_filter"
  }
}

被攔截的請求不會計費——你不會為被拒絕的請求付費。

誤判申訴

如果你認為某次請求被誤判攔截,請聯繫支援團隊並附上請求時間與(如方便的話)request id,我們會協助複查。

隱私說明

每一筆請求都會經過自動化內容審查。

判定為違規的請求,我們會保留其內容作為合規舉證之用。

其他請求不會保留完整提示詞內容。

速率限制、預算與緊急煞車

這些控制可能拒絕原本有效的請求。它們與供應商錯誤不同,也需要不同的復原方式。

控制機制
HTTP 狀態
辨識方式
請求速率限制429??????? 429?? Retry-After ? X-RateLimit-* ?????
限流懲罰封鎖429數字 code 429、暫時限制訊息及 Retry-After。
全域支出緊急煞車503數字 code 503、全域支出上限訊息,以及 30 或 300 秒的 Retry-After。
組織/團隊/成員/使用者支出煞車429數字 code 429,訊息會指出 spend circuit breaker 及受影響範圍。
帳務與預算控制402使用上方列出的穩定帳務字串代碼。

錯誤 envelope 依端點而異。若有 error.type,請搭配 HTTP 狀態碼判斷;error.code 可能是字串或數字狀態碼,也可能省略;error.message 僅供顯示。

影片與媒體資源狀態

影片驗證通常回傳數字 code 400;工作不存在為 404、模型退役為 410、影片內容尚未完成為 409、影片 byte range 無效為 416。重試前請先輪詢至完成,或修正 Range 標頭。

重試策略

只有在不修改請求也可能恢復的錯誤才應重試。若有 Retry-After,請依指定秒數等待;否則使用帶 jitter 的指數退避。限制重試次數,也不要同時疊加 SDK 自動重試與手動重試。

可退避重試
429、502、503、504。有 Retry-After 時必須優先遵守。生成類請求若遇到結果不明的網路中斷,應先查詢原工作,避免建立第二個工作。
修正後再重試
400、401、402、403、404、409、410、413、416。請先修正請求、憑證、餘額、權限、資源狀態或 Range 標頭。

錯誤處理

import random
import time
from openai import OpenAI, APIStatusError

client = OpenAI(
    base_url="https://api.bazaarlink.ai/v1",
    api_key="sk-bl-YOUR_API_KEY",
    max_retries=0,  # Avoid double retries; this example handles them.
)

RETRYABLE = {429, 502, 503, 504}

for attempt in range(5):
    try:
        response = client.chat.completions.create(
            model="openai/gpt-4o",
            messages=[{"role": "user", "content": "Hello!"}],
        )
        break
    except APIStatusError as error:
        if error.status_code not in RETRYABLE or attempt == 4:
            raise
        retry_after = error.response.headers.get("Retry-After")
        delay = (
            float(retry_after)
            if retry_after
            else min(8, 0.5 * (2 ** attempt)) + random.uniform(0, 0.25)
        )
        time.sleep(delay)

串流錯誤格式

在任何 token 串流之前發生的錯誤,會以標準 HTTP 錯誤回應(JSON body)回傳。

串流一旦開始,HTTP 回應已經是 200。用戶端必須解析每個 SSE data frame;只要出現頂層 error,或 choices[0].finish_reason === "error",就應視為失敗且回應不完整。

???????????BazaarLink ????????? error ??????? SSE ?????? 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.

版本管理

BazaarLink 只提供單一穩定的 API 路徑 /v1 —— 沒有依日期釘選的版本、也不需要管理版本 header。API 是持續演進,不是靠編號釋出版本。

非破壞性變更

以下這些會在不事先預告的情況下上線:

  • 新增端點
  • 目錄新增模型
  • 新增選填請求參數
  • 新增回應欄位
  • 新增帶選填屬性的 schema
  • 新增回應狀態/錯誤代碼
用防禦性寫法實作用戶端
請忽略您不認得的回應欄位,也不要在遇到列舉型欄位的未知值時直接失敗 —— 隨著目錄與功能擴充,會持續新增新值。

破壞性變更

這些情況很少見,包含:

  • 刪除或改名端點、參數、或回應欄位
  • 改變欄位型別
  • 把選填參數改成必填

就算真的發生,破壞性變更也只會影響特定端點,不會波及整個 /v1 —— 沒有單一版本升級能一次弄壞所有串接。我們目前還沒有發布正式、帶 Breaking 標籤的 changelog(見下方「掌握最新動態」)—— 若是對您串接來說很關鍵的部分,建議先聯繫 Support 確認,不要依賴沒有文件記載的行為。

下架政策

唯一該預期的常態性「破壞性」事件:個別模型會隨上游供應商淘汰而下架。可透過 GET /v1/models 查詢模型目前的狀態。

GET https://api.bazaarlink.ai/v1/models
Authorization: Bearer sk-bl-YOUR_API_KEY

# A model within 30 days of its deprecation date shows in the catalog
# with an "EOL" badge on the Models page. After the effective date it's
# dropped from the catalog and calls return:
# 410 { "error": { "type": "model_not_available", "code": "model_retired" } }

掌握最新動態

我們目前還沒有發布專屬的 API changelog 或 RSS feed。現階段請直接查看這個頁面、透過 GET /v1/models 追蹤模型狀態,或若您有關鍵串接需要提前得知變更,可聯繫 Support。

客服
客服
您好!有什麼可以協助?
請留下訊息,我們會盡快回覆。