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

API 參考

BazaarLink API 總覽

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

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 a provider-qualified catalog ID
  messages: Message[];             // Must contain at least one message

  // Generation
  stream?: boolean;
  temperature?: number;            // Range: [0, 2]
  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;      // Range: [-2, 2]
  presence_penalty?: number;       // Range: [-2, 2]
  repetition_penalty?: number;     // Range: (0, 2]
  min_p?: number;                  // Range: [0, 1]
  top_a?: number;                  // Range: [0, 1]

  // 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;

  // BazaarLink message transforms and fallback routing
  transforms?: Array<"middle-out">;
  models?: string[];             // Fallback list — this drives waterfall routing, not route
  route?: "fallback";            // Passthrough only; forwarded as-is, no local effect
  provider?: ProviderPreferences;
};

// 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;
};

// Provider routing preferences
type ProviderPreferences = {
  order?: string[];
  only?: string[];
  ignore?: string[];
  allow_fallbacks?: boolean;
  sort?:
    | "price"
    | "latency"
    | "throughput"
    | {
        by: string;
        partition?: string;
      };
  require_parameters?: boolean;
  data_collection?: "allow" | "deny";
  quantizations?: string[];
  max_price?: Record<string, 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;
  native_finish_reason: string | null;
  message: {
    role: "assistant";
    content: string | null;
    tool_calls?: ToolCall[];
  };
};

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

結束原因

finish_reason 使用 stop、length、tool_calls、content_filter、error 等正規化值;native_finish_reason 保留供應商的原始值。

JSON
{
  "finish_reason": "stop",
  "native_finish_reason": "stop"
}

查詢成本與統計資料

依 generation ID 查詢單次完成請求的詳細統計資料(ID 來自 chat/completions 回應的 id,或串流的 x-bz-gen-id header)。

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

對話完成

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

POST/v1/chat/completions

請求內文

model必填
string
模型 ID,例如 "openai/gpt-4o" 或 "anthropic/claude-sonnet-4.6"
messages必填
Message[]
包含 role 和 content 的訊息物件陣列
stream
boolean
若為 true,返回 Server-Sent Events 串流。預設:false
temperature
number
取樣溫度 0–2。越高越隨機。預設:1
max_tokens
integer
要生成的最大 token 數量
max_completion_tokens
integer
max_tokens 的別名(OpenAI o 系列相容)。兩者皆支援,以提供的為準
top_p
number
核取樣概率質量。預設:1
top_k
integer
限制候選 token 數量。0 表示停用(考慮全部)。預設:0
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"。原樣轉發
transforms
string[]
要套用的訊息轉換,例如 ["middle-out"]。省略則在 ≤8k context 模型自動套用
models
string[]
備用模型清單——BazaarLink 依序嘗試,主模型失敗時自動切換
route
string
進階路由相容欄位——大多數使用者不需要。要用 fallback 請用 "models"。
provider
object
進階路由偏好——大多數使用者不需要。
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 a provider-qualified catalog ID
  messages: Message[];             // Must contain at least one message

  // Generation
  stream?: boolean;
  temperature?: number;            // Range: [0, 2]
  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;      // Range: [-2, 2]
  presence_penalty?: number;       // Range: [-2, 2]
  repetition_penalty?: number;     // Range: (0, 2]
  min_p?: number;                  // Range: [0, 1]
  top_a?: number;                  // Range: [0, 1]

  // 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;

  // BazaarLink message transforms and fallback routing
  transforms?: Array<"middle-out">;
  models?: string[];             // Fallback list — this drives waterfall routing, not route
  route?: "fallback";            // Passthrough only; forwarded as-is, no local effect
  provider?: ProviderPreferences;
};

// 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;
};

// Provider routing preferences
type ProviderPreferences = {
  order?: string[];
  only?: string[];
  ignore?: string[];
  allow_fallbacks?: boolean;
  sort?:
    | "price"
    | "latency"
    | "throughput"
    | {
        by: string;
        partition?: string;
      };
  require_parameters?: boolean;
  data_collection?: "allow" | "deny";
  quantizations?: string[];
  max_price?: Record<string, 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": "chatcmpl-abc123",
  "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 只正規化兩個欄位 —— model,以及移除 provider 欄位 —— 其餘上游回應原樣轉發。像 native_finish_reason、system_fingerprint、reasoning 這類欄位只有在該上游供應商有填值時才會出現,不要預設每個模型都一定有。usage.cost 是例外 —— 永遠是 BazaarLink 自己結算/計費的金額,不是上游轉發過來的數值。

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

type NonStreamingChoice = {
  index: number;
  finish_reason: "stop" | "length" | "tool_calls" | "content_filter" | null;
  native_finish_reason: string | null;  // Provider's original finish reason
  message: {
    role: "assistant";
    content: string | null;
    tool_calls?: ToolCall[];
  };
};

type StreamingChoice = {
  index: number;
  finish_reason: string | null;
  native_finish_reason: string | null;  // Provider's original finish reason
  delta: {
    role?: string;
    content?: string | null;
    tool_calls?: ToolCall[];
  };
};

type ResponseUsage = {
  prompt_tokens: number;
  completion_tokens: number;
  total_tokens: number;
  cost: number;                      // Total cost for this request in USD
  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-edit);純生成模型是 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

Both endpoints emit the same event types:

event: heartbeat        # every 60 s, keeps Cloudflare happy
data: {}

event: image            # upstream URL, fastest path
data: {"index": 0, "url": "https://upstream/a.png"}

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,例如 alibaba/wan2.7-t2v
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": "alibaba/wan2.7-t2v",
    "prompt": "a bird flying over mountains",
    "duration": 3,
    "resolution": "720p",
    "generate_audio": false
  }'
# → 202 { "id": "vjob_xxx", "status": "pending" }
Note
Submit 時以最壞情況 × duration × multiplier 預扣;completed 時以上游回傳的 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
bytedance/seedance-2.0text+image+audio+video->videot2v, i2v
bytedance/seedance-2.0-fasttext+image+audio+video->videot2v, i2v
google/veo-3.1text+image->videot2v, i2v
openai/sora-2-protext+image->videot2v, i2v
bytedance/seedance-1-5-protext+image->videot2v, i2v
bytedance/seedance-2.5text+image+audio+video->video
alibaba/happyhorse-1.0text->videot2v
alibaba/wan2.6-r2vtext+image+video->videor2v
alibaba/wan2.6-r2v-flashtext+image+video->videor2v
alibaba/happyhorse-1.1text+image->videot2v, i2v
alibaba/wan2.6-i2v-flashtext+image->videoi2v
alibaba/wan2.5-i2v-previewtext+image->videoi2v
alibaba/wan2.7-i2vtext+image+video->videoi2v, kf2v, continuation
alibaba/wan2.6-t2vtext->videot2v
alibaba/wan2.5-t2v-previewtext->videot2v
alibaba/wan2.2-t2v-plustext->videot2v
alibaba/wan2.7-r2vtext+image+video->videor2v
alibaba/wan2.6-i2vtext+image->videoi2v
alibaba/wan2.7-videoedittext+image+video->videovideoedit
alibaba/wan2.2-i2v-flashtext+image->videoi2v
alibaba/wan2.1-t2v-plustext->videot2v
alibaba/wan2.1-t2v-turbotext->videot2v
alibaba/wan2.7-t2vtext->videot2v
alibaba/wan2.2-i2v-plustext+image->videoi2v

影片輸入

傳送影片檔案給支援影片輸入的模型,用來分析內容、生成說明或回答場景與事件相關問題。可用直接 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
模型 ID,例如 "openai/gpt-4o" 或 "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
取樣溫度 0–2。越高越隨機。預設:1
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 輸出。請參閱結構化輸出章節
models
string[]
備用模型清單——BazaarLink 依序嘗試,主模型失敗時自動切換
transforms
string[]
要套用的訊息轉換,例如 ["middle-out"]。省略則在 ≤8k context 模型自動套用
previous_response_id
string
本端點是無狀態的——傳入非 null 值會直接回 400(invalid_prompt),不是被接受後忽略。請改用無狀態模式:在 input 陣列中帶入完整對話歷史。
provider
object
進階路由偏好——大多數使用者不需要。

請求結構 (TypeScript)

type ResponsesRequest = {
  model: string;                    // "provider/model-name"
  input: string | InputItem[];      // string or multi-turn array

  // Optional
  instructions?: string;            // System-level message
  stream?: boolean;                 // Default: false
  max_output_tokens?: number;
  temperature?: number;             // Range: [0, 2], default: 0.7
  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
  provider?: ProviderPreferences;   // Same as Chat Completions
};

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?"
  }'

回應格式

// Non-streaming response object
type ResponsesResponse = {
  id: string;             // "resp_..."
  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;          // actual cost in credits
  } | 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 相容)

與 Anthropic Claude SDK 相容的 Messages API。使用方式和 Anthropic 官方 API 完全相同,只需更換 base URL 和 auth header。

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

請求內文

model必填
string
模型 ID,例如 "openai/gpt-4o" 或 "anthropic/claude-sonnet-4.6"
max_tokens必填
integer
生成的最大 token 數(正整數)。
messages必填
Message[]
對話訊息陣列(不可為空)。
system
string
選填的 system prompt。
stream
boolean
若為 true,返回 Server-Sent Events 串流。預設:false
temperature
number
取樣溫度 0–2。越高越隨機。預設:1
top_p
number
核取樣概率質量。預設:1
top_k
integer
限制候選 token 數量。0 表示停用(考慮全部)。預設:0
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",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}]
)
print(response.content[0].text)

回應

{
  "id": "msg_...",
  "type": "message",
  "role": "assistant",
  "model": "anthropic/claude-opus-4",
  "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,
    "bz_cost": 0.00042
  }
}

錯誤:400(驗證失敗)、402(額度不足)、429(rate limit)、502(上游錯誤或缺少金鑰)、503(伺服器重啟中)。

模型

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

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"
    }
  ]
}

可用模型 (238)

以下是目前 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-coder-flash1000K ctx · $0.20/$0.97text->text
qwen/qwen-plus1000K ctx · $0.26/$0.78text->text
qwen/qwen3-30b-a3b-instruct-2507262K ctx · $0.05/$0.19text->text
qwen/qwen3.5-flash-02-231000K ctx · $0.07/$0.26text+image+video->text
qwen/qwen3-embedding-8b33K ctx · $0.01/$0.00text->embeddings
qwen/qwen3.8-27b262K ctx · $0.45/$3.20text+image+video->text
qwen/qwen3-235b-a22b-2507262K ctx · $0.09/$0.55text->text
qwen/qwen3.6-27b262K ctx · $0.29/$2.40text+image+video->text
qwen/qwen3-8b131K ctx · $0.12/$0.46text->text
qwen/qwen3.8-2.4t-a95b1049K ctx · $2.00/$6.00text->text
qwen/qwen3-vl-30b-a3b-instruct262K ctx · $0.13/$0.52text+image->text
qwen/qwen3.5-plus-202604201000K ctx · $0.30/$1.80text+image+video->text
qwen/qwen3-next-80b-a3b-thinking262K ctx · $0.15/$1.20text->text
qwen/qwen3-32b131K ctx · $0.08/$0.28text->text
qwen/qwen3.5-plus-02-151000K ctx · $0.26/$1.56text+image+video->text
qwen/qwen3-max262K ctx · $0.78/$3.90text->text
qwen/qwen3-coder-30b-a3b-instruct262K ctx · $0.07/$0.28text->text
qwen/qwen3-vl-8b-instruct262K ctx · $0.12/$0.46text+image->text
qwen/qwen-2.5-7b-instruct33K ctx · $0.10/$0.20text->text
qwen/qwen3-30b-a3b-thinking-250782K ctx · $0.20/$2.40text->text
qwen/qwen3.5-27b262K ctx · $0.20/$1.56text+image+video->text
qwen/qwen3-vl-30b-a3b-thinking262K ctx · $0.20/$2.40text+image->text
qwen/qwen-2.5-coder-32b-instruct33K ctx · $0.66/$1.00text->text
qwen/qwen3.6-35b-a3b262K ctx · $0.15/$1.00text+image+video->text
qwen/qwen3-235b-a22b131K ctx · $0.46/$1.82text->text
qwen/qwen3.5-9b262K ctx · $0.10/$0.15text+image+video->text
qwen/qwen3.7-flash1000K ctx · $0.03/$0.13text+image+video->text
qwen/qwen-2.5-72b-instruct33K ctx · $0.36/$0.40text->text
qwen/qwen3.5-35b-a3b262K ctx · $0.23/$1.80text+image+video->text
qwen/qwen3-vl-235b-a22b-thinking131K ctx · $0.40/$4.00text+image->text
qwen/qwen3-30b-a3b131K ctx · $0.13/$0.52text->text
qwen/qwen3-max-thinking262K ctx · $0.78/$3.90text->text
qwen/qwen3.5-122b-a10b262K ctx · $0.29/$2.40text+image+video->text
qwen/qwen3-vl-32b-instruct131K ctx · $0.10/$0.42text+image->text
qwen/qwen3-vl-8b-thinking131K ctx · $0.18/$2.10text+image->text
qwen/qwen2.5-vl-72b-instruct128K ctx · $0.25/$0.75text+image->text
qwen/qwen3-coder262K ctx · $0.30/$1.00text->text
qwen/qwen3-235b-a22b-thinking-2507262K ctx · $0.23/$2.30text->text
qwen/qwen3-coder-next262K ctx · $0.12/$0.80text->text
qwen/qwen-image-3 · $0.00/$0.00text+image->image
qwen/qwen3-vl-235b-a22b-instruct262K ctx · $0.26/$1.04text+image->text
qwen/qwen-image-3-pro · $0.00/$0.00text+image->image
qwen/qwen3.6-plus1000K ctx · $0.33/$1.95text+image+video->text
qwen/qwen3-coder-plus1000K ctx · $0.65/$3.25text->text
qwen/qwen-plus-2025-07-281000K ctx · $0.26/$0.78text->text
qwen/qwen-plus-2025-07-28:thinking1000K ctx · $0.26/$0.78text->text
qwen/qwen3-14b131K ctx · $0.12/$0.24text->text
qwen/qwen3.5-397b-a17b262K ctx · $0.39/$2.34text+image+video->text
qwen/qwen3-embedding-4b33K ctx · $0.02/$0.00text->embeddings
qwen/qwen3-next-80b-a3b-instruct262K ctx · $0.10/$1.10text->text
qwen/qwen-image-edittext+image->image
qwen/qwen-image-edit-plustext+image->image
qwen/qwen-image-2.0text->image
qwen/qwen-image-maxtext->image
qwen/qwen-image-plustext->image
qwen/qwen-image-edit-maxtext+image->image
qwen/qwen-image-2.0-protext->image
qwen/qwen-imagetext->image
OpenAI
openai/gpt-5.3-codex400K ctx · $1.75/$14.00text+image+file->text
openai/gpt-5.4-nano400K ctx · $0.20/$1.25text+image+file->text
openai/text-embedding-ada-0028K ctx · $0.10/$0.00text->embeddings
openai/gpt-5.6-luna1050K ctx · $0.20/$1.20text+image+file->text
openai/gpt-5.6-terra-pro1050K ctx · $2.00/$12.00text+image+file->text
openai/gpt-5.41050K ctx · $2.50/$15.00text+image+file->text
openai/text-embedding-3-small8K ctx · $0.02/$0.00text->embeddings
openai/gpt-5.6-luna-pro1050K ctx · $0.20/$1.20text+image+file->text
openai/o3200K ctx · $2.00/$8.00text+image+file->text
openai/gpt-5.4-mini400K ctx · $0.75/$4.50text+image+file->text
openai/gpt-5.1400K ctx · $1.25/$10.00text+image+file->text
openai/o4-mini-high200K ctx · $1.10/$4.40text+image+file->text
openai/o3-mini200K ctx · $1.10/$4.40text+file->text
openai/text-embedding-3-large8K ctx · $0.13/$0.00text->embeddings
openai/o1200K ctx · $15.00/$60.00text+image+file->text
openai/o1-pro200K ctx · $150.00/$600.00text+image+file->text
openai/gpt-5400K ctx · $1.25/$10.00text+image+file->text
openai/o3-pro200K ctx · $20.00/$80.00text+image+file->text
openai/o4-mini200K ctx · $1.10/$4.40text+image+file->text
openai/gpt-5-nano400K ctx · $0.05/$0.40text+image+file->text
openai/o3-mini-high200K ctx · $1.10/$4.40text+file->text
openai/gpt-5.4-pro1050K ctx · $30.00/$180.00text+image+file->text
openai/sora-2-pro · $0.00/$0.00text+image->video
openai/gpt-4o-2024-11-20128K ctx · $2.50/$10.00text+image+file->text
openai/gpt-5.4-image-2272K ctx · $8.00/$15.00text+image+file->text+image
openai/gpt-4o128K ctx · $2.50/$10.00text+image+file->text
openai/gpt-5.6-sol1050K ctx · $5.00/$30.00text+image+file->text
openai/gpt-oss-20b131K ctx · $0.03/$0.13text->text
openai/gpt-oss-safeguard-20b131K ctx · $0.07/$0.30text->text
openai/gpt-4o-2024-08-06128K ctx · $2.50/$10.00text+image+file->text
openai/gpt-3.5-turbo16K ctx · $0.50/$1.50text->text
openai/gpt-5.51050K ctx · $5.00/$30.00text+image+file->text
openai/gpt-5.6-sol-pro1050K ctx · $5.00/$30.00text+image+file->text
openai/gpt-oss-120b131K ctx · $0.15/$0.60text->text
openai/gpt-5.6-terra1050K ctx · $2.00/$12.00text+image+file->text
openai/gpt-5-mini400K ctx · $0.25/$2.00text+image+file->text
openai/gpt-image-1400K ctx · $10.00/$10.00text+image->image
openai/gpt-image-1-mini400K ctx · $2.50/$2.50text+image->image
Alibaba
alibaba/wan2.2-t2i-plustext->image
alibaba/happyhorse-1.0 · $0.00/$0.00text->video
alibaba/wan2.6-r2v · $0.00/$0.00text+image+video->video
alibaba/wan2.6-r2v-flash · $0.00/$0.00text+image+video->video
alibaba/happyhorse-1.1 · $0.00/$0.00text+image->video
alibaba/wan2.6-i2v-flash · $0.00/$0.00text+image->video
alibaba/wan2.5-i2v-preview · $0.00/$0.00text+image->video
alibaba/wan2.7-i2v · $0.00/$0.00text+image+video->video
alibaba/wan2.6-t2v · $0.00/$0.00text->video
alibaba/wan2.5-t2v-preview · $0.00/$0.00text->video
alibaba/wan2.2-t2v-plus · $0.00/$0.00text->video
alibaba/wan2.7-r2v · $0.00/$0.00text+image+video->video
alibaba/wan2.6-i2v · $0.00/$0.00text+image->video
alibaba/wan2.6-t2itext->image
alibaba/wan2.5-i2i-previewtext+image->image
alibaba/wan2.2-t2i-flashtext->image
alibaba/wan2.7-videoedit · $0.00/$0.00text+image+video->video
alibaba/wan2.7-image-protext->image
alibaba/wan2.7-imagetext->image
alibaba/wan2.6-imagetext->image
alibaba/wan2.2-i2v-flash · $0.00/$0.00text+image->video
alibaba/wan2.1-t2v-plus · $0.00/$0.00text->video
alibaba/wan2.1-t2v-turbo · $0.00/$0.00text->video
alibaba/wan2.7-t2v · $0.00/$0.00text->video
alibaba/wan2.1-t2i-plustext->image
alibaba/wan2.5-t2i-previewtext->image
alibaba/wan2.1-t2i-turbotext->image
alibaba/wan2.2-i2v-plus · $0.00/$0.00text+image->video
alibaba/z-image-turbotext->image
Google
google/gemini-2.5-flash-lite1049K ctx · $0.10/$0.40text+image+file+audio+video->text
google/gemini-3.1-pro-preview1049K ctx · $2.00/$12.00text+image+file+audio+video->text
google/gemini-3.1-flash-lite-preview1049K ctx · $0.25/$1.50text+image+file+audio+video->text
google/gemma-4-31b-it262K ctx · $0.10/$0.34text+image+video->text
google/gemma-4-26b-a4b-it262K ctx · $0.12/$0.40text+image+video->text
google/gemini-embedding-2-preview8K ctx · $0.20/$0.00text+image+file+audio+video->embeddings
google/gemma-3-4b-it131K ctx · $0.05/$0.10text+image->text
google/gemma-3n-e4b-it33K ctx · $0.06/$0.12text->text
google/gemini-3.5-flash-lite1049K ctx · $0.30/$2.50text+image+file+audio+video->text
google/gemini-3.6-flash1049K ctx · $1.50/$7.50text+image+file+audio+video->text
google/gemma-3-12b-it131K ctx · $0.05/$0.15text+image->text
google/gemini-3.1-flash-image131K ctx · $0.50/$3.00text+image->text+image
google/gemini-3-flash-preview1049K ctx · $0.50/$3.00text+image+file+audio+video->text
google/gemini-2.5-pro-preview1049K ctx · $1.25/$10.00text+image+file+audio->text
google/gemini-2.5-flash1049K ctx · $0.30/$2.50text+image+file+audio+video->text
google/gemma-2-27b-it8K ctx · $0.65/$0.65text->text
google/gemini-3.5-flash1049K ctx · $1.50/$9.00text+image+file+audio+video->text
google/gemini-2.5-flash-image33K ctx · $0.30/$2.50text+image->text+image
google/gemma-3-27b-it262K ctx · $0.08/$0.45text+image->text
google/veo-3.1 · $0.00/$0.00text+image->video
google/gemini-3-pro-image131K ctx · $2.00/$12.00text+image->text+image
google/gemini-3.1-pro-preview-customtools1049K ctx · $2.00/$12.00text+image+file+audio+video->text
google/gemini-embedding-00120K ctx · $0.15/$0.00text->embeddings
google/gemini-2.5-pro-preview-05-061049K ctx · $1.25/$10.00text+image+file+audio+video->text
google/gemini-2.5-pro1049K ctx · $1.25/$10.00text+image+file+audio+video->text
google/gemini-3.1-flash-image-preview131K ctx · $0.50/$3.00text+image->text+image
Anthropic
anthropic/claude-opus-4.61000K ctx · $5.00/$25.00text+image+file->text
anthropic/claude-sonnet-4.61000K ctx · $3.00/$15.00text+image+file->text
anthropic/claude-sonnet-41000K ctx · $3.00/$15.00text+image+file->text
anthropic/claude-sonnet-51000K ctx · $2.00/$10.00text+image+file->text
anthropic/claude-sonnet-4.51000K ctx · $3.00/$15.00text+image+file->text
anthropic/claude-haiku-4.5200K ctx · $1.00/$5.00text+image+file->text
anthropic/claude-3-haiku200K ctx · $0.25/$1.25text+image->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-fable-51000K ctx · $10.00/$50.00text+image+file->text
anthropic/claude-opus-4.1200K ctx · $15.00/$75.00text+image+file->text
anthropic/claude-opus-4200K ctx · $15.00/$75.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
DeepSeek
deepseek/deepseek-v4-pro1049K ctx · $2.40/$4.80text->text
deepseek/deepseek-v3.2164K ctx · $0.28/$0.42text->text
deepseek/deepseek-v4-flash1049K ctx · $0.20/$0.40text->text
deepseek/deepseek-chat-v3-0324164K ctx · $0.27/$1.12text->text
deepseek/deepseek-r1-0528164K ctx · $0.50/$2.15text->text
deepseek/deepseek-v3.2-exp164K ctx · $0.27/$0.41text->text
deepseek/deepseek-v4-flash-07311049K ctx · $0.14/$0.28text->text
deepseek/deepseek-r1-distill-llama-70b8K ctx · $0.80/$0.80text->text
deepseek/deepseek-v3.1-terminus164K ctx · $0.27/$0.95text->text
deepseek/deepseek-chat-v3.1164K ctx · $0.25/$0.95text->text
deepseek/deepseek-chat164K ctx · $0.40/$1.30text->text
deepseek/deepseek-r164K ctx · $0.70/$2.50text->text
deepseek/deepseek-v4-pro-08131049K ctx · $2.40/$4.80text->text
Zhipu AI
z-ai/glm-4.7205K ctx · $0.40/$1.75text->text
z-ai/glm-5.21049K ctx · $1.40/$4.40text->text
z-ai/glm-5.1205K ctx · $1.40/$4.40text->text
z-ai/glm-5205K ctx · $1.00/$3.20text->text
z-ai/glm-5v-turbo203K ctx · $1.20/$4.00text+image+video->text
z-ai/glm-5-turbo203K ctx · $1.20/$4.00text->text
z-ai/glm-4.7-flash203K 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.6205K ctx · $0.55/$2.20text->text
z-ai/glm-4.5131K ctx · $0.60/$2.20text->text
Moonshot AI
moonshotai/kimi-k31049K ctx · $3.00/$15.00text+image+video->text
moonshotai/kimi-k2.5262K ctx · $0.60/$3.00text+image->text
moonshotai/kimi-k2.6262K ctx · $0.86/$3.57text+image->text
moonshotai/kimi-k2.7-code262K ctx · $0.95/$4.00text+image->text
moonshotai/kimi-k2-thinking262K ctx · $0.60/$2.50text->text
moonshotai/kimi-k2131K ctx · $0.57/$2.30text->text
moonshotai/kimi-k2-0905262K ctx · $0.60/$2.50text->text
xAI
x-ai/grok-4.31000K ctx · $1.25/$2.50text+image+file->text
x-ai/grok-4.20-multi-agent2000K ctx · $1.25/$2.50text+image+file->text
x-ai/grok-4.202000K ctx · $1.25/$2.50text+image+file->text
x-ai/grok-build-0.1256K ctx · $1.00/$2.00text+image+file->text
x-ai/grok-4.5500K ctx · $2.00/$6.00text+image+file->text
x-ai/grok-imagine-image-2.0 · $0.00/$0.00text+image->image
x-ai/grok-4.6500K ctx · $2.00/$6.00text+image+file->text
Perplexity
perplexity/sonar-pro-search200K ctx · $3.00/$15.00text+image->text
perplexity/sonar-pro200K ctx · $3.00/$15.00text+image->text
perplexity/sonar-deep-research128K ctx · $2.00/$8.00text->text
perplexity/sonar-reasoning-pro128K ctx · $2.00/$8.00text+image->text
perplexity/sonar127K ctx · $1.00/$1.00text+image->text
MiniMax
minimax/minimax-m2.5205K ctx · $0.30/$1.20text->text
minimax/minimax-m31049K ctx · $0.30/$1.20text+image+video->text
minimax/minimax-m2.7205K ctx · $0.30/$1.20text->text
minimax/minimax-m2.1205K ctx · $0.30/$1.20text->text
bytedance-seed
bytedance-seed/seed-1.6262K ctx · $0.25/$2.00text+image+video->text
bytedance-seed/seed-2.0-mini262K ctx · $0.10/$0.40text+image+video->text
bytedance-seed/seed-2.0-lite262K ctx · $0.25/$2.00text+image+video->text
bytedance-seed/seed-1.6-flash262K ctx · $0.07/$0.30text+image+video->text
Nous
nousresearch/hermes-4-405b131K ctx · $1.00/$3.00text->text
nousresearch/hermes-3-llama-3.1-70b131K ctx · $0.70/$0.70text->text
nousresearch/hermes-4-70b131K ctx · $0.13/$0.40text->text
nousresearch/hermes-3-llama-3.1-405b131K ctx · $1.00/$1.00text->text
ByteDance
bytedance/seedance-2.0 · $0.00/$0.00text+image+audio+video->video
bytedance/seedance-2.0-fast · $0.00/$0.00text+image+audio+video->video
bytedance/seedance-1-5-pro · $0.00/$0.00text+image->video
bytedance/seedance-2.5 · $0.00/$0.00text+image+audio+video->video
Mistral
mistralai/mixtral-8x22b-instruct66K ctx · $2.00/$6.00text+file->text
mistralai/mistral-large128K ctx · $2.00/$6.00text+file->text
mistralai/ministral-3b-2512131K ctx · $0.10/$0.10text+image->text
NVIDIA
nvidia/nemotron-3-super-120b-a12b1000K ctx · $0.30/$0.90text->text
nvidia/nemotron-3-nano-30b-a3b262K ctx · $0.05/$0.20text->text
xiaomi
xiaomi/mimo-v2.51050K ctx · $0.14/$0.28text+image+audio+video->text
xiaomi/mimo-v2.5-pro1050K ctx · $0.43/$0.87text->text
ibm-granite
ibm-granite/granite-4.0-h-micro131K ctx · $0.02/$0.11text->text
Meta
meta-llama/llama-3.2-1b-instruct60K ctx · $0.03/$0.20text->text
Tongyi-MAI
Tongyi-MAI/Z-Image-Turbotext->image

模型頁面瀏覽所有模型。

串流

設定 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":"chatcmpl-abc","choices":[{"delta":{"content":"Hello"},"index":0}]}

data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":" world"},"index":0}]}

data: {"id":"chatcmpl-abc","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 註解列(以冒號開頭)或心跳事件作為 keep-alive — 解析時請略過非 data: 列,不要直接對整列做 JSON.parse。最後一個 data chunk 會帶 usage(token 用量與成本),之後才是 data: [DONE]。成功的回應會含 X-Request-Id header,回報問題時請附上。

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

data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"Hi"},"index":0}]}

data: {"id":"chatcmpl-abc","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":"chatcmpl-abc","choices":[{"delta":{"content":"The capital of "},"index":0}]}

data: {"error":{"message":"Upstream connection lost.","type":"upstream_error","code":502}}

data: [DONE]

嵌入向量

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

什麼是嵌入向量?

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

常見應用場景

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

參數

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
供應商路由偏好設定 —— order、allow_fallbacks、data_collection,以及 Provider Selection 說明的其他欄位。

基本請求

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)}")

供應商路由

跟 chat completions 一樣,可以控制由哪個上游服務嵌入請求 —— 完整欄位說明請見 Provider Selection。

{
  "model": "openai/text-embedding-3-small",
  "input": "Your text here",
  "provider": {
    "order": ["openai"],
    "allow_fallbacks": true,
    "data_collection": "deny"
  }
}

尋找嵌入模型

沒有專屬的嵌入模型清單端點 —— 呼叫 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;不支援的參數會被静默忽略。

取樣參數

純轉發——沒有本地預設值
這些參數會原封不動轉發給上游 provider——BazaarLink 不會注入或強制任何預設值。下方的「預設」是指該欄位省略時 provider 自己的行為,不是 BazaarLink 的保證。
temperature
number
取樣溫度 0–2。越高越隨機。預設:1
top_p
number
核取樣概率質量。預設:1
top_k
integer
限制候選 token 數量。0 表示停用(考慮全部)。預設:0
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 系列模型 —— 見下方說明。

BazaarLink 專屬參數

transforms
string[]
要套用的訊息轉換,例如 ["middle-out"]。省略則在 ≤8k context 模型自動套用
models
string[]
備用模型清單——BazaarLink 依序嘗試,主模型失敗時自動切換
route
string
進階路由相容欄位——大多數使用者不需要。要用 fallback 請用 "models"。
provider
object
進階路由偏好——大多數使用者不需要。

信用額度

查詢當前信用額度餘額與累積 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(帳號已停權)。

生成詳細資料

依 generation ID 查詢單次完成請求的詳細統計資料(ID 來自 chat/completions 回應的 id,或串流的 x-bz-gen-id header)。

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

範例請求

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

回應

{
  "data": {
    "id": "gen_xyz...",
    "model": "openai/gpt-4o",
    "provider": "openai",
    "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(找不到使用者,極少發生)。

Agent 自助註冊

供 AI agent(機器人、自主系統)自行註冊,回傳含試用額度的 API key 與用於升級的 claim token。

POST/v1/agents/register
Rate Limit
免驗證,但每個 IP 每 24 小時限 1 次請求。

請求內文

name必填
string
Agent 名稱(非空、trim 後長度上限 100)。
description
string
選填的 agent 說明。
referral_code
string
選填的推薦碼。

範例請求

curl -X POST https://api.bazaarlink.ai/v1/agents/register \
  -H "content-type: application/json" \
  -d '{
    "name": "My Agent",
    "description": "Autonomous research bot"
  }'

回應

{
  "api_key": "sk-bl-xxxxx...",
  "credits": 0.10,
  "credits_usd": "$0.1000",
  "claim_token": "abc...xyz",
  "claim_expires": "2026-04-27T10:00:00.000Z",
  "upgrade_url": "https://bazaarlink.ai/claim?token=...",
  "referral_code": "aBcDeFgH",
  "free_model": "auto:free",
  "message": "Welcome to BazaarLink!...",
  "referral_message": "Share referral link:...",
  "base_url": "https://api.bazaarlink.ai/v1",
  "docs": "https://bazaarlink.ai/llms.txt"
}

錯誤:400(body 無效或缺少 name)、429(rate limit,1/IP/24h)、500(內部錯誤)。

錯誤代碼

錯誤回應格式

模型推論端點會回傳 OpenAI 相容的錯誤 envelope。部分特殊端點可能省略 type,或依錯誤路徑使用不同值;程式判斷請使用 HTTP 狀態與 error.code,不要解析 message 文字。

{
  "error": {
    "message": "Insufficient credits. Please top up to continue.",
    "type": "invalid_request_error",
    "code": "insufficient_credits"
  }
}

HTTP 狀態與 error.code

串流開始前,HTTP 狀態代表錯誤大類;error.code 則可能是相同的數字,或代表特定處置方式的穩定字串。若有字串代碼應優先判斷,否則使用 HTTP 狀態;error.message 僅供人閱讀。

代碼
名稱
說明
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,也可能代表不同的帳務控制。請依下列穩定代碼顯示正確的處理方式。

代碼
說明
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

內容審查

所有請求在送往模型端之前,都會先經過自動化內容審查。不符合使用規範的請求會被拒絕,不會送達模型,並回傳 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數字 code 429;依 Retry-After 與 X-RateLimit-* 標頭處理。
限流懲罰封鎖429數字 code 429、暫時限制訊息及 Retry-After。
全域支出緊急煞車503數字 code 503、全域支出上限訊息,以及 30 或 300 秒的 Retry-After。
組織/團隊/成員/使用者支出煞車429數字 code 429,訊息會指出 spend circuit breaker 及受影響範圍。
帳務與預算控制402使用上方列出的穩定帳務字串代碼。

相容性提醒:速率限制與緊急煞車目前回傳數字型 error.code。請勿假設尚未實作的字串代碼;請依 HTTP 狀態、Retry-After 與文件所述訊息判斷。

影片與媒體資源狀態

影片驗證通常回傳數字 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 會送出最後一個 SSE 事件,內容為頂層 error 物件,接著是 data: [DONE]。部分上游原樣轉發的 chunk 則可能把錯誤放在 choice 上(choices[0].finish_reason === "error")— 兩種都要處理。

// If the stream fails mid-flight, BazaarLink emits a final SSE event
// with a top-level "error" object, followed by data: [DONE]
data: {"error":{"message":"Upstream stream interrupted. The response is incomplete.","type":"upstream_error","code":502}}

data: [DONE]

// Chunks relayed verbatim from some upstreams may instead carry the error
// inline on the choice: choices[0].finish_reason === "error" with an
// "error" object ({ code, message }) on the choice — handle both shapes.
// 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。

客服
客服
您好!有什麼可以協助?
請留下訊息,我們會盡快回覆。
API 參考文件|聊天、嵌入與模型路由