BazaarLinkBazaarLink
ログイン
ドキュメントAPIリファレンスSDKリファレンスエージェント利用AIスキル

BazaarLinkドキュメント

BazaarLinkは台湾の統合AI APIゲートウェイです — 単一のOpenAI互換APIエンドポイントを通じて、OpenAI、Anthropic、Google、Metaなどの数百のモデルにアクセスできます。

AIエージェントスキルファイル
AIアシスタント(Claude、Cursor、Copilotなど)にスキルファイルを読み込ませると、BazaarLink APIの完全な知識を得られます:
Read https://bazaarlink.ai/skill.md and follow the instructions to integrate BazaarLink into your app.
無料モデルとレート制限
無料モデル、毎分リクエスト上限、無料クレジットについては次をご覧ください: レート制限 · よくある質問

料金体系

BazaarLink はモデル利用量をゼロ加算で提供します(各プロバイダーの公式定価と同一)。プラットフォーム手数料はチャージ(入金)時に徴収されます:10% の取引手数料、台湾ドル決済ではさらに 5% の台湾営業税。米ドル建てで記帳し、台湾ドル見積りと電子統一発票を提供します。セルフサービスの従量課金チャージに対応し、企業は月次請求(Net-30、応相談)も手配できます。

仕組み

  • 消費(引き落とし):各 API コールは実際のトークン使用量に基づき、プロバイダーの公式米ドル定価で残高から差し引かれます。ゼロ加算で、消費時に追加費用はかかりません。
  • チャージ(入金):台湾ドルはリアルタイム売りレートで米ドルに換算され残高に加算されます。チャージ時に 10% の取引手数料が徴収されます。
  • • クレジットカード:別途 US$0.60 の定額手数料がかかり、領収書が発行されます。
  • • 台湾ドル決済:5% の台湾営業税が加算され、台湾の電子統一発票が発行されます。
  • • 銀行電信送金:大口・法人のチャージについては、お問い合わせのうえ送金と個別請求書の手配をいたします。
  • 発票:電子統一発票に対応し、台湾の経費精算フローに適合します。調達手続きや月次請求が必要な企業は、企業向け条件(Net-30、応相談)を手配できます。
US$10.00 をチャージする場合:台湾ドル決済 = $10.00 + 10% 取引手数料 US$1.00 + 5% 営業税 US$0.55 = US$11.55(統一発票を発行);クレジットカード = $10.00 + 取引手数料 US$1.00 + 定額手数料 US$0.60 = US$11.60。チャージ後、US$10.00 の残高は公式定価で消費され、以降の加算はありません。

為替レートについて

Foreign-exchange conversion uses the real-time rate; monthly billing uses the rate at billing (statement) time, while prepaid top-ups convert at the top-up-time rate. The rate and timestamp are retained with billing records.

失敗したリクエストの課金保護

アップストリームのリクエストが失敗し、精算可能な使用量データがない場合、BazaarLink は予約額を全額自動返金します。ストリーム開始後に中断した場合でも、その試行の請求額は 0 ドルです。

請求されない場合
設定は不要です。公開推論 API とメディア API に自動適用されます。アップストリームから BazaarLink に費用が請求されても、失敗分をお客様へ転嫁せず BazaarLink が負担する場合があります。
  • アップストリームに接続できない、リクエストが拒否される、または利用可能な結果が返らない場合
  • 一部の内容が返った後でも、最終使用量データを受け取る前にストリームが中断した場合
  • usage がない、またはすべて 0 の空の usage オブジェクトだけが返った場合

出力トークンが 0 でも必ず無料とは限りません

リクエストが正常に完了し、プロバイダーが有効な usage を返した場合、BazaarLink はその使用量を精算します。出力トークンだけで無料かどうかを判断しないでください。出力トークンが 0 でも、入力トークンまたは有効なアップストリーム報告コストがあれば課金されることがあります。最終請求額は usage.cost またはアクティビティ記録で確認してください。

クイックスタート

3つの統合方法

アプローチ
適した用途
スタート
Raw API任意の言語、依存関係ゼロ、リクエストを完全制御
OpenAI / Anthropic SDKすでに公式SDKを使用中 — ベースURLとキーを差し替えるだけ
エージェントフレームワークLangChain、Vercel AI SDK、CrewAIなどのエージェントアプリ

5分以内に始められます。BazaarLinkはOpenAI SDKと完全互換です —

ベースURL

https://bazaarlink.ai/api/v1

OpenAI SDKの使用

BazaarLinkはOpenAI SDKと完全互換です。ベースURLとAPIキーを変更するだけで、他のコードはそのままです。

from openai import OpenAI

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

completion = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[
        {"role": "user", "content": "What is the meaning of life?"}
    ],
)

print(completion.choices[0].message.content)
APIキーが必要ですか?
APIキーは APIキーページから取得できます。すべてのキーは sk-bl-.
モデルID形式 — provider/model-name 形式を推奨
常に完全な provider/model 形式を使用してください(例:openai/gpt-4.1)。よく使われるファミリー(gpt-*、claude-*)はすべてのエンドポイントで自動的にプレフィックスが補われ、chat/completions はさらにカタログから曖昧さのないベアネームを完全なIDに解決します — ただし解決できない名前は400エラーを返すため、完全な形式だけが唯一保証された書き方です。
✓ openai/gpt-4o   anthropic/claude-sonnet-4.6   google/gemini-2.5-flash
✗ gpt-4.1   claude-sonnet-4.6   gemini-2.5-flash

上流キーの持ち込み(BYOK)

ご自身の上流プロバイダーAPIキー(OpenAIまたはAnthropic互換インターフェース)を個人アカウントや組織に紐付けると、対象リクエストはあなたのキーで上流に直接接続されます。シームレス(seamless)と厳格(strict)の2つのフォールバックモードを選択可能。個人はキーページのBYOKタブで、組織は組織設定で一元管理します。 BYOK設定へ →

コンテンツフィルタリング

APIトラフィックの双方向コンテンツ保護:プロンプトインジェクションを含むリクエストはブロック(400)され、リクエスト・レスポンス内の機密データ(APIキー、カード番号、身分証番号など)は自動的にマスクされます。ルールと除外リストはカスタマイズ可能で、使用統計も確認できます。 コンテンツフィルター設定へ →

OpenRouterからの移行

BazaarLinkのAPIはOpenRouter互換です — ほとんどの統合は2つの値を変更するだけで切り替えられます:ベースURLを https://bazaarlink.ai/api/v1 に、APIキーを sk-bl- で始まるBazaarLinkキーに変更します。

  1. ベースURL:https://openrouter.ai/api/v1 → https://bazaarlink.ai/api/v1
  2. APIキー:sk-or-... → sk-bl-...(/keys で作成)
  3. モデルID:同じ provider/model 形式(例:anthropic/claude-sonnet-4.6);全カタログは GET /api/v1/models で取得
  4. models[] フォールバック、プロバイダールーティング設定、ストリーミング、ツールコール、構造化出力は同じリクエスト形式を使用します
  from openai import OpenAI

  client = OpenAI(
-     base_url="https://openrouter.ai/api/v1",
-     api_key="sk-or-...",
+     base_url="https://bazaarlink.ai/api/v1",
+     api_key="sk-bl-...",
  )
Note
請求は米ドル建てで、台湾の電子発票にも対応しています。OpenRouter固有の機能(例::nitro プロバイダーソート)については、APIリファレンスページのモデルバリアントとプロバイダー選択のセクションで同等の動作を確認してください。

認証

すべてのAPIリクエストには、APIキーを含むAuthorizationヘッダーが必要です。

Authorization: Bearer sk-bl-YOUR_API_KEY

APIキーは ダッシュボードから取得できます。キーを安全に保管し、クライアントサイドのコードに公開しないでください。

セキュリティに関する注意
クライアントサイドのJavaScriptでAPIキーを公開しないでください。常にバックエンドサーバーを経由してリクエストをプロキシしてください。

オプションヘッダー

HTTP-Referer
string
サイトURL、使用状況の追跡と分析用(任意)
X-Title
string
アプリ名、ダッシュボードに表示(任意)

設計原則

BazaarLinkは3つのコア原則に基づいて設計されています:

1. 統一インターフェース

1つのAPI、1つのSDK、数百のモデル。OpenAI、Anthropic、Google Gemini、Meta Llamaなどをコード変更なしで切り替え — モデルIDを変更するだけ。

2. 価格最適化

BazaarLinkは選択したモデルに対して最もコスト効率の良いプロバイダーに自動ルーティング。使った分だけ支払い、米ドルで請求、完全な発票サポート。

3. 高可用性

自動フェイルオーバーにより、プロバイダーがダウンしてもリクエストはシームレスに再ルーティング。コード変更もダウンタイムもなし。

マルチモーダル

BazaarLinkはマルチモーダル入力をサポート — 対応モデルにテキストとともに画像、音声、ファイルを送信できます。コンテンツはアップストリームプロバイダーにそのまま転送されます。

対応モダリティ

入力
説明
対応モデル例
テキスト標準テキストメッセージ全モデル
画像URLまたはbase64データURI — PNG、JPEG、WebP、GIFopenai/gpt-5.3-codexanthropic/claude-opus-4.6google/gemini-2.5-flash-lite他 142 件
ファイル / PDFbase64データURI経由のドキュメント(`data:application/pdf;base64,...`)openai/gpt-5.3-codexanthropic/claude-opus-4.6google/gemini-2.5-flash-lite他 70 件
音声生のbase64 — URLはサポートなし。`format`フィールドが必要google/gemini-2.5-flash-litexiaomi/mimo-v2.5google/gemini-3.1-pro-preview他 13 件
動画URL(CDN)またはbase64データURIgoogle/gemini-2.5-flash-liteqwen/qwen3.5-plus-02-15minimax/minimax-m3他 37 件

例:

# Image — URL or base64 data URI
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"text","text":"What is in this?"},
        {"type":"image_url","image_url":{"url":"https://example.com/photo.jpg"}}
      ]}]}'

# File / PDF — base64 data URI only, no URL
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"file","file":{"filename":"doc.pdf","file_data":"data:application/pdf;base64,JVBER..."}},
        {"type":"text","text":"Summarize this."}
      ]}]}'

# Audio — raw base64, no URL. "format" is required
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"text","text":"Transcribe this."},
        {"type":"input_audio","input_audio":{"data":"UklGRi...","format":"wav"}}
      ]}]}'

# Video — URL (CDN) or base64 data URI
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":[
        {"type":"text","text":"Describe this video."},
        {"type":"video_url","video_url":{"url":"https://example.com/clip.mp4"}}
      ]}]}'

画像の送信

image_urlパーツを含むコンテンツ配列形式を使用します。対応フォーマット:PNG、JPEG、WebP、GIF(アニメーション含む)。1つのメッセージに複数の画像を含めることができます — それぞれ別のimage_urlパーツとして:

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer sk-bl-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [{"role":"user","content":[
      {"type":"text","text":"What is in this image?"},
      {"type":"image_url","image_url":{"url":"https://example.com/photo.jpg","detail":"auto"}}
    ]}]
  }'
画像の送信
常に画像とともにテキストパーツを含めてください。すべてのプロバイダーとの最善の互換性のために、テキストファースト順序(テキストパーツを画像パーツの前に)が推奨されます。
画像の送信
各モデルの対応入力モダリティはモデルページで確認してください。modalityカラムで各モデルが受け付ける入力が表示されます。

制限

BazaarLinkには2種類の独立した制限があります。リクエスト頻度によるレート制限と、アカウントの支出によるクレジット制限です。レート制限を超えるとHTTP 429、クレジットが尽きるとHTTP 402が返されます。

レート制限

レート制限はユーザーごと(キーごとではない)で、1分あたりのリクエスト数(RPM)で測定されます。日次上限はありません。ティアはアカウントのクレジット残高によって自動決定されます。

ティア
RPM
日次使用量
備考
無料(クレジット $5未満)20 RPM無制限開発&テスト
有料(クレジット $5以上)200 RPM無制限本番ワークロード

レート制限を超過すると、Retry-Afterヘッダー付きの429レスポンスが返されます。リトライ時にはエクスポネンシャルバックオフを実装してください。

レスポンスヘッダー

成功レスポンスにはクライアント側追跡用のレート制限ヘッダーが必ず含まれる:

X-RateLimit-Limit: 200        # Max requests per minute for your tier
X-RateLimit-Remaining: 198    # Remaining requests in current window
X-RateLimit-Reset: 1740000060 # Unix timestamp when the window resets
X-Request-Id: chatcmpl-abc123 # Unique request ID for debugging

クレジット制限

402レスポンスは、アカウント残高またはキーの支出上限が0に達したことを意味し、リクエストが速すぎるという意味ではありません。このレスポンスにはレート制限ヘッダーが含まれず、ストリーミング中に制限に達した場合はHTTPステータスの変化ではなくSSEエラーイベントとして返されます。

402 Insufficient Credits
残高が $0 に達すると、API は HTTP 402 を返し、メッセージ "Insufficient credits. Please top up to continue." が含まれる。リアルタイムで支出を追跡するにはレスポンスの usage.cost を監視すること。

個人サーキットブレーカー

すべてのAPIキーに適用される、1分間・1時間の固定USD支出上限です。ウィンドウの閾値に達すると新規リクエストはHTTP 429を受け取り、時刻境界でウィンドウが自動リセットされます。

cbEnabled
boolean
有効
cbMinuteUsd
number | null
1分あたりのUSD上限 · デフォルトを使用
cbHourlyUsd
number | null
1時間あたりのUSD上限 · デフォルトを使用
(デフォルト継承中)
0.01 以上の値を入力してください(空欄でデフォルト)
個人サーキットブレーカー · 調整

画像生成

modalities:["image"] を付けた /v1/chat/completions、または OpenAI DALL·E 互換の /v1/images/generations で画像を生成します。

curl -N https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"openai/gpt-5.4-image-2","messages":[{"role":"user","content":"a red cat on a sofa"}],"modalities":["image","text"],"stream":true}'

完全なフロー(ストリーミング、画像編集、SSE プロトコル、モデル一覧)は API リファレンスへ →

動画生成

非同期の3ステップフロー(submit → poll → content)。動画生成には30秒〜5分かかります。

curl https://bazaarlink.ai/api/v1/videos \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"alibaba/wan2.7-t2v","prompt":"a bird flying over mountains","duration":3}'
# → 202 { "id": "vjob_xxx", "status": "pending" }

完全なフロー(ポーリング、ダウンロード、タスクタイプ、注意事項)は API リファレンスへ →

PDF入力

PDFをネイティブサポートするモデル(Claude、Geminiなど)に、メッセージで直接PDF文書を送信できます。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."},
        ],
    }],
)

動画入力

動画入力に対応するモデルに動画ファイルを送信し、分析、キャプション生成、シーンやイベントに関する質問への回答をさせます。直接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リファレンス →

管理APIキー

管理キーはプログラマティックなキー管理用に設計されています。標準APIキーの作成、一覧表示、更新、無効化、削除ができますが、AIモデルの呼び出しはできません。

注意
管理キーではAIモデル(chat/completions/messages/embeddings)を呼び出せません。モデルアクセスには標準APIキーを使用してください。

管理キーの作成

Management API Keys ページに移動し、「Create」をクリックしてください — 通常の API Keys ページ内のタイプ選択ではなく、専用の別ページです。

キー一覧

GET https://bazaarlink.ai/api/v1/keys
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Response
{
  "keys": [
    {
      "id": "clxyz123...",
      "name": "Production Key",
      "keyType": "standard",
      "keyPrefix": "sk-bl-abc1",
      "keySuffix": "XyZ9",
      "enabled": true,
      "spendLimitUsd": 10.00,
      "spendLimitPeriod": "month",
      "expiresAt": null,
      "createdAt": "2026-01-01T00:00:00.000Z",
      "lastUsed": "2026-03-01T12:34:56.000Z",
      "requestCount": 1234,
      "totalTokens": 5678901
    }
  ]
}

サブキーの作成

POST https://bazaarlink.ai/api/v1/keys
Authorization: Bearer sk-bl-YOUR_MGMT_KEY
Content-Type: application/json

{
  "name": "Agent Key",
  "limit": 10.00,
  "limit_reset": "monthly",
  "expires_at": "2026-12-31T23:59:59Z"
}

# limit_reset: daily | weekly | monthly
# expires_at:  ISO 8601 datetime (optional)

# Response — save the key value, it won't be shown again
{
  "id": "clxyz789...",
  "name": "Agent Key",
  "key": "sk-bl-xyz789abcdef...",
  "keyType": "standard",
  "spendLimitUsd": 10.00,
  "spendLimitPeriod": "month",
  "expiresAt": "2026-12-31T23:59:59.000Z",
  "enabled": true,
  "createdAt": "2026-03-01T00:00:00.000Z"
}

キーの更新

PATCH https://bazaarlink.ai/api/v1/keys/:id
Authorization: Bearer sk-bl-YOUR_MGMT_KEY
Content-Type: application/json

{"enabled": false}              # disable key
{"spendLimitUsd": 5, "spendLimitPeriod": "week"}  # set spend limit
{"spendLimitUsd": null}         # remove spend limit
# Response: {"updated": true}

キーの取り消し

DELETE https://bazaarlink.ai/api/v1/keys/:id
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Returns 204 No Content on success

残高照会

GET https://bazaarlink.ai/api/v1/credits
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Response
{
  "data": {
    "total_credits": 12.345,
    "total_usage": 3.210
  }
}

使用量照会

GET https://bazaarlink.ai/api/v1/usage?period=month
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# period: day | week | month | year

アプリ帰属

リクエストヘッダーでアプリケーションを識別して、使用量追跡、ダッシュボード表示、詳細な分析を有効にします。

注意
これらのヘッダーは完全にオプションであり、API機能には影響しません。ただし、デバッグと使用量帰属のために設定することが推奨されます。

利用可能なヘッダー

HeaderDescription
HTTP-RefererサイトURL、使用状況の追跡と分析用(任意)
X-Titleアプリ名、ダッシュボードに表示(任意)
from openai import OpenAI

client = OpenAI(
    base_url="https://bazaarlink.ai/api/v1",
    api_key="sk-bl-YOUR_KEY",
    default_headers={
        "HTTP-Referer": "https://yourapp.com",  # Optional: your site URL
        "X-Title": "My Application",             # Optional: your app name
    },
)

response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)

エラーコード

Error response format

Model inference endpoints return an OpenAI-compatible error envelope. The type field can vary or be omitted; use the HTTP status and error.code instead of parsing the message.

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

HTTP status and error.code

Before streaming, the HTTP status identifies the broad failure class. error.code is either that number or a stable string for a specific remedy. Prefer the string code when present, otherwise use the HTTP status.

コード
名前
説明
400Bad Request不正なリクエスト、空のmessages配列、または必須フィールドの欠落
401UnauthorizedAPIキーが欠落、無効、または無効化されている
402Payment Requiredアカウントクレジット不足、キーごとの支出制限到達、または月次/週次予算上限超過
403Forbiddenアカウントが停止されているか、権限がない
404Not FoundRequested model, generation, key, or other resource does not exist
409ConflictResource is not in the required state, such as an incomplete video job
410GoneRequested model has been retired and must be replaced
413Payload Too Largeリクエストボディが10MBを超えています。コンテンツサイズを縮小するかリクエストを分割してください
416Range Not SatisfiableRequested byte range is invalid for generated video content
429Too Many Requestsレート制限超過。リトライ前にRetry-Afterヘッダーを確認してください
500Server ErrorBazaarLink内部エラー
502Bad Gatewayすべてのアップストリームプロバイダーが失敗。フェイルオーバーが試行されました
503Service Unavailableこのモデルにアップストリームプロバイダーが設定されていません。管理者に連絡してください
504Gateway TimeoutUpstream connection or stream stalled and timed out

Machine-readable billing codes

A 402 can represent different controls. Use these stable codes to choose the correct action.

コード
説明
budget_cap_reachedA weekly or monthly budget cap was reached; raise or reset the cap.
credit_limit_exceededA monthly-billing organization's credit line was exhausted; contact billing.
insufficient_creditsThe prepaid balance is insufficient; add credits.
spend_limit_exceededThe API key reached its daily, weekly, or monthly spend limit.

Stable error.code catalog

These string codes are emitted by public inference and media paths. Branch on the string code when present; the HTTP status remains the broad failure class.

Model and endpoint
Model lookup, lifecycle, pricing, modality, and endpoint compatibility errors.
コード
HTTP status
unknown_model400
invalid_model_id400
model_not_found404
model_retired410
model_endpoint_mismatch400
embedding_on_chat_endpoint400
model_not_priced400
invalid_modality_for_model400
Request and safety
Invalid parameters, context, tools, schemas, and content-safety refusals.
コード
HTTP status
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
Image generation and editing
Image input, multipart editing, output, and image-pipeline errors.
コード
HTTP status
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
Upstream routing
Sanitized provider connectivity, authentication, throttling, and availability errors.
コード
HTTP status
upstream_unreachable502
upstream_auth_failed502
upstream_rate_limited429
upstream_unavailable502/503

Rate limits, budgets, and emergency brakes

These controls can reject an otherwise valid request and require different recovery actions.

Control
HTTP status
How to identify it
Request rate limit429Numeric code 429; use Retry-After and X-RateLimit-* headers.
Rate-limit penalty block429Numeric code 429 and a temporary restriction message; use Retry-After.
Global spend emergency brake503Numeric code 503, global spend-limit message, and Retry-After of 30 or 300 seconds.
Scoped spend brake429Numeric code 429 and a spend circuit-breaker message naming the scope.
Billing and budget controls402Use the stable billing string codes listed above.

Compatibility note: rate-limit and emergency-brake paths currently emit numeric error.code values. Use HTTP status, Retry-After, and the documented response message.

Video and media resource state

Video validation commonly returns numeric code 400. Missing jobs return 404, retired models 410, unfinished video content 409, and invalid video byte ranges 416.

Retry policy

Retry only failures that may recover without changing the request. Honor Retry-After or use exponential backoff with jitter. Do not stack SDK and manual retries.

Retry with backoff
429, 502, 503, and 504. Check the original generation job before creating another after an ambiguous network failure.
Fix before retrying
400, 401, 402, 403, 404, 409, 410, 413, and 416. Fix the request, credentials, balance, permissions, resource state, or Range header first.

エラー処理

import random
import time
from openai import OpenAI, APIStatusError

client = OpenAI(
    base_url="https://bazaarlink.ai/api/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-4.1",
            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)

ストリーミングエラー形式

トークンがストリーミングされる前に発生したエラーは、JSONボディを持つ標準のHTTPエラーレスポンスを返します。

After a stream starts, the HTTP response is already 200. Parse each SSE data frame and treat a top-level error or choices[0].finish_reason === "error" as a failed, incomplete response.

ストリームが途中で失敗した場合、BazaarLink はトップレベルの error オブジェクトを含む最後のSSEイベントを送信し、その後に data: [DONE] が続きます。一部のアップストリームからそのまま転送されるチャンクでは、エラーが 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.

ツールコール

ツールコール(ファンクションコールとも呼ばれる)は、定義した外部関数をモデルが呼び出せるようにします。モデルがツールを呼び出すタイミングを判断し、構造化された引数を生成します — コードが関数を実行し、結果を返して会話を続けます。

対応モデル

ほとんどのフロンティアモデルがツールコールをサポートしています。人気のある選択肢:

ツールの定義

各ツールはモデルが呼び出せる関数を記述するJSONオブジェクトです。parametersフィールドはJSON Schemaを使用します。

name必須
string
関数名(a-z、A-Z、0-9、アンダースコア、ハイフン)
description必須
string
関数がいつ、どのように使用されるべきかの明確な説明
parameters必須
object
関数パラメータを定義するJSON Schemaオブジェクト

tool_choiceオプション

動作
"auto"モデルがツールを呼び出すかどうかを判断(デフォルト)
"none"モデルはツールを呼び出さない
"required"モデルは少なくとも1つのツールを呼び出す必要がある
{"type": "function", "function": {"name": "get_weather"}}モデルは指定された関数を呼び出す必要がある

完全なフロー

ツールコールはマルチターンプロセスです:(1) ツール付きリクエストを送信 → (2) モデルがtool_callsを返す → (3) 関数を実行 → (4) 結果を送り返す → (5) モデルが最終レスポンスを生成。

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [{"role":"user","content":"What is the weather in Taipei?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "City name"},
            "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
          },
          "required": ["city"]
        }
      }
    }],
    "tool_choice": "auto"
  }'
# Response carries tool_calls — run get_weather() yourself, then send the
# result back with role:"tool" (same shape as the Python/TS steps 3-5) to
# get the model's final answer.

並列ツールコール

一部のモデルは1つのレスポンスで複数のツールを呼び出せます。各ツールコールを処理し、すべての結果を返します:

# Model may return multiple tool_calls
if message.tool_calls:
    messages = [
        {"role": "user", "content": "Weather and time in Tokyo?"},
        message,
    ]

    for tool_call in message.tool_calls:
        # Execute each function
        if tool_call.function.name == "get_weather":
            result = {"temperature": 22, "condition": "Clear"}
        elif tool_call.function.name == "get_time":
            result = {"time": "2026-02-23T15:30:00+09:00"}

        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result),
        })

    # Send all results back at once
    final = client.chat.completions.create(
        model="openai/gpt-4.1",
        messages=messages,
        tools=tools,
    )
    print(final.choices[0].message.content)

ストリーミング中のツールコール

ストリーミング時、ツールコールは位置でインデックスされた部分的なデルタとして届きます——各デルタの引数文字列をインデックスごとに蓄積し、finish_reasonが"tool_calls"になった時点で呼び出しが完了したことを示します。

# Streaming: tool_calls arrive as partial deltas indexed by position —
# accumulate function.arguments per index until finish_reason == "tool_calls".
stream = client.chat.completions.create(
    model="openai/gpt-4.1",
    messages=[{"role": "user", "content": "What's the weather in Taipei?"}],
    tools=tools,
    tool_choice="auto",
    stream=True,
)

tool_calls = {}
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.tool_calls:
        for tc in delta.tool_calls:
            entry = tool_calls.setdefault(tc.index, {"id": "", "name": "", "arguments": ""})
            if tc.id:
                entry["id"] = tc.id
            if tc.function.name:
                entry["name"] = tc.function.name
            if tc.function.arguments:
                entry["arguments"] += tc.function.arguments
    if chunk.choices[0].finish_reason == "tool_calls":
        for call in tool_calls.values():
            print(call["name"], json.loads(call["arguments"]))

シンプルなAgentループ

モデルがツールを要求し続ける限り呼び出しを続け、最終的な回答を返したら停止する汎用パターン——無限ループを防ぐためmax_iterationsを使用します。

# Generic loop: keep calling the model while it keeps requesting tools,
# stop once it returns a plain answer. max_iterations guards against loops.
messages = [{"role": "user", "content": "What's the weather in Taipei, and what time is it there?"}]
max_iterations = 10

for _ in range(max_iterations):
    response = client.chat.completions.create(
        model="openai/gpt-4.1",
        messages=messages,
        tools=tools,
    )
    message = response.choices[0].message
    messages.append(message)

    if not message.tool_calls:
        break  # model gave a final answer

    for tool_call in message.tool_calls:
        args = json.loads(tool_call.function.arguments)
        result = TOOL_MAPPING[tool_call.function.name](**args)
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result),
        })
else:
    print("Warning: max_iterations reached without a final answer")

print(messages[-1].content)

関数定義のベストプラクティス

  • 具体的で説明的な名前を使う——単に weather ではなく get_weather_forecast のように。
  • 関数の目的と使用すべきタイミングを明確に記述する——モデルは呼び出すかどうかをこのテキストのみで判断します。
  • 可能な限り enum で値を制限し、description に例を含めて誤った引数の生成を減らす。
  • 本当に必須のフィールドのみ required とし、任意フィールドは実際に省略可能にする。

構造化出力

モデルにスキーマに一致する有効なJSONを返させます。モデル出力をプログラムで解析する信頼性の高いアプリケーション構築に不可欠です。

方法1:response_format(JSON Schema)

で厳密なJSON Schemaへの準拠を強制:

type必須
string
"json_schema"を指定
json_schema.name必須
string
スキーマの名前(キャッシングに使用)
json_schema.strict
boolean
trueの場合、厳密なスキーマ準拠を保証
json_schema.schema必須
object
JSON Schema定義
curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [{"role":"user","content":"Review the movie Inception"}],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "movie_review",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "title": {"type": "string"},
            "rating": {"type": "integer", "description": "Rating 1-10"},
            "summary": {"type": "string"},
            "pros": {"type": "array", "items": {"type": "string"}},
            "cons": {"type": "array", "items": {"type": "string"}}
          },
          "required": ["title", "rating", "summary", "pros", "cons"],
          "additionalProperties": false
        }
      }
    }
  }'

ヒント

  • 明確でわかりやすいプロパティ名を使用 — モデルはそれをコンテキストとして使用します。
  • スキーマプロパティに説明を追加してモデルを導きましょう。
  • strict: trueを設定するとスキーマ準拠が保証されます(レイテンシがわずかに増加する場合があります)。
  • スキーマはシンプルに — 深くネストされたスキーマは出力品質を低下させる可能性があります。
  • 異なるモデルでテスト — モデルによって複雑なスキーマの処理能力が異なります。

アシスタントプリフィル

メッセージ配列の最後に未完成の assistant メッセージを追加し、互換性のあるモデルルートに続きを生成するよう要求します。

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4.6",
    "messages": [
      {"role":"user","content":"What is the capital of France?"},
      {"role":"assistant","content":"The capital of France is"}
    ]
  }'
# Model continues: " Paris, known for the Eiffel Tower..."
仕組み
BazaarLink は最後の assistant メッセージを保持して転送します。続きの生成動作は選択したアップストリームモデルとプロバイダーが実装するため、すべてのルートで保証されるわけではありません。

メッセージ変換

モデルのコンテキスト制限に収まるようにメッセージを自動変換。メッセージがモデルのコンテキストウィンドウを超えた場合、変換が中間のメッセージを除去して会話を効率的に圧縮します。

Auto
コンテキストウィンドウが8,192トークン以下のモデルは、デフォルトでmiddle-outが自動適用されます。無効にするには`transforms: []`を渡してください。任意のモデルで有効にするには`transforms: ["middle-out"]`を渡してください。

使い方

// Enable middle-out on any model
{
  "model": "openai/gpt-4.1",
  "transforms": ["middle-out"],
  "messages": [
    { "role": "system", "content": "You are a helpful assistant." },
    ... // long conversation — middle will be trimmed to fit context
  ]
}

// Disable auto-trimming for small-context models
{ "transforms": [] }

変換タイプ

変換
説明
middle-out最初(システムプロンプト、コンテキスト)と最後(最近のメッセージ)を保持しつつ、中間のメッセージを最初に削除

デフォルト動作

≤8kコンテキストのモデルではmiddle-outが自動的に有効。より大きなコンテキストモデルでは明示的に有効化してください。Anthropic Claudeモデルはtransforms設定に関係なく、1,000メッセージ制限を自動的に適用します。

ゼロデータ保持

BazaarLinkはデフォルトでメッセージ内容を保存しません。このページではデータの取り扱い方法を説明します。機密データを処理するアプリケーションに適しています。

現在のデータ取り扱い

  • メッセージ内容:デフォルトでは保存されず、処理後にメモリから破棄
  • 課金メタデータ:トークン数、タイムスタンプ、モデルID
  • 使用ログ:リクエスト統計のみ、メッセージ内容なし
  • アップストリーム転送:メッセージはアップストリームプロバイダーに転送 — 各プロバイダーのプライバシーポリシーに従う

プロンプトキャッシング

プロンプトキャッシングは以前に計算されたプロンプトトークンを再利用し、コストとレイテンシを大幅に削減します — 特に大きな繰り返しシステムプロンプトを持つアプリケーションに効果的です。

Note
BazaarLinkはキャッシュの節約を自動追跡し、課金に反映します。レスポンスの`cached_tokens`フィールドに実際のキャッシュヒットが、`cacheDiscount`にそのリクエストで節約された金額が表示されます。

仕組み

設定が必要かどうかはプロバイダーによります。OpenAI系モデルは長く繰り返されるプロンプトプレフィックスを自動でキャッシュします — リクエストの変更は不要です。Claude(Anthropic)モデルはリクエストに明示的な cache_control ブレークポイントが含まれる場合のみキャッシュされます。BazaarLink はこれを代わりに追加しないため、マーカーがない Claude リクエストは決してキャッシュされません。BazaarLink は送信されたキャッシュマーカーをそのまま転送し、使用量レスポンスで実際のキャッシュ読み書きトークン数を報告します。

# OpenAI-family models: nothing to add, long repeated prefixes cache automatically.
response = client.chat.completions.create(
    model="openai/gpt-4.1",
    messages=[
        {"role": "system", "content": "You are an expert..."},  # cached automatically if long/repeated
        {"role": "user", "content": "Question here"},
    ],
)

# Check cache savings in the response usage
usage = response.usage
print(f"Prompt tokens: {usage.prompt_tokens}")
print(f"Cached tokens: {usage.prompt_tokens_details.cached_tokens}")
print(f"Cache savings: {usage.prompt_tokens_details.cached_tokens / usage.prompt_tokens * 100:.1f}%")
Claudeには明示的なcache_controlマーカーが必要です
キャッシュしたいコンテンツブロックに cache_control: {"type": "ephemeral"} を追加してください(下記の例を参照)。Anthropicには独自の最小プロンプト長の制限もあり、それを下回るとマーカーがあってもエラーなく静かにキャッシュされません。レスポンスの cached_tokens(OpenAI形式)または cache_read_input_tokens / cache_creation_input_tokens(Anthropic形式)でヒットを確認してください。
# Claude models: you must mark the block to cache yourself.
response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6",
    messages=[
        {
            "role": "system",
            "content": [
                {"type": "text", "text": "You are an expert...", "cache_control": {"type": "ephemeral"}}
            ],
        },  # BazaarLink does not add cache_control on your behalf
        {"role": "user", "content": "Question here"},
    ],
)

usage = response.usage
print(f"Cache read tokens: {getattr(usage, 'cache_read_input_tokens', 0)}")
print(f"Cache write tokens: {getattr(usage, 'cache_creation_input_tokens', 0)}")

推論トークン

推論モデル(DeepSeek R1、o1シリーズなど)は最終回答を生成する前に内部で思考します。これらの内部トークンは推論トークンと呼ばれ、別途課金されます。

Note
BazaarLinkは`usage.completion_tokens_details.reasoning_tokens`で推論トークンを報告し、課金でも個別に表示されます。

レスポンスからの推論トークンの読み取り

response = client.chat.completions.create(
    model="deepseek/deepseek-r1",
    messages=[{"role": "user", "content": "Solve: if f(x) = x^2 + 3x, what is f(5)?"}],
)

# Read reasoning tokens from usage
usage = response.usage
print(f"Completion tokens: {usage.completion_tokens}")
if hasattr(usage, "completion_tokens_details"):
    details = usage.completion_tokens_details
    print(f"Reasoning tokens: {details.reasoning_tokens}")
    print(f"Output tokens: {details.accepted_prediction_tokens}")
const response = await client.chat.completions.create({
  model: "openai/o3-mini",
  messages: [{ role: "user", content: "Prove that sqrt(2) is irrational." }],
  // @ts-ignore - BazaarLink extension
  reasoning_effort: "high",  // low | medium | high
});

const usage = response.usage;
console.log("Reasoning tokens:", usage?.completion_tokens_details?.reasoning_tokens);

思考モード制御

一部のモデルは「思考」モードの切り替えをサポートしています。思考モードは最終回答の前に内部推論トークンを生成し、トークン消費が増加する代わりに品質が向上します。

モデルファミリーパラメータデフォルト
qwen3-*enable_thinking: booleanfalse(プラットフォームデフォルト)
openai/o1, o3, o4-minireasoning_effort: "low" | "medium" | "high"medium
deepseek/deepseek-r1常時有効(無効化不可)
# Qwen3: explicitly enable thinking mode
response = client.chat.completions.create(
    model="qwen/qwen3-32b",
    messages=[{"role": "user", "content": "Prove the Pythagorean theorem"}],
    extra_body={"enable_thinking": True},  # opt-in to thinking
)

# usage.completion_tokens_details.reasoning_tokens shows thinking token count

統一reasoningオブジェクト(新フォーマット)

BazaarLinkは統一reasoningオブジェクトもサポートしており、すべてのモデルファミリーで一貫したAPIで動作します:

フィールド適用対象
reasoning.effort"xhigh" | "high" | "medium" | "low" | "none"OpenAI o-series, Grok
reasoning.max_tokensintegerAnthropic Claude, Gemini
reasoning.excludebooleanレスポンスから思考を非表示(モデルは引き続き推論を実行)
// Claude extended thinking — specify thinking budget in tokens
const response = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4.5",
  messages: [{ role: "user", content: "Prove the Pythagorean theorem" }],
  // @ts-ignore - BazaarLink extension
  reasoning: { max_tokens: 5000 },
});

// OpenAI o3 — specify effort level
const response2 = await client.chat.completions.create({
  model: "openai/o3",
  messages: [{ role: "user", content: "Solve this math problem..." }],
  // @ts-ignore - BazaarLink extension
  reasoning: { effort: "high" },
});

// Hide thinking content from response (model still thinks)
const response3 = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4.5",
  messages: [{ role: "user", content: "What is 2+2?" }],
  // @ts-ignore - BazaarLink extension
  reasoning: { max_tokens: 2000, exclude: true },
});
料金
思考トークンはコンプリーショントークンとして課金されます。一部のプロバイダーは思考モードに高いレートを課金します — Qwen3は思考が有効な場合、標準料金の2倍です。BazaarLinkは予期しないコストを避けるため、Qwen3のenable_thinkingをデフォルトでfalseに設定しています。

レイテンシ&パフォーマンス

AI APIレスポンスレイテンシの最適化はユーザーエクスペリエンスに不可欠です。BazaarLinkアーキテクチャでレイテンシに影響する主要因と最適化のベストプラクティスを以下に示します。

Note
BazaarLinkはすべてのリクエストについて`duration_ms`(エンドツーエンドレイテンシ)と`throughput`(トークン/秒)を記録——GET /api/v1/generation?id=... で照会するか、Activity ExportのCSVで確認できます。

レイテンシに影響する要因

  • モデルサイズ:大規模モデル(70B+)は一般に生成が遅い
  • プロバイダーの負荷:プロバイダーや時間帯によって変動
  • トークン数:max_tokensが高いほどコンプリーション時間が長い
  • ストリーミング vs 非ストリーミング:stream: trueは最初のトークンをより速く配信
  • コンテキスト長:非常に長いコンテキストは前処理時間を増加

最適化のヒント

  • 体感レイテンシを改善するにはストリーミング(stream: true)を推奨
  • 高スループットプロバイダーを選択するには:nitroバリアントを使用
  • レイテンシに敏感なシナリオではより小さなモデル(flash/mini/haiku)を選択
  • 最低レイテンシのプロバイダーを自動選択するにはprovider.sort: "latency"を使用
  • 繰り返しリクエストのレイテンシを削減するにはプロンプトキャッシングを有効化
import time

# Measure time to first token with streaming
start = time.time()
first_token_time = None

stream = client.chat.completions.create(
    model="google/gemini-2.5-flash",  # Fast model
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content and not first_token_time:
        first_token_time = time.time() - start

print(f"Time to first token: {first_token_time:.3f}s")
# Look up per-request latency and throughput after the fact, using the
# generation ID from the response (or the final streamed chunk).
curl "https://bazaarlink.ai/api/v1/generation?id=chatcmpl-abc123" \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY"

# Response
{
  "data": {
    "id": "chatcmpl-abc123",
    "model": "google/gemini-2.5-flash",
    "duration_ms": 842,
    "throughput": 61.2,
    "usage": { "prompt_tokens": 12, "completion_tokens": 48, "total_tokens": 60 }
  }
}
# Use provider.sort for automatic latency optimization
response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={
        "provider": {
            "sort": "latency",  # Always pick lowest-latency provider
        }
    },
)

稼働率最適化

BazaarLinkは複数のレイヤーでAPI可用性を最大化:自動フェイルオーバー、サーキットブレーカー、プロバイダーヘルスモニタリング。

Note
BazaarLinkはすべてのアップストリームプロバイダーの可用性を追跡。プロバイダーのエラーレートが閾値を超えると、サーキットブレーカーが自動的にトリガーされ、次に利用可能なプロバイダーにリクエストをルーティングします。

可用性メカニズム

  • サーキットブレーカー:障害の発生したプロバイダーを自動検出して隔離
  • 自動フェイルオーバー:バックアッププロバイダーにシームレスに切り替え — コード変更不要
  • プロバイダーヘルスモニタリング:プロバイダーごとのエラーレートとレイテンシを継続的に追跡
  • リトライロジック:一時的なエラー(5xx)は自動リトライ

サーキットブレーカー

# BazaarLink handles failover automatically — no code changes needed.
# Configure fallback models for maximum resilience:

response = client.chat.completions.create(
    model="openai/gpt-4o",       # Primary model
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={
        "models": [              # Fallback chain
            "openai/gpt-4o",
            "anthropic/claude-sonnet-4.6",
            "google/gemini-2.5-flash",
        ],
        "route": "fallback",     # Enable fallback routing
    },
)

# Check if failover was used (in usage logs)
# "is_failover": true indicates the primary provider was bypassed
プロバイダーヘルス監視は社内運用向けの表示です
GET /api/admin/provider-health は運用ダッシュボード用の内部エンドポイントで、管理者認証が必要です。プロバイダーごとのリクエスト数、エラー率、レイテンシパーセンタイル、フェイルオーバー統計などを含む完全な運用データを返します——一般顧客向けの公開APIではないため、ここでは実際のフィールドを再現していません。

ガードレール

APIリクエストにコンテンツ安全機構を追加し、有害なコンテンツをフィルタリングしてコンプライアンスポリシーを施行します。BazaarLinkが現在提供するカスタマイズ可能なコンテンツフィルターガードレールは組織(Organization)レベルのみです。個人(非組織)APIキーには対応する設定がなく、コンテンツ安全は各アップストリームモデルプロバイダー自身の組み込み安全システムに完全に依存します。

現在の範囲
個人APIキーには組み込みのカスタムガードレールがありません——コンテンツ安全は上流プロバイダー自身の安全システムに完全に依存します。カスタマイズ可能なコンテンツフィルタールール(ブロック/編集/記録、キーワードと正規表現ルール、組み込みPIIテンプレート)が必要な場合は、組織を作成して組織APIキーを使用してください——設定は「コンテンツフィルターガードレール」にあります。

計画中の機能(個人・組織キーいずれにも未提供)

ガードレール
説明
PII検出個人を特定できる情報の検出と編集
トピック制限承認されたトピックのみにモデルレスポンスを制限
出力検証返す前にカスタムルールでモデル出力を検証

現在の動作

個人APIキー:すべてのアップストリームプロバイダーには独自のコンテンツ安全システムがあり、コンテンツフィルターをトリガーしたモデルレスポンスはfinish_reason: "content_filter"で返され、BazaarLinkは追加のフィルタリングを行いません。組織APIキー:org_adminは「コンテンツフィルターガードレール」でカスタムルール(ブロック/編集/記録)を設定でき、テキストがモデルに到達する前に適用されます。

Cursor IDE Integration

BazaarLink を Cursor の OpenAI Override URL に設定し、即座に Cursor 内ですべてのモデルを呼び出せます。Responses API の自動変換、ツール形式の正規化、Claude モデル向けの bz- プレフィックス規約をサポートします。

クイックセットアップ

Cursor で 設定 → モデル を開き、次の手順を行います:

  1. Override OpenAI Base URL を https://bazaarlink.ai/v1 に設定
  2. Override OpenAI API Key を sk-bl-... の BazaarLink キーに設定
  3. 使いたいモデル名を入力 — Claude モデルは下記の bz- プレフィックスを参照。
後方互換
旧 URL https://bazaarlink.ai/v1/cursor は引き続き動作します — 現在は /v1/chat/completions を再エクスポートする薄いラッパーです。新規セットアップでは /v1 を直接使用してください。

bz- プレフィックス(Claude モデル用)

Cursor のクライアント側バリデーションは claude- で始まるモデル名を Cursor 自身の Anthropic 連携に転送し、Override URL を経由しません。Cursor のリクエストを BazaarLink に送らせるには、モデル名の前に bz- を付けます。サーバーがプレフィックスを取り除き、残りを alias map で解決します。

Cursor での入力解決先
bz-claude-sonnet-4.6anthropic/claude-sonnet-4.6
bz-claude-opus-4.7anthropic/claude-opus-4.7
gpt-4oopenai/gpt-4o
gemini-2.5-flashgoogle/gemini-2.5-flash

ドットとハイフンのバリエーションは正規化されます: bz-claude-sonnet-4.6 と bz-claude-sonnet-4-6 はどちらも同じモデルに解決されます。

CURSOR_MODEL_MAP 環境変数(オペレーターオーバーライド)

BazaarLink をセルフホストしている場合、この環境変数を設定すると Cursor 側の任意のモデル名をカタログの canonical id に再マッピングできます:

CURSOR_MODEL_MAP=gpt-claude-sonnet:anthropic/claude-sonnet-4.6,gpt-opus:anthropic/claude-opus-4.7

これで Cursor で gpt-claude-sonnet と入力すると、サーバー側で anthropic/claude-sonnet-4.6 にマッピングされます。Cursor にあるモデルが GPT ファミリーだと思わせて Override URL を経由させつつ、実際は Claude を提供したい場合に便利です。

自動的に処理される内容

リクエストが /api/v1/chat/completions に届くと、BazaarLink は以下の互換性変換を透過的に適用します — クライアント側で何もする必要はありません:

  • Responses API ボディを自動検出 — body に messages の代わりに input がある場合、Chat Completions 形式に変換されます(Cursor は GPT ファミリーのモデルに対して Responses API 形式を送信)。
  • フラットなツール定義をラップ — Cursor Agent は function ラッパーなしの { name, description, parameters } を送信します。Anthropic が Tool '' not found in provided tools として拒否しないようにラップします。
  • 不正な tool_choice を強制変換 — Cursor は { type: "auto" }(オブジェクト形式、function なし)を送信します。OpenAI 仕様では auto/none/required は文字列形式が必須なので、強制的に変換します。
  • 非 OpenAI プロバイダーへのルーティング時に OpenAI 専用フィールドを削除 — parallel_tool_calls、logprobs、top_logprobs、logit_bias、service_tier、user は転送前に削除されます(そうしないと Anthropic は 400 を返します)。
  • max_output_tokens → max_tokens にマッピングし、Responses-API 専用フィールド(previous_response_id、truncation、background、store)を削除します。reasoning フィールドは Chat-Completions ネイティブのボディでは保持されます。

Cursor Agent モード

ツール呼び出しは標準の Chat Completions ツール呼び出しフローで動作します。Cursor は tools(Shell、Read、Write、Grep など)と tool_choice: "auto" を送信します; BazaarLink は選択したプロバイダーに転送し、プロバイダーがツールを呼ぶか決定します。ツール呼び出しは標準 OpenAI tool_calls deltas として返り、Cursor がローカルで実行して会話を継続します。gpt-4o(ネイティブ OpenAI)を選んでも bz-claude-sonnet-4.6を選んでも同じように動作します。

上流の拒否のデバッグ
プロバイダーから 4xx エラーが返ってくる場合、admin の「Provider Health」パネルを確認してください。すべての 4xx レスポンスは、上流のエラーボディの全文と転送したリクエストボディの概要が保存されます — 🔴 の行をクリックすると JSON が展開されます。

モデルルーティング

BazaarLinkはprovider/model-name形式を使用してリクエストを正しいアップストリームプロバイダーにルーティングします。単一のAPIエンドポイントで主要モデルにアクセスできます。

モデルID形式

{provider}/{model-name}

# Examples
openai/gpt-5.4-mini
anthropic/claude-sonnet-4.6
google/gemini-3-flash-preview
deepseek/deepseek-v3.2

ルーティング優先度

リクエストを送信すると、BazaarLinkは次の順序でアップストリームプロバイダーを解決します:

  1. 完全一致 — 完全なモデルIDに一致するモデルルートを検索
  2. プロバイダーワイルドカード — provider/*ルートにフォールバック(例:openai/*)
  3. グローバルワイルドカード — *ワイルドカードルートにフォールバック
  4. デフォルトプロバイダーキー — カタログ登録済みモデルに限り、有効でデフォルト指定されたキーを使用

利用可能なすべてのモデルは モデルページで閲覧できます。

オートルーター

Auto Router v3 はリクエストを14個のタスク tier のいずれかに評価し、その tier に現在設定されている primary と fallback チェーンを使用します。有料表と無料表は管理画面で別々に管理できます。

  • auto — 有料ルーティング表を使用し、成功した実モデルの公開価格で課金されます。
  • auto:free — 無料ルーティング表を使用し、無料枠内は 0 ドルです。枠を超えると、残高のあるアカウントは有料 fallback を無効にしていない限り有料 auto に切り替わる場合があります。

使い方

モデルを"auto"(有料)または"auto:free"(無料)に設定して自動ルーティングを有効化:

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto","messages":[{"role":"user","content":"Review this TypeScript function"}]}'

v3 の tier 選択

一般 tier は simple、standard、complex、reasoning。専門 tier は coding、vision、image、video、data、search、social、email、calendar、trading です。信頼度が低い境界では難易度を一段上げます。

  • tier 評価:messages、tools、長さ、キーワード、構造的特徴から14 tier の1つを選択
  • 強制ルール:画像、形式推論、専門タスクは tier を直接指定可能
  • ルート参照:現在の primary と最大5件の fallback を読み、無効な tier は503を返す
  • 実行:primary の後、設定順に fallback を試行
  • レスポンス追跡:解決されたモデルはレスポンスボディとX-Auto-Resolved-Modelヘッダーで返される

現在のモデル表

以下は推論と管理画面が使用する同じライブ設定です。各 tier の primary、fallback 順序、有効状態は再デプロイなしで変更できます。

auto

Tier
Primary
Fallbacks
State
simpleopenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-previewanthropic/claude-haiku-4.5
enabled
standardgoogle/gemini-3-flash-preview
openai/gpt-5.4-minianthropic/claude-haiku-4.5
enabled
complexgoogle/gemini-3.1-pro-preview
anthropic/claude-sonnet-4.6openai/gpt-5.4-pro
enabled
reasoninganthropic/claude-opus-4.7
openai/gpt-5.4-progoogle/gemini-3.1-pro-preview
enabled
codingopenai/gpt-5.3-codex
anthropic/claude-sonnet-4.6openai/gpt-5.4-pro
enabled
visionopenai/gpt-5.4-image-2
enabled
imageopenai/gpt-5.4-image-2
enabled
videobytedance/seedance-2.0-fast
bytedance/seedance-2.0anthropic/claude-sonnet-4.6
enabled
dataopenai/gpt-5.4-pro
anthropic/claude-sonnet-4.6google/gemini-3.1-pro-preview
enabled
searchperplexity/sonar-pro
perplexity/sonar-reasoning-proopenai/gpt-5.4-pro
enabled
socialopenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-previewanthropic/claude-haiku-4.5
enabled
emailopenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-previewanthropic/claude-sonnet-4.6
enabled
calendaropenai/gpt-5.4-nano
google/gemini-3.1-flash-lite-preview
enabled
tradinganthropic/claude-opus-4.7
openai/gpt-5.4-progoogle/gemini-3.1-pro-preview
enabled

auto:free

Tier
Primary
Fallbacks
State
simpledeepseek/deepseek-v4-flash
enabled
standarddeepseek/deepseek-v4-flash
enabled
complexminimax/minimax-m2.5
enabled
reasoningminimax/minimax-m2.5
enabled
codingdeepseek/deepseek-v4-flash
enabled
visionopenai/gpt-5.4-image-2
disabled
imageopenai/gpt-5.4-image-2
disabled
videogoogle/gemini-2.5-flash-lite
disabled
datadeepseek/deepseek-v4-flash
enabled
searchminimax/minimax-m2.5
enabled
socialdeepseek/deepseek-v4-flash
enabled
emaildeepseek/deepseek-v4-flash
enabled
calendardeepseek/deepseek-v4-flash
enabled
tradingdeepseek/deepseek-v4-flash
enabled

一部のモデルはレート制限付きの無料枠を提供しています。無料資格はプラットフォームがモデル単位で付与します — 通常のモデルIDでそのまま呼び出せます。:free サフィックスは任意のエイリアスです(有料モデルに付けても無料にはなりません)。

無料枠を使い切った後
枠を使い切っても、残高があればリクエストはそのモデルの有料価格で自動的に継続され(サービスは中断しません)、通常の有料呼び出しと同じ料金が発生します。課金より失敗を望む場合は X-Free-Fallback: false ヘッダーを送るか、キー設定で自動切替を無効にしてください。その場合は 429 が返ります。残高がない場合、超過リクエストは常に 429 を返します。
X-Auto-Resolved-Model
実際に選ばれたモデルは X-Auto-Resolved-Model ヘッダーとレスポンスの model フィールドに返されます。

モデルバリアント

任意のモデルIDにサフィックスを追加してルーティング動作を変更。BazaarLinkは7種類のバリアントをサポート。

バリアントタイプ
バリアントには2つのカテゴリがあります:独立モデルID(サフィックス付きモデルが独自のエンドポイント)とルーティングショートカット(サフィックスがモデル自体を変更せずにBazaarLinkのプロバイダー選択方法を変更)。

独立モデルID

これらのバリアントは独自の料金と機能を持つ別々のモデルとして存在します。BazaarLinkは最初にサフィックス付きの完全なモデルIDを試し、次にベースモデルにフォールバックします。

:free
:extended
:thinking
:exacto

ルーティングショートカット

これらのサフィックスはモデルのアイデンティティを変更せずにプロバイダー選択を変更します。サフィックスはルートマッチング前に除去されます。

:floor   # lowest listed input price first
:nitro   # throughput-oriented shortcut
:online  # enable web-search routing

マルチプロバイダー動作

バリアントをサポートするアップストリームでは、サフィックスはそのまま転送されます。直接プロバイダー(直接OpenAI、Fireworksなど)では、サフィックスが除去され、BazaarLinkがローカルでルーティングを処理します。

無料モデル

一部のモデルはレート制限付きの無料枠を提供しています。無料資格はプラットフォームがモデル単位で付与します — 通常のモデルIDでそのまま呼び出せます。:free サフィックスは任意のエイリアスです(有料モデルに付けても無料にはなりません)。

  • 通常のモデルID(例: deepseek/deepseek-v4-flash)で呼び出してください。無料枠内のリクエストは自動的に無料で処理されます。
  • 無料利用はユーザーごとに毎分リクエスト数(RPM)と1日の上限で制限されます。上限はアカウント階層(未入金 / 入金済み)に応じて変動します。
  • 無料枠を超過してもクレジット残高があれば、リクエストは表示価格の有料枠で自動的に継続されます。X-Free-Fallback: false を送ると自動フォールバックを無効化し、代わりに429が返ります。残高がない場合、超過リクエストは429を返します。
  • GET /api/v1/models は無料枠のあるモデルごとに :free エントリを一覧します。auto:free は常に無料モデルへルーティングされます。

現在無料枠があるモデル

これらのモデル ID をそのまま指定すると無料枠が適用されます。ラインナップは随時変わるため、最新の一覧は API で取得してください。

deepseek/deepseek-v4-flash

無料枠の上限

項目
毎分リクエスト数 (RPM)10 / min
1日あたりのリクエスト枠150 / day
アカウント階層倍率 — 未入金× 1
アカウント階層倍率 — 入金済み× 3

1日あたりの枠 = 上表のリクエスト枠 × アカウント階層倍率で、無料モデルごとに個別に計算されます。auto:free にはさらに IP 単位の並行上限があります。個々のモデルにはプラットフォーム側でより厳しい/緩い上限が設定される場合があり、実効値はモデルページの「無料枠」ブロックに表示されます。

無料枠を使い切った後

枠を使い切っても、残高があればリクエストはそのモデルの有料価格で自動的に継続され(サービスは中断しません)、通常の有料呼び出しと同じ料金が発生します。課金より失敗を望む場合は X-Free-Fallback: false ヘッダーを送るか、キー設定で自動切替を無効にしてください。その場合は 429 が返ります。残高がない場合、超過リクエストは常に 429 を返します。

# Return 429 instead of switching to paid routing
-H "X-Free-Fallback: false"

組織管理

BazaarLinkの組織は3階層アーキテクチャを使用:組織→チーム→メンバー。クレジットは組織レベルで保管され、各チームとメンバーに月次支出上限を設定可能。APIリクエストはメンバー→チーム→組織のクレジットを順に確認します。

組織を管理
チームの追加、メンバーの招待、組織設定の変更は、 設定を開いて組織を選択

3階層予算システム

すべてのAPIリクエストで3つの予算レイヤーが順に確認されます。いずれかのレイヤーを超過するとHTTP 429が返されます:

  1. メンバー月次予算(OrgMember.monthlyBudget)
  2. チーム月次予算(Team.monthlyBudget)
  3. 組織クレジット残高(Organization.credits)

使用量レポート

組織ポータルのレポートページでは、4つのディメンションにわたる月次支出分析を提供:

  • 概要:総支出、マージン率、日次トレンドチャート
  • チーム別:チームごとの支出、シェア%、モデル内訳、予算稼働率
  • モデル別:モデルごとの支出、平均価格($/1Mトークン)
  • メンバー別:メンバーごとの支出 — org_adminのみ

すべてのビューがBOMプレフィックス付きCSVエクスポートをサポートしており、Excel直接互換です。

組織の作成と管理

  1. 設定→組織→新しい組織を作成
  2. 組織名を選択して管理エリアを開く
  3. 組織ポータルでチームを作成(オプション:コストセンターコードと月次予算)
  4. メールでメンバーを招待し、ロールとチームを割り当て
  5. メンバー用のAPIキーを発行 — 使用量は正しいチーム/メンバーに自動タグ付け
  6. レポートページでチーム、モデル、メンバー別の月次支出を確認

メンバーロール

org_adminフルコントロール:メンバー、チーム、請求、設定
billing_viewer財務レポートの読み取り専用アクセス(メンバーごとの詳細は非表示)
team_admin自分のチーム内のメンバーと予算を管理
memberAPIを使用、チームと組織の予算制限に従う

What else can an organization manage?

Beyond members and teams, the organization management area provides:

  • APIキー:組織、チーム、メンバー用のキーを作成し、利用可能なモデルを制限
  • コンテンツフィルタリング:モデルへ送信する前に機密テキストをブロック、編集、または記録
  • 許可モデル:組織、チーム、メンバー、個別APIキーごとにモデルを制限
  • 予算と緊急停止:月間上限と分・時間単位の支出保護を設定
  • レポートと請求:支出、モデル利用、チーム配賦、残高、与信限度、支払いを確認
  • 変更・セキュリティログ:設定変更、コンテンツフィルター検知、セキュリティイベントを追跡
  • 教育機関向けプランでは、学生セッションとクォータも管理できます

Content filtering

Organization-owned rules inspect text before it reaches a model. An org_admin can enable, edit, and test them in Settings.

  • block: reject with HTTP 403
  • redact: replace matches with [REDACTED]
  • flag: send unchanged and record an audit event
  • Built-in sensitive-data and prompt-injection templates plus custom keyword or regex rules
  • Up to 100 safety-checked rules with a test preview
Currently limited to text input
Images, audio, video, some structured or multimodal content, and model output are not inspected.

管理API(v1)

/api/v1/orgs/エンドポイントはBearer管理キー(sk-bl-...)とセッションCookieの両方を受け付け、ブラウザセッションなしでサーバー間の組織管理を可能にします。

認証
すべての/api/v1/orgs/エンドポイントにはorg_adminロールが必要です。Authorization: Bearer sk-bl-<key>またはセッションCookieを渡してください。管理キーは設定→APIキーから作成できます。

組織

GET/api/v1/orgs

呼び出し元が所属するすべての組織を、role と joinedAt 付きで一覧する。

GET/api/v1/orgs/:orgId

team および member 数を含む組織の詳細を取得する。

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

チーム

GET/api/v1/orgs/:orgId/teams

メンバー数付きでチームを一覧する。name 順。

POST/api/v1/orgs/:orgId/teams
name必須
string
チームの表示名 (組織内で一意であること)
costCenterCode
string
会計用コストセンターコード
monthlyBudget
number | null
チームの月次支出上限 (USD)
PATCH/api/v1/orgs/:orgId/teams/:teamId

部分更新 — 変更するフィールドのみを含めること。

DELETE/api/v1/orgs/:orgId/teams/:teamId
# Create a team
curl https://bazaarlink.ai/api/v1/orgs/{orgId}/teams \
  -X POST \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Engineering", "costCenterCode": "ENG-001", "monthlyBudget": 500}'

メンバー

GET/api/v1/orgs/:orgId/members

ネストされた user (id/name/email) と team 情報を含む全メンバーを一覧する。

POST/api/v1/orgs/:orgId/members
email必須
string
既存の BazaarLink ユーザーの Email
role
string
org_admin | billing_viewer | team_admin | member (default: member)
teamId
string
チームに割り当て (role が team_admin の場合は必須)
monthlyBudget
number | null
メンバー単位の月次支出上限 (USD)

メールアドレスにBazaarLinkアカウントがない場合は404。既にメンバーの場合は409。デフォルトロール:member。

PATCH/api/v1/orgs/:orgId/members/:memberId

role、teamId、または monthlyBudget の部分更新。

DELETE/api/v1/orgs/:orgId/members/:memberId

対象が最後のorg_adminの場合は400を返します。

# Add a member
curl https://bazaarlink.ai/api/v1/orgs/{orgId}/members \
  -X POST \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "alice@example.com", "role": "member", "monthlyBudget": 50}'

# Remove a member
curl https://bazaarlink.ai/api/v1/orgs/{orgId}/members/{memberId} \
  -X DELETE \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

レポートAPI

月次支出データをプログラムで照会。org_adminとbilling_viewerがアクセス可能。ウェブセッションとBearer管理キーの両方を受け付け。

クエリパラメータ:year(デフォルト:現在の年)、month(デフォルト:現在の月、1〜12)。

エンドポイント
説明
GET /api/orgs/:orgId/reports/overview総支出、マージン率、日次トレンド
GET /api/orgs/:orgId/reports/by-teamチーム別支出、シェア %、モデル内訳、予算消化率
GET /api/orgs/:orgId/reports/by-modelモデル別支出、平均価格 ($/1M tokens)
GET /api/orgs/:orgId/reports/by-memberメンバー別支出 — org_admin のみ
GET /api/orgs/:orgId/reports/exportCSV ダウンロード; ?view=overview|by-team|by-model|by-member を付与可能
# Monthly overview via management key
curl "https://bazaarlink.ai/api/orgs/{orgId}/reports/overview?year=2026&month=3" \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

# By-team breakdown
curl "https://bazaarlink.ai/api/orgs/{orgId}/reports/by-team?year=2026&month=3" \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

# Export CSV (downloads file)
curl "https://bazaarlink.ai/api/orgs/{orgId}/reports/export?year=2026&month=3&view=by-team" \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY" \
  -o report.csv

エラーレスポンス対応表

401API key 無効または取り消し済み
403RBAC ブロック (呼び出し元のロール不足) または Allowed Models ホワイトリストに無いモデル
402月間予算、与信限度額、または利用可能残高が不足しています
429三層予算のいずれか超過、response body に scope (member / team / org) と reset time
503Spend Circuit Breaker トリップ、Retry-After header に復旧時間 (秒)

許可モデル (ホワイトリスト)

組織・チーム・個人メンバーが呼び出せるモデルを制限する。高コストモデルや未検証モデルのブロック、モデル標準の強制、チームを単一プロバイダーに限定する用途に有用。

動作の仕組み

  • 3 つの独立したレイヤー (組織・チーム・メンバー) がそれぞれ独自のリスト (DB 内では String[]) を保持する。
  • 3 レイヤーすべてが空の場合、全モデルが許可される (デフォルト動作)。
  • 1 つ以上のレイヤーが非空の場合、実効リストは非空レイヤーの積集合 — 制限のかかった全レイヤーで許可されたモデルのみ通過する。
  • 変更は数秒以内に反映される (60 秒の in-memory + 5 分の Redis キャッシュ。更新時に両方クリア)。

パターン形式

  • 完全一致 — 例: openai/gpt-4o (この厳密なモデルのみ)。
  • プロバイダーワイルドカード — 例: openai/* (openai/ プレフィックス配下の任意のモデル)。
  • 小文字のみ。1 リスト最大 200 件、1 件あたり最大 100 文字。

管理場所

Org Portal → Allowed Models。org_admin は組織 / チーム / メンバーのリストを編集可能。team_admin は自身のチームとその配下メンバーのみ編集可能。

ブロック時のエラーレスポンス

許可されていないモデルへの呼び出しは HTTP 403 と以下の body を返す:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": {
    "message": "Model is not allowed for this account",
    "code": "model_not_allowed"
  }
}

管理 API

全エンドポイントは Web Session または Bearer Management Key (sk-bl-...) を受け付ける。PATCH はリスト全体を置換する。クリアするには [] を渡す。

# Org-level list
GET    /api/orgs/:orgId/allowed-models
PATCH  /api/orgs/:orgId/allowed-models

# Team-level list
GET    /api/orgs/:orgId/teams/:teamId/allowed-models
PATCH  /api/orgs/:orgId/teams/:teamId/allowed-models

# Member-level list
GET    /api/orgs/:orgId/members/:memberId/allowed-models
PATCH  /api/orgs/:orgId/members/:memberId/allowed-models

# Example: restrict an org to OpenAI + a specific Anthropic model
curl -X PATCH https://bazaarlink.ai/api/orgs/$ORG_ID/allowed-models \
  -H "Authorization: Bearer sk-bl-..." \
  -H "Content-Type: application/json" \
  -d '{"allowedModels": ["openai/*", "anthropic/claude-sonnet-4.6"]}'

サーキットブレーカー (Spend Kill Switch)

Upstream コストが急増した際に後続リクエストをブロックする、デュアルウィンドウ方式の消費上限。暴走スクリプト、無限ループ、漏洩キーの不正利用が実損になる前に封じ込める設計。

動作の仕組み

  • スコープごとに 2 つの固定ウィンドウ (1 分 / 1 時間の upstream コスト USD) を Redis で追跡。
  • いずれかのウィンドウがしきい値に達すると、当該スコープの後続リクエストはウィンドウがリセットされるまで全て拒否される。
  • デフォルト: $5 / 分、$20 / 時間、デフォルトで有効。
  • カウンタは TTL 付きで Redis に保持される — 復旧は自動で、組織 / チーム / メンバーのトリップに手動リセットは不要。

スコープ (member > team > org の順で上書き)

各レイヤーは独自のしきい値を設定できる。解決順序は member → team → org → プラットフォームデフォルト — フィールドごとに最初の non-null 値が採用される (cbEnabled / cbMinuteUsd / cbHourlyUsd)。

  • Org レベル — 組織配下の全キーに適用。Org Portal → Circuit Breaker で設定。
  • Team レベル — そのチームにタグ付けされた全キーに適用。当該キーに対して org を上書きする。
  • Member レベル — そのメンバーにタグ付けされたキーのみに適用。team と org を上書きする。

トリップ時の挙動

トリップ中はリクエストが fail fast (upstream は呼び出されない)。レスポンスは HTTP 429 と以下の body:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": {
    "message": "Spend circuit breaker tripped at member scope (minute window: $5.2341 ≥ $5.00). Try again later or contact your organization owner."
  }
}
グローバル vs スコープ別
別途、グローバルなプラットフォーム全体のサーキットブレーカー (オペレーター制御、Org Portal からは不可視) が存在し、Retry-After header 付きの HTTP 503 を返す。マルチテナント不正利用からプラットフォームを守るためにオペレーターが設定するもので、Org 設定からは上書きできない。

監査ログ

全てのトリップイベントと全ての設定変更が記録される:

  • トリップイベント — action は org.cb.tripped / team.cb.tripped / org_member.cb.tripped。スコープ + ウィンドウごとに 1 時間 1 件に重複排除されるため、継続トリップでログが氾濫しない。
  • 設定変更 — action は org.cb.update / team.cb.update / org_member.cb.update。変更前後の値と実行者を記録する。

管理 API

Org admin は API 経由で設定の取得 / 更新が可能。全エンドポイントは Web Session または Bearer Management Key (sk-bl-...) を受け付ける。PATCH の body には任意のサブセットを送ればよく、null を渡すとそのフィールドはクリアされ親レイヤーにフォールバックする。

# Org-level config
GET    /api/orgs/:orgId/circuit-breaker
PATCH  /api/orgs/:orgId/circuit-breaker

# Team-level config
GET    /api/orgs/:orgId/teams/:teamId/circuit-breaker
PATCH  /api/orgs/:orgId/teams/:teamId/circuit-breaker

# Member-level config
GET    /api/orgs/:orgId/members/:memberId/circuit-breaker
PATCH  /api/orgs/:orgId/members/:memberId/circuit-breaker

# Example: tighten the org-level cap to $2/min, $10/hr
curl -X PATCH https://bazaarlink.ai/api/orgs/$ORG_ID/circuit-breaker \
  -H "Authorization: Bearer sk-bl-..." \
  -H "Content-Type: application/json" \
  -d '{"cbMinuteUsd": 2, "cbHourlyUsd": 10, "cbEnabled": true}'

# GET response (org scope)
{
  "settings":         { "cbEnabled": true, "cbMinuteUsd": 2,  "cbHourlyUsd": 10  },
  "resolvedSettings": { "cbEnabled": true, "cbMinuteUsd": 2,  "cbHourlyUsd": 10  },
  "liveSpend":        { "minuteSpend": 0.4123, "hourSpend": 3.8721 }
}

APIキーローテーション

APIキーの定期的なローテーションはセキュリティのベストプラクティスです。BazaarLinkはダウンタイムゼロのキーローテーションをサポート — 新しいキーを先に作成し、移行してから古いキーを取り消します。

注意
APIキーはダッシュボードまたは管理APIからいつでも取り消せます。取り消しは即時 — そのキーを使用するすべてのリクエストが即座に失敗します。

ローテーション手順

  1. 新しいAPIキーを作成
  2. アプリケーションまたは環境変数を新しいキーに更新
  3. 新しいキーが正常に動作していることを確認
  4. 古いキーを無効化または削除
# Key CRUD via Bearer auth requires a MANAGEMENT key (keyType: "management").
# Standard keys get 403 on /api/v1/keys — create a management key first,
# or rotate keys from the dashboard UI instead.

# Step 1: Create new key (management key auth)
POST https://bazaarlink.ai/api/v1/keys
Authorization: Bearer $BL_MANAGEMENT_KEY
{"name": "Production v2"}
# → saves new key: sk-bl-NEW_KEY_VALUE

# Step 2: Update your application
# export BAZAARLINK_API_KEY=sk-bl-NEW_KEY_VALUE

# Step 3: Verify new key works
curl https://bazaarlink.ai/api/v1/models \
  -H "Authorization: Bearer sk-bl-NEW_KEY_VALUE"

# Step 4: Revoke old key (management key auth again)
DELETE https://bazaarlink.ai/api/v1/keys/:old_key_id
Authorization: Bearer $BL_MANAGEMENT_KEY

アクティビティエクスポート

財務監査、コスト分析、コンプライアンスレポート用に、完全なAPI使用履歴をCSVでダウンロード。

CSVエクスポート

ログインしてログページに移動。右上のCSVエクスポートボタンをクリックして、完全な履歴をCSVファイルとしてダウンロード。API呼び出しは不要です。

CSVカラム

Column
Description
dateISO 8601 timestamp (UTC)
modelModel ID (e.g. openai/gpt-4o)
providerUpstream provider name
prompt_tokensInput token count
completion_tokensOutput token count
total_tokensTotal tokens (prompt + completion)
reasoning_tokensReasoning tokens (o-series / thinking models)
cached_tokensPrompt cache hit tokens
cost_usdCost in USD credits
duration_msEnd-to-end latency in milliseconds
finish_reasonstop / length / content_filter / error
statusHTTP status code from upstream
app_nameX-Title header value (app attribution)

JSON使用量API

プログラマティックアクセスには、期間、モデル、キー別にグループ化された集計統計を照会:

# Query usage data (grouped / aggregated)
GET https://bazaarlink.ai/api/v1/usage
Authorization: Bearer sk-bl-YOUR_KEY

# With period filtering (day | week | month | year)
GET https://bazaarlink.ai/api/v1/usage?period=month

# Response
{
  "period": "month",
  "since": "2025-01-01T00:00:00.000Z",
  "credits": 10.5000,
  "totals": {
    "spend": 0.1812,
    "requests": 309,
    "tokens": 161200,
    "promptTokens": 95000,
    "completionTokens": 66200
  },
  "byModel": [{ "model": "openai/gpt-4o", "spend": 0.0028, "tokens": 1200, "requests": 5 }],
  "byKey":   [{ "keyName": "My Agent", "spend": 0.0028, "tokens": 1200, "requests": 5 }],
  "byApp":   [{ "appName": "MyApp", "spend": 0.0015, "tokens": 600, "requests": 3 }],
  "timeSeries": [{ "date": "2025-01-15", "model": "openai/gpt-4o", "cost": 0.0012, "tokens": 500, "requests": 2 }]
}

使用量会計

トークン消費量、コスト分析、リクエスト履歴を含む詳細な使用統計をAPIで照会。

注意
使用量データは米ドルで課金されます。個々のリクエスト記録はログページまたはCSVエクスポートで確認できます。集計統計(期間、モデル、キー別)は`/api/v1/usage`エンドポイントでBearerトークン認証で利用可能です。

レスポンスフィールドリファレンス

FieldTypeDescription
modelstringModel ID used (e.g., openai/gpt-4o)
providerstringUpstream provider name
prompt_tokensnumberInput tokens consumed
completion_tokensnumberOutput tokens generated
total_tokensnumberTotal tokens (prompt + completion)
reasoning_tokensnumberReasoning tokens (for thinking models)
cached_tokensnumberPrompt tokens served from cache
costnumberTotal cost in USD credits
duration_msnumberEnd-to-end latency in milliseconds
throughputnumberGeneration speed in tokens/sec
finish_reasonstringstop | length | content_filter | error
statusnumberHTTP status code from upstream
app_namestring | nullApplication name (X-Title header)
key_namestringAPI key name used for the request
import httpx

# Aggregated stats (Bearer token — period: day | week | month | year)
response = httpx.get(
    "https://bazaarlink.ai/api/v1/usage",
    headers={"Authorization": "Bearer sk-bl-YOUR_KEY"},
    params={"period": "month"},
)

data = response.json()
totals = data["totals"]
print("This month: US$%.4f  (%d requests)" % (totals["spend"], totals["requests"]))

# Cost breakdown by model
for m in data["byModel"]:
    print("  %s: US$%.4f  (%d reqs, %d tokens)" % (m["model"], m["spend"], m["requests"], m["tokens"]))

Institution プラン (機構臨時方案)

Institution プランでは、あらゆる機関(学校、企業、カンファレンス、政府機関など)が組織レベルの 1 つのキーから所属メンバーに短命のセッショントークンを発行できる。メンバーがプラットフォームのアカウントを作成する必要はない。組織はメールドメイン(例:nthu.edu.tw)でトークン発行可能なメンバーを制御し、すべての利用は組織アカウントに課金される。本ページは教育シナリオを例として説明していますが、同じ仕組みは短期間・複数ユーザーの一時アクセスを必要とするあらゆる機関に適用できる。

対象ユーザー
個別の学生アカウントを作成せず、長命の API キーを未成年に渡すことなく、クラス全体に AI API へのアクセスを提供したい学校や教育機関向け。

アーキテクチャ概要

  • 機関 Keysk-edu- で始まる。組織のキーページで org_admin が作成する。Bearer トークンとして API を直接呼び出すことはできない — 直接呼び出しは 403 を返す。
  • Member Session Tokenedu-sess- で始まる。学生がメール認証後に取得する。デフォルト有効期限は 24 時間で、組織管理者が取り消せる。
  • Allowed Domainsセッションをリクエストできるメールドメインを組織が設定する(完全一致、サフィックスバイパス不可)。
  • Usage attribution学生のすべてのリクエストは組織アカウントに課金される。利用状況は組織ダッシュボードでセッションごと・メールごとに確認できる。

ステップ 1 — プラットフォーム管理者が組織タイプを Education に設定

sales@bazaarlink.ai / support@bazaarlink.ai から対象の組織を見つけ、「Org Type」タブに切り替えて Education を選択し、許可するメールドメインを設定する:

{
  "orgType": "education",
  "eduConfig": {
    "allowedDomains": ["nthu.edu.tw", "student.nthu.edu.tw"],
    "sessionTtlSeconds": 86400,
    "verificationTtlSeconds": 900,
    "maxSessionsPerEmailPerKey": 5
  }
}
ドメインマッチングは完全一致
nthu.edu.tw は @nthu.edu.tw のみにマッチする — @nthu.edu.attacker.com にはマッチしない。サブドメインは明示的にリストする必要がある(例:student.nthu.edu.tw)。

ステップ 2 — 組織管理者が 機関 Key を作成

組織の API Keys ページで、新しいキーを作成する際にキータイプとして「Education」を選択する。システムは sk-edu-... キーを生成し、一度だけ表示する — 保存して、その組織の学生に公式チャネル経由で配布する。

ステップ 3 — 学生が認証コードをリクエスト

学生は /access に行き edu キー + 学校のメールアドレスを入力する。または直接 API を呼び出す:

POST/api/edu/request-code
curl -X POST https://bazaarlink.ai/api/edu/request-code \
  -H "Content-Type: application/json" \
  -d '{
    "key": "sk-edu-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "email": "alice@nthu.edu.tw"
  }'

# Success (incl. unknown key/email — enumeration defence) → {"ok":true,"sent":true}
# Rate limit / resend cooldown → 429 {"error":"rate_limited"} or {"error":"cooldown"}
# Sends a 6-digit verification code to the email; default 15-minute lifetime
列挙対策
request-code はキーが存在するか、メールドメインが許可されているかに関わらず常に 202 を返し、攻撃者がどの edu キーが存在するかを探ることを防ぐ。失敗した試行は組織監査ログに記録される。

ステップ 4 — 学生がコードを送信してセッショントークンと交換

POST/api/edu/verify
curl -X POST https://bazaarlink.ai/api/edu/verify \
  -H "Content-Type: application/json" \
  -d '{
    "key":   "sk-edu-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "email": "alice@nthu.edu.tw",
    "code":  "646291"
  }'

# Success → 200
{
  "token":     "edu-sess-827d11a1ec67d175cfd4f67f929261f4",
  "expiresAt": "2026-05-04T11:16:00.163Z",
  "organization": { "id": "...", "name": "NTHU AI Lab" }
}

# Wrong code → 400 {"error":"invalid"}
# 5 wrong attempts → 429 {"error":"too_many_attempts"} (code invalidated; re-request)

ステップ 5 — セッショントークンで API を呼び出す

edu-sess-... トークンを Bearer トークンとして、任意の chat / completions / embeddings エンドポイントに対して使用する:

curl -X POST https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer edu-sess-827d11a1ec67d175cfd4f67f929261f4" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-haiku-4.5",
    "messages": [{"role": "user", "content": "Hello"}]
  }'
sk-edu- キーは直接使用できない
sk-edu-... を Bearer トークンとして chat エンドポイントに直接送信すると次が返る:
403 — Education keys cannot be used directly. Visit /access to exchange for a session.
これは意図的な逆ゲートであり、学校が長命のキーを個々の学生に漏らすことを防ぐ。

組織ダッシュボード — モニタリングと取り消し

Education タイプの組織はサイドナビに Education タブが表示され、次の機能を提供する:

  • Settings許可ドメイン、TTL、キーごと・メールごとの最大セッション数、セッションごとのリクエスト / トークン / USD クォータを調整する。
  • Sessionsアクティブ / 期限切れ / 取り消し済みのすべてのセッションをリスト表示。メールでフィルタ可能。個別セッションを取り消せる。
  • Usage statsセッションごとの呼び出し回数、トークン消費量、累積コスト。

セキュリティと制限

項目デフォルト説明
Session TTL24 時間セッショントークンの有効期限。期限切れのセッションは再認証が必要。
認証コード TTL15 分メール認証コードの有効期限。
認証コード長6 桁Redis に HMAC-SHA256 ハッシュとして保存。平文では保存しない。
推測回数制限5 回これを超えるとコードは即座に無効化される。
request-code クールダウン60 秒同じ (key, email) に対する繰り返しリクエストの最小間隔。
IP ごとのレート制限10 / 15 分スパム対策。
キーごとのレート制限100 / 時間大量メール送信を防ぐ。
メールごとの最大セッション数5eduConfig で設定可能。1 つのメールアドレスがトークンを抱え込むのを防ぐ。
取り消しの伝播≤ 60 秒L1/L2 キャッシュ TTL。DB での取り消し後、すべてのノードに伝播するまで最大 60 秒かかる。

課金と利用帰属

セッショントークン経由のすべてのリクエストは、edu キーを所有する組織に 100% 課金される。これは上流プロバイダ(OpenAI / Anthropic 等)の課金方式(トークン単位)に沿ったもの。組織ダッシュボードはセッション別、メール別、キー別のドリルダウンに対応する。

フィードバック報告

問題、バグ、提案を報告してBazaarLinkの改善にご協力ください。すべてのフィードバックチャネルを積極的に監視しています。

報告方法

チャネル
最適な用途
応答時間
お問い合わせページ一般的なフィードバック、機能リクエスト1〜2営業日
メールバグ報告、技術的な問題24時間以内
APIレスポンスヘッダー自動報告されるエラーとメトリクス自動

含めるべき情報

  • リクエストID(レスポンスのidフィールドから)
  • 使用したモデルと送信したパラメータ
  • 期待される動作と実際の動作
  • タイムスタンプと問題の発生頻度
  • エラーメッセージまたはHTTPステータスコード

お問い合わせページにアクセスしてフィードバックを送信してください。

FAQ

BazaarLinkはOpenAIに直接アクセスするのとどう違いますか?
BazaarLinkは米ドル請求と台湾ドル建て価格、統一発票、中国語サポート、主要モデルへの単一APIを提供します。同じコードでOpenAI、Anthropic、Googleなどにアクセスできます。
既存のコードを変更する必要がありますか?
ベースURLとAPIキーを変更するだけです。他のすべての設定(モデルIDを除く)は変更不要です。
BazaarLinkはメッセージを保存しますか?
デフォルトではメッセージ内容は保存しません。課金目的でトークン数とタイムスタンプのみを記録します。
統一発票(統一發票)を取得するには?
統一発票はビジネスプラン以上で月末に自動発行されます。即時発行についてはサポートにお問い合わせください。
対応している支払い方法は?
主要なクレジットカード(Visa、Mastercard、American Express)に対応しています。
どのOpenAI SDK機能がサポートされていますか?
チャットコンプリーション、ストリーミング、ツールコール、構造化出力(response_format)、アシスタントプリフィルがすべて動作します。機能はアップストリームプロバイダーに転送されます。
LangChainやCrewAIなどのエージェントフレームワークでBazaarLinkを使用できますか?
はい!OpenAI APIをサポートするフレームワークはBazaarLinkで動作します。ベースURLを設定し、BazaarLink APIキーを使用するだけです。例についてはエージェント利用セクションをご覧ください。
サポート
サポート
こんにちは。どのようなご用件でしょうか?
メッセージをお送りください。担当者より返信します。