BazaarLinkBazaarLink
Войти
ДокументацияAPI СсылкаSDK СсылкаАгентное использованиеAI Навыки

BazaarLink Документация

BazaarLink — это унифицированный шлюз AI API для Тайваня, обеспечивающий доступ к сотням моделей из OpenAI, Anthropic, Google, Meta и других через единый OpenAI-совместимый шлюз. конечная точка API.

AI Файл навыков агента
Загрузите наш файл навыков в своего ИИ-помощника (Claude, Cursor, Copilot…), чтобы дать ему полное знание BazaarLink API:
Read https://bazaarlink.ai/skill.md and follow the instructions to integrate BazaarLink into your app.
Бесплатные модели и ограничения скорости
Ищете информацию о бесплатных моделях, ограничениях на поминутные запросы и бесплатных кредитах? Видеть Ограничения ставок · FAQ

Цены

BazaarLink использует модель цен с нулевой наценкой (идентичной официальной прейскурантной цене каждого поставщика). Комиссия за платформу взимается при пополнении счета (депозите): комиссия за транзакцию 10% плюс 5% Тайвань VAT на каналах TWD. Счет выставляется в формате USD с расценками TWD и едиными электронными счетами. Пополнение баланса с оплатой по мере использования; предприятия могут организовать ежемесячную оплату (Net-30, по договоренности).

Как это работает

  • Потребление (дебет): каждый вызов API оплачивается на основе фактического использования токенов по официальной прейскурантной цене USD провайдера, вычитаемой из вашего баланса — нулевая наценка, никакой дополнительной платы за потребление.
  • Пополнение (депозит): TWD конвертируется в USD по курсу продажи в реальном времени и добавляется к вашему балансу; При пополнении взимается комиссия за транзакцию 10%.
  • • Способы оплаты и комиссии конкретного канала показаны на актуальной странице оплаты.
  • • Для подходящих каналов TWD применимые налоги и условия тайваньского электронного инвойса показываются до оплаты.
  • • Банковский перевод: для крупных или корпоративных пополнений свяжитесь с нами, чтобы организовать банковский перевод и индивидуальное выставление счета.
  • Инвойс доступен только через фактически предлагаемый подходящий канал либо по подтверждённым корпоративным условиям. Если нужны налоговый номер, предложение или ежемесячный расчёт, свяжитесь с отделом продаж до оплаты.
Пример
При покупке баланса US$10.00 актуальная страница оплаты до подтверждения показывает доступные способы, итоговую сумму, комиссии или налоги и право на квитанцию либо инвойс. Затем баланс расходуется по официальным ценам без наценки на модель.

О курсе валют

При конвертации иностранной валюты используется курс реального времени; при ежемесячном выставлении счетов используется ставка на момент выставления счета (выписки), а при предоплаченных пополнениях конвертируется по ставке на момент пополнения счета. Тариф и временная метка сохраняются в записях о выставлении счетов.

Защита от выставления счетов при сбое запроса

Если восходящий запрос завершается неудачей без оплачиваемого использования, BazaarLink автоматически возвращает всю зарезервированную сумму. Вы платите 0 долларов за эту попытку, даже если трансляция уже началась до того, как она потерпела неудачу.

Когда с вас не взимается плата
Настройка не требуется. Это правило включается автоматически для общедоступных выводов и API мультимедиа. BazaarLink может поглотить стоимость, уже взимаемую вышестоящим провайдером, вместо того, чтобы перекладывать на вас стоимость неудачного запроса.
  • Восходящий канал не может подключиться, отклоняет запрос или не возвращает пригодный для использования ответ.
  • A поток останавливается до получения окончательной записи об использовании, даже после частичного содержимого.
  • Ответ не содержит данных об использовании или содержит только пустой объект использования с нулевым значением. Вывод токенов

0 не всегда означает бесплатность

usage.cost — сумма в USD, списанная за запрос. Даже при 0 выходных токенов могут оплачиваться входные токены; проверьте usage.cost или запись Activity для итоговой суммы.

Быстрый старт

Три способа интеграции

Подход
Подходит для
Старт
Сырой APIЛюбой язык, нулевые зависимости, полный контроль запросов→
OpenAI / Anthropic SDKУже на официальном SDK — поменять базу URL и только ключ→
Агентные платформыLangChain, Vercel AI SDK, CrewAI и другие приложения-агенты→
Все запросы автоматически проверяются перед отправкой модели; запросы, нарушающие нашу политику использования, отклоняются и возвращают ошибку 403.

Начните работу менее чем за 5 минут. BazaarLink полностью совместим с OpenAI SDK — просто измените

Для запросов длительностью более 100 секунд рекомендуется использовать stream:true. Для нестриминговых запросов примерно через 12 секунд (значение по умолчанию, которое можно изменить в настройках развёртывания) сначала возвращается 200 и начинается отправка пробелов keepalive; если позже возникает ошибка, она возвращается как 200 + error JSON. Keepalive — это пробелы перед JSON-телом, которые стандартные JSON-парсеры игнорируют.

База URL

https://api.bazaarlink.ai/v1

api.bazaarlink.ai — это точка входа только для API, развёртываемая отдельно от сайта. Прежний базовый URL https://bazaarlink.ai/api/v1 по-прежнему полностью поддерживается — существующие интеграции менять не нужно.

Использование OpenAI SDK

BazaarLink полностью совместим с OpenAI SDK. Просто измените базовый ключ URL и API — весь остальной код останется прежним.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.bazaarlink.ai/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-.
Вызов прямо из браузера (CORS)
Публичный API отвечает на каждый запрос /v1 с заголовком Access-Control-Allow-Origin: *, поэтому его можно вызывать прямо из браузерного JavaScript через fetch или OpenAI SDK. Никогда не встраивайте API-ключ во фронтенд-код — его увидит любой, кто откроет страницу; используйте отзываемый ключ с лимитом расходов или проксируйте вызов через собственный бэкенд.
Формат идентификатора модели — используйте provider/model-name
GET /v1/models перечисляет id, например "claude-sonnet-4.6", и канонические alias, например "anthropic/claude-sonnet-4.6". Запросы принимают обе формы.
✓ claude-sonnet-4.6   anthropic/claude-sonnet-4.6

Принесите свой ключ (BYOK)

Подключите upstream API-ключ к личной учётной записи или организации. Подходящие запросы сначала используют ваш ключ. После ошибки upstream запрос может попробовать другой доступный источник; если его нет, запрос вернёт ошибку. Личными ключами управляйте на странице ключей, ключами организации — в её настройках. Перейти в настройки BYOK →

Контентная фильтрация

Двусторонняя защита содержимого вашего трафика API: запросы, содержащие попытки внедрения подсказок, блокируются (400), а конфиденциальные данные в подсказках или ответах (ключи API, номера карт, национальные идентификаторы и т. д.) автоматически удаляются. Правила и список исключений настраиваются, включая статистику использования. Перейти к настройкам фильтра контента →

Данные соцсетей (:social)

Добавьте :social к имени модели, если вопрос касается социальной платформы. Перед ответом модели BazaarLink получает подходящие публикации, профили или комментарии с этой платформы и передаёт их как справочный материал. Если данные платформы не удалось получить вовремя, запрос переключается на обычный веб-поиск, поэтому ответ вы получите в любом случае.

Пример

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  --max-time 60 \
  -d '{
    "model": "gpt-5.4-mini:social",
    "messages": [{ "role": "user", "content": "Последние посты в X о GPT-6" }]
  }'

Что важно знать

  • Время ожидания: данные соцсетей запрашиваются в реальном времени, поэтому запрос с :social может занимать от 20 до 40 секунд до начала ответа. По истечении 40 секунд происходит переключение на веб-поиск. Установите тайм-аут клиента не менее 60 секунд. :online остаётся быстрым, так как это обычный веб-поиск.
  • Цена: запросы, на которые отвечено данными соцсетей, используют тот же ежедневный бесплатный лимит поиска, что и :online (5 в сутки без баланса, 10 при наличии баланса или подписки; сброс в 00:00 UTC). Сверх лимита каждый запрос тарифицируется по прайс-листу Data API (см. GET /v1/data/catalog) дополнительно к оплате токенов самой модели. Запрос, переключённый на веб-поиск, тарифицируется как :online.
  • Охват: :social читает лишь часть соцсетей, список зависит от включённых настроек; актуальный список на /solutions/data-api#social-suffix. Платформа, которая есть в каталоге Data API, но не в этом списке, не читается через :social, поэтому запрос о ней или без указания платформы обрабатывается веб-поиском.
  • Совместимость: работает с POST /api/v1/chat/completions, /api/v1/messages и /api/v1/responses, в потоковом (streaming) и обычном режимах, с теми же ссылками на источники, что и :online. :online и :social нельзя сочетать в одном имени модели (400 invalid_web_search_options).

Миграция с OpenRouter

API API совместим с OpenRouter — большинство интеграций переключаются путем изменения двух значений: базового URL на https://api.bazaarlink.ai/v1 и ключа API на a. Ключ BazaarLink, начинающийся с sk-bl-.

  1. База URL: https://openrouter.ai/api/v1 → https://api.bazaarlink.ai/v1
  2. API ключ: sk-or-... → sk-bl-... (создайте его по адресу /keys)
  3. Model ID: тот же формат provider/model (например, anthropic/claude-sonnet-4.6); полный каталог по адресу GET /v1/models. Резервные варианты
  4. models[], потоковая передача, вызов инструментов и структурированные выходные данные используют одну и ту же форму запроса.
  from openai import OpenAI

  client = OpenAI(
-     base_url="https://openrouter.ai/api/v1",
-     api_key="sk-or-...",
+     base_url="https://api.bazaarlink.ai/v1",
+     api_key="sk-bl-...",
  )
Note
Расчеты ведутся в USD, доступны электронные счета Тайваня. Специфичные для upstream средства маршрутизации, например :nitro, игнорируются. Поддерживаемые BazaarLink параметры маршрутизации описаны в справочнике API.

Аутентификация

Для всех запросов API требуется заголовок авторизации с вашим ключом API.

Authorization: Bearer sk-bl-YOUR_API_KEY

Получите ключ API с сайта приборная панель. Храните свой ключ в безопасности — не раскрывайте его в клиентском коде.

Примечание по безопасности
Никогда не раскрывайте ключи API на стороне клиента JavaScript. Всегда прокси-запросы через ваш внутренний сервер.

Дополнительные заголовки

HTTP-Referer
string
Ваш сайт URL, для отслеживания использования и анализа (необязательно)
X-Title
string
Название вашего приложения, отображаемое на информационных панелях (необязательно)

Принципы

BazaarLink разработан на основе трех основных принципов:

1. Единый интерфейс

Один API, один SDK, сотни моделей. Переключайтесь между OpenAI, Anthropic, Google Gemini, Meta Llama и другими, не меняя код — просто измените идентификатор модели.

2. Оптимизация цен

BazaarLink автоматически направляет к наиболее экономичному поставщику для выбранной вами модели. Вы платите только за то, что используете, счет выставляется в формате USD с полной поддержкой выставления счетов.

3. Обработка запросов

При проблеме с upstream-источником запрос может попробовать другой доступный источник. Если доступных источников нет, запрос вернёт ошибку.

Мультимодальный

BazaarLink поддерживает мультимодальные входы — отправляйте изображения, аудио и файлы вместе с текстом в модели, которые их поддерживают. Контент передается вышестоящему провайдеру.

Поддерживаемые методы

Ввод
Описание
Примеры моделей
ТекстСтандартные текстовые сообщенияВсе модели
ИзображенияURL или данные base64 URI — PNG, JPEG, WebP, GIFopenai/gpt-6-lunaanthropic/claude-sonnet-4.6google/gemini-4-argon+98 читать далее
Файлы / PDF-файлыДокумент через данные base64 URI (`data:application/pdf;base64,...`)openai/gpt-6-lunaanthropic/claude-sonnet-4.6google/gemini-4-argon+41 читать далее
АудиоRaw base64 — нет поддержки URL. Требуется поле `format`.google/gemini-4-argonelevenlabs/scribe-v2google/gemini-3.1-flash-lite-preview+15 читать далее
ВидеоURL (CDN) или данные base64 URIgoogle/gemini-4-argonqwen/qwen3.8-maxminimax/minimax-m3+39 читать далее

Примеры:

# Image — URL or base64 data URI
curl https://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-3.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://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-3.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://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-3.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://api.bazaarlink.ai/v1/chat/completions \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"google/gemini-3.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 (включая анимированные). Вы можете включить несколько изображений в одно сообщение — каждое как отдельную часть image_url:

curl https://api.bazaarlink.ai/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"}}
    ]}]
  }'
Отправка изображений
Всегда добавляйте текстовую часть рядом с изображениями. Для лучшей совместимости со всеми поставщиками рекомендуется упорядочивать текст сначала (текстовая часть перед частями изображения).
Отправка изображений
Проверьте страницу «Модели», чтобы узнать, какие методы ввода поддерживаются каждой моделью. Столбец модальности показывает, какие входные данные принимает каждая модель.

Ограничения

BazaarLink применяет два независимых ограничения: ограничение скорости запросов в минуту и кредитный лимит на расходы по счету. Превышение ограничения скорости возвращает HTTP 429; исчерпание кредитов возвращает HTTP 402.

Ограничения ставок

Ограничения скорости указаны для каждого пользователя (а не для каждого ключа) и измеряются в запросах в минуту (RPM). Дневного лимита нет. Уровень определяется автоматически в зависимости от кредитного баланса вашего аккаунта.

Уровень
RPM
Ежедневное использование
Примечания
Бесплатно (< кредитов $5)20 RPMБез ограниченийРазработка и тестирование
Оплачено (≥ кредитов в размере $5)200 RPMБез ограниченийПроизводственные нагрузки

При превышении ограничения скорости вы получаете ответ 429 с заголовком Retry-After. Реализуйте экспоненциальную отсрочку при повторных запросах.

Заголовки ответов

Ответы могут содержать x-request-id; x-generation-id в нестриминговых ответах; x-ratelimit-*; retry-after при необходимости; и x-auto-resolved-model при маршрутизации auto или auto:free.

x-request-id: 85e6f35c71a31f19-SJC
x-generation-id: 85e6f35c71a31f19-SJC
x-ratelimit-limit: 200
x-ratelimit-remaining: 198
x-ratelimit-reset: 1740000060
retry-after: 5
x-auto-resolved-model: openai/gpt-4o

Кредитные лимиты Ответ

A 402 означает, что баланс вашего счета или ограничение расходов ключа достигло нуля — это не значит, что вы отправляете запросы слишком быстро. Эти ответы не содержат заголовков ограничения скорости, и если ограничение будет достигнуто в середине потока, вы получите событие ошибки SSE вместо изменения статуса HTTP.

402 Недостаточно кредитов
Когда ваш баланс достигает 0 долларов США, API возвращает HTTP 402 с сообщением «Недостаточно кредитов. Пополните счет, чтобы продолжить». — отслеживайте использование.стоимость в ответах, чтобы отслеживать расходы в режиме реального времени.

Список разрешённых IP

Для каждого API-ключа можно задать отдельный список разрешённых IP, чтобы использовать этот ключ могли только запросы с указанных исходных IP.

Когда это полезно

Это подходит для production-развёртываний на серверах с фиксированным исходящим IP. Если приложение отправляет запросы из домашней или мобильной сети либо с меняющегося адреса, сначала убедитесь, что исходящий IP стабилен, иначе вы можете сами заблокировать себе доступ.

Как настроить

Откройте /keys , откройте меню «⋯» нужного ключа, выберите «Список разрешённых IP», введите записи и сохраните.

Также можно использовать PATCH /api/v1/keys/:id с авторизованной сессией или Management API key:

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

{
  "allowedCidrs": [
    "203.0.113.7",
    "198.51.100.0/24"
  ]
}

# Clear the allowlist and return to unrestricted access
{"allowedCidrs": []}

Формат записей

В UI вводите одно значение в каждой строке. В API передавайте те же значения в массиве `allowedCidrs`. Поддерживаются обычный IPv4-адрес, IPv4 CIDR или IPv6 literal (только точное совпадение).

203.0.113.7
198.51.100.0/24
2001:db8::1

Поведение

Пустой список (отправленный как пустой массив []) означает отсутствие ограничений по исходному IP. Это значение по умолчанию, поэтому поведение существующих ключей не меняется.

Исходный IP берётся из заголовка `cf-connecting-ip`.

Если список не пуст, но исходный IP определить не удалось, запрос отклоняется (fail-closed).

⚠️ Важно: при отказе возвращается только общий 401
Запрос не из списка или запрос, для которого нельзя определить исходный IP, получает в точности тот же общий HTTP 401, что и при недействительном ключе; отдельного сообщения об ошибке нет. Это намеренный дизайн безопасности, чтобы получивший ключ злоумышленник не узнал о существовании списка. Обратная сторона — неверная настройка выглядит точно как недействительный ключ и крайне сложна для отладки. Перед сохранением убедитесь, что исходящий IP вашего сервера уже есть в списке.
⚠️ Важно: IPv6 поддерживает только точное сравнение строк
Для IPv6 вычисление подсетей не выполняется: строка адреса должна полностью совпадать. Если IPv6-адрес меняется, вы можете потерять доступ. Диапазоны CIDR /0–/32 поддерживаются только для IPv4.
Когда изменения вступают в силу
После успешного PATCH или сохранения в UI экземпляр, выполнивший обновление, немедленно очищает свой кэш. В обычных условиях другие экземпляры синхронизируются примерно в течение 15 секунд. Если общий Redis временно недоступен, межэкземплярная инвалидация не распространяется сразу и может задержаться до TTL кэша в один час.

個人緊急煞車

針對您所有 API 金鑰套用的固定 1 分鐘 / 1 小時 USD 支出上限。當時間窗口的門檻被觸及時,新的請求將收到 HTTP 429;窗口於整點邊界自動重置。

cbEnabled
boolean
啟用
cbMinuteUsd
number | null
每分鐘 USD 上限 · 使用預設值
cbHourlyUsd
number | null
每小時 USD 上限 · 使用預設值
(繼承預設值)
數值至少為 0.01(或留空使用預設值)
個人緊急煞車 · 調整 →

Безопасность аккаунта

Помимо пароля, BazaarLink также поддерживает двухэтапную проверку для дополнительной защиты при входе.

Включить двухэтапную проверку (TOTP)

  1. Откройте страницу «Настройки», найдите раздел «Двухэтапная проверка (TOTP)» и нажмите «Включить двухэтапную проверку».
  2. Отсканируйте QR-код на экране приложением-аутентификатором (например, Google Authenticator) или введите секрет, показанный ниже, вручную.
  3. Введите 6-значный код, сгенерированный приложением-аутентификатором, и подтвердите — на этом включение завершится.

После включения система покажет 8 резервных кодов (показываются только один раз) — каждый длиной 10 символов и одноразовый. Сразу запишите или скопируйте их и сохраните в надёжном месте, отдельно от телефона; используйте резервный код для входа, если телефон утерян или приложение-аутентификатор недоступно.

Вход после включения
После этого при каждом входе, помимо пароля (или входа через Google), нужно будет ввести код из приложения-аутентификатора или один резервный код.

Другие способы защитить аккаунт

Сочетайте эти функции с двухэтапной проверкой, чтобы ещё больше ограничить ущерб от утечки или неправильного использования ключа:

  • Список разрешённых IP — ограничивает использование API-ключа только указанными исходными IP-адресами.
  • Персональный автоматический выключатель расходов — задаёт лимиты расходов в минуту и в час, которые автоматически приостанавливают запросы при превышении.
  • Лимит расходов по ключу — задаёт дневной, недельный или месячный лимит расходов при создании или обновлении API-ключа.

Генерация изображения

Создавайте изображения с помощью /v1/chat/дополнений с модальностями:["image"] или OpenAI DALL·E-совместимого /v1/images/generations.

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

Полный поток (потоковая передача, редактирование изображений, протокол SSE, список моделей) →

Создание видео

Async Трехэтапный процесс (отправка → опрос → контент). Создание видео занимает от 30 секунд до 5 минут.

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

Полный поток (опрос, загрузка, типы задач, предупреждения) →

PDF Входы

Отправляйте документы PDF непосредственно в сообщениях для моделей, которые изначально поддерживают ввод PDF (например, Claude, Gemini). BazaarLink перенаправляет файл прямо в модель — тарифицируется как обычные входные токены, без дополнительной оплаты или этапа обработки.

Поддерживаемые форматы

  • 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 или базовыми данными URI — URL более эффективен для общедоступного видео; base64 предназначен для локальных файлов или частного видео.

Поддерживаемые форматы

MP4 (H.264)MPEGMOVВебМ
response = client.chat.completions.create(
    model="google/gemini-3.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 →

OAuth PKCE

OAuth 2.0 PKCE (ключ подтверждения для обмена кодами) позволяет общедоступным клиентским приложениям (браузерным SPA, мобильным приложениям) совершать вызовы API от имени отдельных пользователей без хранения долговременного секретного секрета сервера на стороне клиента.

Когда использовать OAuth PKCE

  • Создание браузера SPA или мобильного приложения, требующего оплаты по количеству пользователей.
  • Мультиарендное SaaS — каждый конечный пользователь платит за свое использование API
  • Вы не можете хранить общий секретный ключ на стороне клиента (публичный клиент).
  • Вам нужен отдельный отзываемый ключ для каждого пользователя (он действует, пока пользователь его не отзовёт) вместо одного общего ключа API.

Что увидят ваши пользователи

Опишите эти шаги на своём экране входа:

  1. В вашем приложении они выбирают «Войти через BazaarLink» (или как вы назовёте кнопку).
  2. Браузер открывает страницу авторизации BazaarLink. Если они ещё не вошли, сначала входят и автоматически возвращаются на эту страницу.
  3. Страница показывает адрес вашего приложения и что произойдёт после разрешения: для приложения создаётся новый API-ключ, использование списывается с их баланса BazaarLink, а ключ можно отозвать в любой момент. Они могут назвать ключ и задать ежемесячный лимит расходов (оба необязательно).
  4. Они нажимают «Разрешить» и возвращаются в ваше приложение. Если нажимают «Отклонить», ключ не создаётся, ваше приложение не уведомляется, а пользователи видят страницу «Доступ отклонён».
  5. Чтобы позже отозвать доступ, они открывают страницу «API-ключи» (https://bazaarlink.ai/keys) и отключают или удаляют ключ, названный по вашему приложению.

Как это работает

Шаг 1. Начать аутентификацию — Сгенерируйте случайный code_verifier (длинную случайную строку) и его хэш SHA-256 в качестве code_challenge, затем перенаправьте пользователя на страницу аутентификации BazaarLink.

https://bazaarlink.ai/auth?callback_url=https://yourapp.com/callback&code_challenge=CODE_CHALLENGE&code_challenge_method=S256

Параметры URL авторизации

  • callback_url (обязателен) — куда пользователь возвращается после разрешения. Правила ниже.
  • code_challenge (обязателен) — SHA-256 от вашего code_verifier в кодировке base64url (43 символа, без заполнения).
  • code_challenge_method (обязателен) — должен быть S256.
  • state (необязателен) — ваше собственное непрозрачное CSRF-значение, от 1 до 256 печатных ASCII-символов. BazaarLink возвращает его без изменений как &state=… сразу после code. Некорректный state приводит к тому, что страница авторизации показывает "Недопустимый запрос авторизации".
  • key_label (необязателен) — до 100 символов. Предзаполняет название ключа на странице согласия (пользователь по-прежнему может его изменить). Слишком длинные или пустые метки игнорируются.
  • Headless tools (CLI / desktop, no callback_url) — omit callback_url. After the user allows, the page shows a one-time code (valid 5 minutes, single use) for them to enter into your tool; exchange it exactly like a redirected code. The page cannot show which app is asking, so tell users to enter the code only in a tool they started themselves.

Не поддерживается

  • workspace_id и required_workspace_id — не поддерживаются. Ключ всегда принадлежит собственному аккаунту пользователя.
  • code_challenge_method=plain — не поддерживается (только S256).

Правила для callback_url

  • Должен быть https://. http:// принимается только для localhost, 127.0.0.1 и [::1] (любой порт); тогда страница согласия показывает предупреждение о локальной разработке.
  • Без фрагмента (#), без имени пользователя и пароля в URL, не более 2048 символов.
  • Страница согласия показывает имя хоста вашего callback, чтобы пользователь видел, какое приложение запрашивает доступ.
  • После разрешения браузер направляется на ваш callback_url с добавленным code=… (и state=…, если вы его передали; существующая строка запроса сохраняется). Code действует 10 минут и работает один раз.

Шаг 2. Код обмена для ключа API — После того как пользователь авторизует запрос, BazaarLink перенаправляет на ваш callback_url с одноразовым code. Code действует 10 минут и может быть использован один раз; неверный code_verifier аннулирует его. Отправьте POST с code, code_verifier и code_challenge_method (обязательны все три), чтобы получить API-ключ пользователя.

curl https://bazaarlink.ai/api/v1/auth/keys \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<CODE_FROM_CALLBACK_URL>",
    "code_verifier": "<CODE_VERIFIER>",
    "code_challenge_method": "S256"
  }'

# Response
# { "key": "sk-bl-...", "user_id": "..." }

Шаг 3. Используйте ключ с пользовательской областью действия — Возвращённый ключ — обычный API-ключ BazaarLink, принадлежащий авторизовавшему пользователю: использование списывается с баланса этого пользователя, а не с вашего.

curl https://bazaarlink.ai/api/v1/chat/completions \
  -H "Authorization: Bearer sk-bl-..." \
  -H "Content-Type: application/json" \
  -d '{"model": "google/gemini-3.5-flash", "messages": [{"role": "user", "content": "Hello"}]}'

Пример на JavaScript (браузер)

// 1) Create a verifier + S256 challenge, then send the user to BazaarLink
const b64url = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)))
  .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const verifier = b64url(crypto.getRandomValues(new Uint8Array(32)));
const challenge = b64url(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)));
sessionStorage.setItem("bl_verifier", verifier);
// "state" is optional: BazaarLink hands it back unchanged next to the code.
const state = b64url(crypto.getRandomValues(new Uint8Array(16)));
sessionStorage.setItem("bl_state", state);
location.href =
  "https://bazaarlink.ai/auth?callback_url=" + encodeURIComponent(location.origin + "/callback") +
  "&code_challenge=" + challenge + "&code_challenge_method=S256&state=" + state;

// 2) On /callback: check your own state, then exchange the one-time code for a user key
const params = new URLSearchParams(location.search);
if (params.get("state") !== sessionStorage.getItem("bl_state")) throw new Error("state mismatch");
const res = await fetch("https://bazaarlink.ai/api/v1/auth/keys", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    code: params.get("code"),
    code_verifier: sessionStorage.getItem("bl_verifier"),
    code_challenge_method: "S256",
  }),
});
if (!res.ok) throw new Error((await res.json()).error?.message ?? "exchange failed"); // 403 invalid_code: ask the user to authorize again
const { key } = await res.json(); // use as: Authorization: Bearer <key>
Безопасность: только S256
Задайте для code_challenge_method значение S256 (хеш SHA-256). Поддерживается только S256: запросы с plain или без code_challenge_method отклоняются с HTTP 400.
Примечание
Если пользователь отклоняет запрос, BazaarLink не перенаправляет обратно на ваш callback_url и не уведомляет ваше приложение. Показывается только страница «Доступ отклонён», поэтому /auth не может стать открытым редиректом. Обрабатывайте состояние «не авторизовано» внутри приложения (например, по таймауту или кнопкой «повторить»).

Страница /auth и POST /api/v1/auth/keys обслуживаются с https://bazaarlink.ai (не с api.bazaarlink.ai). Полученный ключ работает с обоими базовыми URL: https://bazaarlink.ai/api/v1 и https://api.bazaarlink.ai/v1.

Если пользователь при авторизации задаёт лимит расходов, это месячный лимит; он сбрасывается в соответствии с месячным периодом аккаунта.

Ошибки

Ошибки имеют формат в стиле OpenAI {"error":{"message","type","code"}}. POST /api/v1/auth/keys может вернуть:

  • 400 invalid_code_challenge_method — code_challenge_method отсутствует, равен plain или отличается от S256.
  • 400 — некорректное JSON-тело либо отсутствует code / code_verifier.
  • 403 invalid_code — code неизвестен, просрочен или уже использован, code_verifier неверен, либо аккаунту больше не разрешён доступ. Во всех этих случаях намеренно возвращается одно и то же сообщение, чтобы вызывающая сторона не могла их различить. Неверный code_verifier также аннулирует code: попросите пользователя авторизоваться заново.
  • 429 rate_limited — более 30 попыток обмена за 10 минут с одного IP (см. заголовок Retry-After).
  • 429 key_total_cap — на аккаунте уже максимальное число API-ключей: 200.
  • 405 — принимается только POST.

Создание кода с вашего сервера (ключ управления)

Владелец личного ключа управления (Management Key) может создать код авторизации напрямую через POST /api/v1/auth/keys/code, не направляя пользователя на страницу в браузере (совместим с OpenRouter). Код привязан к владельцу ключа управления, поэтому ключ, который вы получите в обмен, — это стандартный ключ в аккаунте этого владельца с лимитом, периодом, сроком действия и именем, заданными здесь. Используйте, когда ваш собственный инструмент уже держит ключ управления и хочет передать приложению ограниченный ключ. Обмен (POST /api/v1/auth/keys) такой же, как выше.

  • callback_url (обязательно) и code_challenge + code_challenge_method=S256 (обязательно) — те же правила, что и для URL авторизации.
  • key_label (необязательно) — до 100 символов; имя ключа. По умолчанию: "App: <ваш callback-хост>".
  • limit (необязательно) — лимит расходов в USD, 0 или больше; 0 или отсутствие значения означает отсутствие лимита.
  • usage_limit_type (необязательно) — daily, weekly или monthly: как часто сбрасывается лимит. Используется только вместе с limit; по умолчанию monthly.
  • expires_at (необязательно) — когда истекает ключ: время ISO 8601 UTC в будущем с секундами, например 2026-12-31T23:59:59Z. Значения с точностью до минут отклоняются. Если не указано, ключ остаётся действительным, пока не будет отозван.
  • workspace_id — не поддерживается (400). spawn_agent и spawn_cloud принимаются и игнорируются.
curl https://bazaarlink.ai/api/v1/auth/keys/code \
  -H "Authorization: Bearer sk-bl-YOUR_MGMT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "callback_url": "https://yourapp.com/callback",
    "code_challenge": "<CODE_CHALLENGE>",
    "code_challenge_method": "S256",
    "key_label": "My app",
    "limit": 10,
    "usage_limit_type": "monthly",
    "expires_at": "2026-12-31T23:59:59Z"
  }'

# Response
# { "data": { "id": "<ONE_TIME_CODE>", "app_id": 123456789, "created_at": "2026-10-22T12:00:00.000Z" } }
# Then POST { "code": "<ONE_TIME_CODE>", "code_verifier": "<CODE_VERIFIER>", "code_challenge_method": "S256" } to /api/v1/auth/keys

Ответ: { "data": { "id", "app_id", "created_at" } }. id — одноразовый код для обмена (действует 10 минут, один раз). В BazaarLink нет реестра приложений, поэтому app_id — это стабильное целое число, выведенное из вашего callback-адреса: один и тот же адрес всегда получает один и тот же app_id.

  • 401 unauthorized — нет ключа Bearer или ключ неизвестен.
  • 403 management_key_required — ключ не является личным ключом управления (стандартные ключи и ключи управления организации отклоняются).
  • 403 account_not_allowed — владелец ключа заблокирован или удалён.
  • 400 — invalid_callback_url, invalid_code_challenge_method, invalid_code_challenge, invalid_expires_at, workspace_not_supported или некорректное тело запроса.
  • 429 rate_limited — более 30 кодов в час для одного владельца или 120 в час с одного IP (см. Retry-After).

Ключ, который вы получаете

  • Стандартный API-ключ BazaarLink (sk-bl-…), такого же типа, как ключ, созданный на странице «API-ключи». Действует, пока пользователь его не отзовёт.
  • Использование списывается с баланса BazaarLink пользователя. Если пользователь задал лимит расходов на странице согласия, это месячный лимит.
  • Работает с обоими базовыми URL: https://bazaarlink.ai/api/v1 и https://api.bazaarlink.ai/v1.
  • Учитывается в лимите аккаунта в 200 ключей и отображается в списке «API-ключи» пользователя, где его можно в любой момент отключить или удалить.
  • Заблокированные или удалённые аккаунты не могут авторизовать приложения, а code, выданный до блокировки, отклоняется при обмене (403 invalid_code).

Что вы получаете

  • Код авторизации + поток PKCE для общедоступных клиентских приложений
  • Оплата для каждого пользователя: каждый платит за своё использование со своего баланса
  • Отдельный ключ для каждого пользователя; он указан на странице «API-ключи» пользователя, где его можно отозвать

Управление API Ключи

Ключи управления предназначены для программного управления ключами. Они могут создавать, перечислять, обновлять, отключать и удалять стандартные ключи API, но не могут вызывать модели ИИ.

Примечание
Клавиши управления не могут вызывать модели AI (chat/completions/messages/embeddings). Для доступа к модели используйте стандартный ключ API.

Создание ключа управления

Перейти вManagement API Страница ключейи нажмите «Создать» — это отдельная страница от ваших стандартных ключей API, а не селектор типа на той же странице.

Список ключей

GET https://api.bazaarlink.ai/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://api.bazaarlink.ai/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"
}

Update Key

PATCH https://api.bazaarlink.ai/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://api.bazaarlink.ai/v1/keys/:id
Authorization: Bearer sk-bl-YOUR_MGMT_KEY

# Returns 204 No Content on success

Запрос баланса

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

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

Использование запросов

GET https://api.bazaarlink.ai/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://api.bazaarlink.ai/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!"}],
)

Коды ошибок

Ошибка формата ответа Конечные точки вывода

Формат ошибок зависит от endpoint. Используйте HTTP-статус и error.type, если он есть. error.code может быть строкой, числом или отсутствовать; error.message предназначено только для отображения.

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

HTTP

Формат ошибок зависит от endpoint. Используйте HTTP-статус и error.type, если он есть. error.code может быть строкой, числом или отсутствовать; error.message предназначено только для отображения.

Код
Название
Описание
424Сбой зависимостиНастроенный вами ключ BYOK отклонён upstream-провайдером; проверьте или замените его в настройках BYOK. Ошибка появляется только в строгом режиме
400Неверный запросНеверный запрос, пустой массив сообщений или отсутствуют обязательные поля
401НесанкционированныйAPI Ключ отсутствует, недействителен или отключен.
402Требуется оплатаНедостаточно средств на счете, достигнут предел расходов на ключ или превышен предел бюджета monthly/weekly
403ЗапрещеноУчетная запись заблокирована или не имеет разрешения
404Не найденЗапрошенная модель, поколение, ключ или другой ресурс не существует.
409КонфликтРесурс не находится в требуемом состоянии, например задание видео не завершено.
410УшелЗапрошенная модель снята с производства и должна быть заменена.
413Полезная нагрузка слишком великаТело запроса превышает 10 МБ; уменьшить размер контента или разделить запрос
416Диапазон неудовлетворителенЗапрошенный диапазон байтов недействителен для созданного видеоконтента.
429Слишком много запросовПревышен лимит скорости; перед повторной попыткой проверьте заголовок Retry-After
432Бесплатная квота исчерпанаTavily-совместимые эндпоинты (/v1/search, /v1/extract, /v1/crawl, /v1/map): бесплатная квота поиска исчерпана или баланс равен нулю или отрицателен; пополните баланс, чтобы продолжить. Тело ответа в формате Tavily: {"detail":{"error":"..."}}
500Ошибка сервераВнутренняя ошибка BazaarLink
502Плохой шлюзНи один upstream-источник не обработал запрос; запрос вернёт ошибку.
503Сервис недоступенДля этой модели не настроен ни один вышестоящий поставщик; связаться с администратором
504Тайм-аут шлюзаВосходящее соединение или поток остановлены и истекло время ожидания.

Машиночитаемые коды оплаты Ответ

A 402 может представлять собой различные элементы управления. Эти стабильные коды позволяют клиентам показывать правильное следующее действие.

Код
Описание
byok_key_invalidНастроенный вами ключ BYOK отклонён upstream-провайдером; проверьте или замените его в настройках BYOK. Ошибка появляется только в строгом режиме.
budget_cap_reachedA Достигнут предел еженедельного или ежемесячного бюджета рекомендаций; поднимите или сбросьте крышку.
credit_limit_exceededA Жесткая кредитная линия организации, осуществляющей ежемесячные платежи, исчерпана; контактный биллинг.
insufficient_creditsA пользователь или организация с предоплатой не может зарезервировать достаточный баланс; добавить кредиты.
spend_limit_exceededКлюч API достиг настроенного ежедневного, еженедельного или ежемесячного лимита расходов.
capacity_unavailableThis model is temporarily at capacity. Retry shortly; the Retry-After header says how long to wait.

Подробные коды ошибок

Если запрос 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
Создание и редактирование изображений
Ввод изображения, многочастное редактирование, вывод и ошибки конвейера изображений.
Код
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
capacity_unavailable429
upstream_unavailable502/503
byok_key_invalid424

Модерация контента

Все запросы автоматически проверяются перед отправкой модели. Запросы, нарушающие нашу политику использования, отклоняются до модели и возвращают ошибку 403.

Категории контента, которые блокируются

Модерация основана на нашей Политике допустимого использования (Acceptable Use Policy) и в первую очередь блокирует следующие категории контента:

  • Контент сексуальной эксплуатации
  • Угрозы насилия
  • Инструкции по совершению противоправных действий
  • Контент, связанный с биологической опасностью

Формат ответа 403

Запрос, заблокированный модерацией, возвращает ошибку в следующем формате:

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

Заблокированные запросы не тарифицируются — вы не будете платить за отклонённый запрос.

Обжалование ложного срабатывания

Если вы считаете, что запрос был заблокирован ошибочно, обратитесь в службу поддержки, указав время запроса и (по возможности) request id — мы проверим.

Конфиденциальность

Запросы автоматически проверяются на безопасность контента; текст и изображения вашего последнего ввода могут отправляться стороннему сервису оценки безопасности контента.

Для запросов, признанных нарушающими, предположительно нарушающими, близкими к порогу или попавшими в случайную выборку, мы можем сохранять полный текст или его начальную часть как доказательство соответствия требованиям, для разрешения споров и аудита, без обещания фиксированного срока удаления.

Для остальных обычных успешных запросов промпты и ответы не сохраняются; на запросы с ключами ZDR первые два пункта не распространяются.

Ограничения ставок, бюджеты и экстренные тормоза

Эти элементы управления могут отклонить действительный запрос. Они отличаются от сбоев поставщика и требуют других действий по восстановлению.

Управление
HTTP
Как это определить
Ограничение скорости запроса429Строковый или числовой код 429; используйте заголовки Retry-After и X-RateLimit-*.
Блок штрафа за ограничение скорости429Цифровой код 429 и сообщение о временном ограничении; используйте Повтор-После.
Global проводит аварийное торможение503Цифровой код 503, сообщение о глобальном лимите расходов и повторная попытка через 30 или 300 секунд.
Org/team/member/user расходный тормоз429Цифровой код 429 и сообщение автоматического выключателя с указанием затронутой области.
Контроль выставления счетов и бюджета402Используйте коды строк стабильного платежа, перечисленные выше.

Формат ошибок зависит от endpoint. Используйте HTTP-статус и error.type, если он есть. error.code может быть строкой, числом или отсутствовать; error.message предназначено только для отображения.

Состояние видео и медиаресурсов

Проверка видео обычно возвращает числовой код 400. Отсутствующее задание возвращает 404, устаревшая модель возвращает 410, незавершенное видеоконтент возвращает 409, а недопустимый диапазон видеобайтов возвращает 416. Опрос до завершения или исправление заголовка Range перед повторной попыткой.

Политика повторных попыток

Повторять только те сбои, которые можно устранить без изменения запроса. Если присутствует Retry-After, подождите столько же; в противном случае используйте экспоненциальную задержку с джиттером. Ограничьте попытки и избегайте наслаивания ручных повторов поверх автоматических попыток SDK.

Повторить попытку с откатом
429, 502, 503 и 504. Соблюдайте параметр «Повторить попытку после», если он предусмотрен. Для запросов на создание не создавайте второе задание после неоднозначного сбоя сети, пока вы не проверите исходное задание.
Исправьте перед повторной попыткой
400, 401, 402, 403, 404, 409, 410, 413 и 416. Сначала измените запрос, учетные данные, баланс, разрешения, состояние ресурса или заголовок диапазона.

Обработка ошибок

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)

Форматы ошибок потоковой передачи

Ошибки, возникающие до потоковой передачи каких-либо токенов, возвращают стандартный ответ об ошибке HTTP с телом JSON.

После запуска потока ответ HTTP уже равен 200. Анализируйте каждый кадр данных SSE и обрабатывайте ошибку верхнего уровня или choice[0].finish_reason === "error" как неудавшийся, неполный ответ.

Если поток завершается ошибкой после начала, BazaarLink может отправить последнее SSE-событие с объектом error верхнего уровня, а затем data: [DONE]. Считайте ответ неполным и не используйте частичный вывод как завершённый результат.

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

data: [DONE]

// Branch on error.code; error.type can vary by failure path.

Вызов инструмента

Tool Вызов (также известный как вызов функции) позволяет моделям вызывать внешние функции, которые вы определяете. Модель решает, когда вызывать инструмент, и генерирует структурированные аргументы — ваш код выполняет функцию и возвращает результаты для продолжения диалога.

Поддерживаемые модели

Большинство передовых моделей поддерживают вызов инструментов. Вот несколько популярных вариантов:

Определение инструментов

Каждый инструмент представляет собой объект JSON, описывающий функцию, которую может вызывать модель. Поле параметров использует схему JSON.

nameобязательно
string
Имя функции (a–z, A–Z, 0–9, подчеркивание, тире)
descriptionобязательно
string
Четкое описание того, когда и как следует использовать функцию.
parametersобязательно
object
JSON Объект схемы, определяющий параметры функции

tool_choice Параметры

Значение
Поведение
"auto"Model решает, вызывать ли инструмент (по умолчанию).
"none"Model не будет вызывать какой-либо инструмент.
"required"Модель должна вызывать хотя бы один инструмент.
{"type": "function", "function": {"name": "get_weather"}}Model должна вызвать указанную функцию.

Полный поток

Вызов инструмента — это многоходовой процесс: (1) отправка запроса с помощью инструментов → (2) модель возвращает Tool_calls → (3) выполнение функций → (4) отправка результатов обратно → (5) модель генерирует окончательный ответ.

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":"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.

Параллельные вызовы инструментов

Некоторые модели могут вызывать несколько инструментов в одном ответе. Обрабатывайте каждый вызов инструмента и возвращайте все результаты:

# 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-4o",
        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-4o",
    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"]))

Простой агентский цикл

A универсальный шаблон, который продолжает вызывать модель, пока она продолжает запрашивать инструменты, и останавливается, как только возвращает окончательный ответ. Используйте 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-4o",
        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)

Рекомендации по определению функций

  • Используйте конкретные описательные имена — get_weather_forecast, а не просто погода.
  • Напишите четкое описание того, что делает функция и когда ее использовать — модель полагается исключительно на этот текст, чтобы решить, следует ли ее вызывать.
  • Ограничивайте значения перечислением, где это возможно, и включите пример в описание, чтобы уменьшить количество неверных аргументов.
  • Обязательно отмечайте только те поля, которые действительно обязательны — необязательные поля должны быть действительно пропущенными.

Структурированный вывод

Заставьте модель возвращать действительный JSON, соответствующий схеме. Это важно для создания надежных приложений, которые программно анализируют выходные данные модели.

Метод 1: формат_ответа (схема JSON)

для обеспечения строгого соответствия схеме JSON:

typeобязательно
string
Должен быть "json_schema"
json_schema.nameобязательно
string
A имя схемы (используется для кэширования)
json_schema.strict
boolean
Если это правда, гарантирует точное соответствие схемы.
json_schema.schemaобязательно
object
Определение схемы JSON
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":"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
        }
      }
    }
  }'

Советы

  • Используйте понятные, описательные имена свойств — модель использует их в качестве контекста.
  • Добавьте описания к свойствам схемы для управления моделью.
  • Set strict: true для гарантированного соответствия схемы (может немного увеличить задержку).
  • Сохраняйте простоту схем: глубокая вложенность схем может снизить качество вывода.
  • Протестируйте разные модели — некоторые справляются со сложными схемами лучше, чем другие.

Assistant Предварительное заполнение

Добавьте частичное сообщение помощника в качестве последнего элемента, чтобы запросить продолжение маршрутов совместимой модели.

curl https://api.bazaarlink.ai/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 сохраняет и пересылает последнее сообщение помощника. Поведение продолжения реализуется выбранной восходящей моделью и поставщиком, поэтому оно не гарантируется на каждом маршруте.

Преобразование сообщений

The client-supplied transforms field is ignored and removed before an upstream request. It cannot enable or disable message transformations. BazaarLink may apply context handling under its own server-side rules; shorten the input or select a model with a larger context window when needed.

Unsupported request field
Do not rely on transforms values such as middle-out; they do not change how this request is routed or processed.

Нулевое сохранение данных

При обычных успешных запросах BazaarLink не сохраняет содержимое вашего сообщения (исключения: см. Политику конфиденциальности); режим ключа ZDR обеспечивает более строгое нулевое хранение данных. На этой странице описывается, как обрабатываются ваши данные. Подходит для приложений, обрабатывающих конфиденциальные данные.

Обработка текущих данных

  • Содержимое сообщения: не сохраняется при обычных успешных запросах (исключения: см. Политику конфиденциальности); режим ключа ZDR строже
  • Записи об использовании для расчётов и эксплуатации: количество токенов, время, модель, стоимость, задержка и статус
  • Журналы использования: при обычных успешных запросах только статистика использования, без содержания сообщений
  • Пересылка вверх по течению: сообщения пересылаются вышестоящим поставщикам — в соответствии с их политикой конфиденциальности. При кэшировании

Быстрое кэширование

Prompt повторно используются ранее вычисленные токены подсказок, что значительно снижает затраты и задержки — особенно для приложений с большими повторяющимися системными подсказками.

Note
BazaarLink автоматически отслеживает экономию кэша и отражает ее в счетах. Поле `cached_tokens` в ответе показывает фактические попадания в кэш; `cacheDiscount` показывает сумму, сэкономленную по этому запросу.

Как это работает

Необходимость настройки кэширования зависит от поставщика. Модели семейства OpenAI автоматически кэшируют длинные повторяющиеся префиксы подсказок — никаких изменений запроса не требуется. Claude (Anthropic) моделирует кэширование только тогда, когда запрос содержит явную точку останова Cache_control; BazaarLink не добавляет это за вас, поэтому запрос Claude без маркера никогда не кэшируется. BazaarLink пересылает любые маркеры кэша, которые вы отправляете, как есть, и сообщает о результирующих токенах кэша read/write в ответе об использовании.

# OpenAI-family models: nothing to add, long repeated prefixes cache automatically.
response = client.chat.completions.create(
    model="openai/gpt-4o",
    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: {"type": "ephemeral"} в блок контента, который вы хотите кэшировать, как показано ниже. Anthropic также устанавливает собственную минимальную длину приглашения, прежде чем оно вообще будет кэшироваться — короткие приглашения автоматически пропускают кэширование даже при наличии маркера. Проверьте кэшированные_токены (OpenAI-shape) или кэш_read_input_tokens/cache_creation_input_tokens (Anthropic-shape) в ответе, чтобы подтвердить попадание.
# 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/gpt-5.5",
  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/gpt-5.5, gpt-5.6-sol, gpt-5.4reasoning_effort: "low" | "medium" | "high"medium
deepseek/deepseek-r1—Всегда включено (невозможно отключить)
# Qwen3: explicitly enable thinking mode
response = client.chat.completions.create(
    model="qwen/qwen3.7-flash",
    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

Единый объект рассуждения (новый формат)

BazaarLink также поддерживает унифицированный объект рассуждения, который работает во всех семействах моделей с единым согласованным 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 GPT-5.6 Sol — specify effort level
const response2 = await client.chat.completions.create({
  model: "openai/gpt-5.6-sol",
  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 },
});

Чтение текста рассуждений

Модель с рассуждениями может вернуть текст рассуждений вместе с ответом. У перечисленных ниже моделей рассуждения включены по умолчанию: запрос без параметров рассуждений выполняется с включённым рассуждением, возвращает его текст, и оплачиваются реально использованные токены рассуждений. Чтобы отключить, отправьте reasoning: { exclude: true } или include_reasoning: false. Все остальные модели возвращают текст рассуждений только по вашему запросу: отправьте reasoning_effort, объект reasoning, include_reasoning: true, thinking или enable_thinking.

Модели, которые рассуждают по умолчанию: gemini-4-argon, deepseek-v4.1-flash, deepseek-v4.1-flash-1017

Как его запросить

Передайте в запросе любое из следующего: reasoning_effort (low, medium или high), объект reasoning (effort, max_tokens), include_reasoning: true, thinking: { type: "enabled" } или enable_thinking: true. Передайте reasoning.exclude: true или include_reasoning: false, чтобы отключить текст рассуждений (модель всё равно рассуждает).

ПолеГдеЗначение
reasoningchoices[].message.reasoningТекст рассуждений (строка)
reasoning_detailschoices[].message.reasoning_detailsТекст рассуждений в виде списка элементов, в каждом только type и text
reasoningchoices[].delta.reasoningПотоковая передача: текст рассуждений приходит частями (delta.reasoning и delta.reasoning_details) раньше текста ответа в delta.content
Note
Нет параметра: перечисленные выше модели рассуждают по умолчанию, поэтому вы получаете текст рассуждений и платите за токены рассуждений (usage.completion_tokens_details.reasoning_tokens). У всех остальных моделей нет параметра — нет текста рассуждений: вы получаете только ответ (message.content), как и раньше. Чтобы отключить рассуждения у перечисленной модели, отправьте reasoning.exclude: true или include_reasoning: false: рассуждение не выполняется, токены рассуждений не оплачиваются. У других моделей с рассуждениями exclude лишь скрывает текст; их токены рассуждений по-прежнему учитываются.

Какие уровни поддерживает модель, видно в GET /v1/models: каждая модель с рассуждениями перечисляет reasoning.supported_efforts, reasoning.default_effort и reasoning.mandatory (например, gemini-4-argon поддерживает high, medium и low).

Пример: gemini-4-argon

response = client.chat.completions.create(
    model="gemini-4-argon",
    messages=[{"role": "user", "content": "Which is larger, 9.11 or 9.9?"}],
    reasoning_effort="high",  # or: extra_body={"include_reasoning": True}
)

message = response.choices[0].message
print(message.reasoning)          # the thinking text (only returned because we asked)
print(message.content)            # the answer
const stream = await client.chat.completions.create({
  model: "gemini-4-argon",
  messages: [{ role: "user", content: "Which is larger, 9.11 or 9.9?" }],
  stream: true,
  // @ts-ignore - BazaarLink extension
  reasoning: { effort: "high" },
});

for await (const chunk of stream) {
  const delta: any = chunk.choices[0]?.delta;
  if (delta?.reasoning) process.stdout.write(delta.reasoning); // thinking text
  if (delta?.content) process.stdout.write(delta.content);     // answer
}

В /v1/responses запрашивайте через reasoning: { effort, summary: "auto" }; текст рассуждений возвращается в элементе reasoning массива output. В /v1/messages передайте thinking: { type: "enabled", budget_tokens }, чтобы получить блоки thinking.

Цены
Токены Thinking оплачиваются как токены завершения. Некоторые провайдеры взимают более высокую плату за режим мышления — Qwen3 стоит в 2 раза дороже стандартной цены, когда мышление активно. BazaarLink по умолчанию устанавливает для Qwen3 значение Enable_thinking=false, чтобы избежать непредвиденных затрат.

Задержка и производительность

Оптимизация задержки ответа AI API имеет решающее значение для удобства пользователей. Ниже приведены ключевые факторы, влияющие на задержку в архитектуре BazaarLink, а также рекомендации по оптимизации.

Note
BazaarLink записывает `duration_ms` (сквозная задержка) и `throughput` (tokens/sec) для каждого запроса — ищите их через GET /v1/generation?id=... или в экспорте действий CSV.

Факторы, влияющие на задержку

  • Размер модели: модели большего размера (70B+), как правило, генерируются медленнее.
  • Нагрузка поставщика: зависит от поставщика и времени суток.
  • Количество токенов: чем больше max_tokens, тем дольше время завершения
  • Потоковая передача и непотоковая передача: поток: true доставляет первый токен быстрее.
  • Длина контекста: очень длинные контексты увеличивают время предварительной обработки.

Советы по оптимизации

  • Предпочитайте потоковую передачу (stream: true), чтобы уменьшить воспринимаемую задержку.
  • Выбирайте модели меньшего размера (flash/mini/haiku) для сценариев, чувствительных к задержке.
  • Включите кэширование запросов, чтобы уменьшить задержку при повторных запросах.
import time

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

stream = client.chat.completions.create(
    model="google/gemini-3.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://api.bazaarlink.ai/v1/generation?id=BAZAARLINK_REQUEST_ID" \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY"

# Response
{
  "data": {
    "id": "85e6f35c71a31f19-SJC",
    "model": "google/gemini-3.5-flash",
    "duration_ms": 842,
    "throughput": 61.2,
    "usage": { "prompt_tokens": 12, "completion_tokens": 48, "total_tokens": 60 }
  }
}

Оптимизация времени работы

После ошибки upstream запрос может попробовать другой доступный источник. Если ни один источник не может его обработать, запрос вернёт ошибку. Автоматические выключатели ограничивают повторные попытки, а состояние поставщиков отслеживается.

Note
BazaarLink отслеживает доступность всех вышестоящих поставщиков. Когда частота ошибок поставщика превышает пороговое значение, автоматический выключатель автоматически срабатывает и направляет запросы следующему доступному поставщику.

Механизмы доступности

  • Автоматический выключатель: автоматически обнаруживает и изолирует неисправных поставщиков
  • При проблеме с upstream-источником запрос может попробовать другой доступный источник. Если доступных источников нет, запрос вернёт ошибку.
  • Мониторинг состояния поставщика: непрерывно отслеживает частоту ошибок и задержку для каждого поставщика.
  • Retry логика: временные ошибки (5xx) автоматически повторяются

Автоматический выключатель

# If an upstream source returns an error, the request can try another available source.
# Requests handled by a platform model are billed at that model's catalog price.

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

# Check whether another source handled the request (in usage logs)
# "is_failover": true indicates the primary provider was bypassed
Мониторинг состояния поставщика — это внутренний обзор операционной системы.
GET /api/admin/provider-health — это внутренняя конечная точка панели управления операциями, доступная для проверки подлинности администратора. Он возвращает полную рабочую нагрузку (объем запросов для каждого поставщика, частоту ошибок, процентили задержки, статистику отработки отказа и т. д.) — это не общедоступный клиент API, поэтому мы не воспроизводим здесь точные поля.

Ограждения

Добавьте механизмы безопасности контента в запросы API для фильтрации вредоносного контента и обеспечения соблюдения политик соответствия. BazaarLink в настоящее время предлагает настраиваемые защитные фильтры контента только на уровне организации; Персональные (не организационные) ключи API не имеют эквивалентных настроек — безопасность контента полностью зависит от собственных встроенных систем безопасности каждого вышестоящего поставщика модели.

Текущий объем
Личные ключи API не имеют встроенных пользовательских ограждений — безопасность контента полностью зависит от собственных систем безопасности вышестоящего поставщика. Если вам нужны настраиваемые правила фильтрации контента (block/redact/flag, правила ключевых слов и регулярных выражений, встроенные шаблоны PII), создайте организацию и используйте ключ организации API, настроенный в разделе «Защиты фильтра контента».

Планируемые функции (пока недоступны ни для личных ключей, ни для ключей организации)

Ограждение
Описание
PII обнаружениеОбнаружение и редактирование личной информации
Ограничение темыОграничивать ответы моделей только утвержденными темами.
Проверка выводаПроверка выходных данных модели на соответствие пользовательским правилам перед возвратом.

Текущее поведение

Личные ключи API: все вышестоящие поставщики имеют свои собственные системы безопасности контента — ответы модели, запускающие фильтры контента, возвращаются с Finish_reason: «content_filter», а BazaarLink не применяет дополнительную фильтрацию. Ключи организации API: org_admin может настраивать пользовательские правила (block/redact/flag) в разделе «Защитные ограждения фильтра содержимого», применяемые до того, как текст достигнет модели.

Cursor IDE Интеграция

Используйте BazaarLink в качестве переопределения OpenAI курсора URL. Встроенная настройка с автоматическим преобразованием тел ответов API, нормализацией формата инструмента и соглашением о префиксе bz- для моделей Claude.

Быстрая настройка

В Курсоре откройте «Настройки» → «Модели», затем:

  1. Установите для переопределения OpenAI Base URL значение https://api.bazaarlink.ai/v1.
  2. Установите Override OpenAI API Key на ваш ключ sk-bl-... BazaarLink
  3. Добавьте желаемое название модели — см. ниже Claude (префикс bz-).
Обратная совместимость
Прежний совместимый эндпоинт /cursor по-прежнему работает на обоих хостах (https://api.bazaarlink.ai/v1/cursor и https://bazaarlink.ai/api/v1/cursor). Это тонкий реэкспорт /v1/chat/completions — для новых настроек используйте базовый URL выше.

Префикс bz- (для моделей Claude)

Проверка Cursor на стороне клиента перенаправляет любое имя модели, начинающееся с claude-, посредством собственной интеграции Cursor с Anthropic, минуя переопределение URL. Чтобы заставить Cursor отправить запрос на BazaarLink, добавьте к имени модели префикс bz-. Сервер удаляет префикс и разрешает остальное через карту псевдонимов.

Введите курсорРешает:
bz-claude-sonnet-4.6anthropic/claude-sonnet-4.6
bz-claude-opus-4.7anthropic/claude-opus-4.7
gpt-4oopenai/gpt-4o
gemini-3.5-flashgoogle/gemini-3.5-flash

Варианты «точка-дефис» нормализованы: bz-claude-sonnet-4.6 и bz-claude-sonnet-4-6 разрешаются для одной и той же модели.

CURSOR_MODEL_MAP env var (переопределение оператора)

Для локальных развертываний BazaarLink установите эту переменную env, чтобы переназначить произвольные имена моделей на стороне курсора в канонические идентификаторы каталога:

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

Теперь gpt-claude-sonnet, введенный в курсор, сопоставляется с серверной стороной anthropic/claude-sonnet-4.6. Полезно, когда вы хотите, чтобы курсор считал модель семейством GPT (поэтому она маршрутизируется через переопределение URL), в то время как вы на самом деле обслуживаете Claude.

Что происходит автоматически

Когда запрос достигает /v1/chat/completions, BazaarLink прозрачно применяет эти преобразования совместимости — вам не нужно ничего делать на стороне клиента:

  • Автоматическое обнаружение тел ответов API — если тело содержит входные данные вместо сообщений, оно преобразуется в форму Chat Completions (курсор отправляет ответы в формате API для моделей семейства GPT).
  • Wraps определения плоского инструмента — агент курсора отправляет { имя, описание, параметры } без оболочки функции. Мы обертываем его так, чтобы вышестоящий сервис не отклонял его как «Инструмент», не найденный в предоставленных инструментах.
  • Приводит неверный инструмент Tool_choice — Курсор отправляет { type: "auto" } (форма объекта, без функции). Спецификация OpenAI требует строковой формы для auto/none/required, поэтому мы приводим.
  • Удаляет поля, специфичные для провайдера, если вышестоящий сервис их не поддерживает — parallel_tool_calls, logprobs, top_logprobs, logit_bias, service_tier, user удаляются перед пересылкой (в противном случае вышестоящий сервис возвращает 400).
  • Maps max_output_tokens → max_tokens и полосы Responses-API-только поля (previous_response_id, усечение, фон, хранилище). Поле рассуждений сохраняется для тел, родных для Chat-Completions.

Режим агента курсора

Вызов инструментов осуществляется через стандартный поток вызова инструментов Chat Completions. Курсор отправляет инструменты (Shell, Read, Write, Grep и т. д.) с помощью Tool_choice: "auto"; BazaarLink перенаправляет провайдеру выбранной вами модели, который решает, следует ли вызывать инструмент. Вызовы инструментов возвращаются как стандартные OpenAItool_calls deltas; Курсор выполняется локально и продолжает диалог. Работает одинаково независимо от того, выбираете ли вы gpt-4o (родной OpenAI) или bz-claude-sonnet-4.6.

Отладка отклонений восходящего потока
Если вы видите ошибки поставщика 4xx, проверьте панель администратора «Состояние поставщика». Каждый ответ 4xx сохраняется с полным телом ошибки восходящего потока и сводкой тела перенаправленного нами запроса — щелкните любую строку 🔴, чтобы развернуть JSON.

Модель маршрутизации

BazaarLink использует формат provider/model-name для маршрутизации запросов к правильному вышестоящему поставщику. Это дает вам доступ ко всем основным моделям через единую конечную точку API.

Формат идентификатора модели

{provider}/{model-name}

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

Приоритет маршрутизации

При отправке запроса BazaarLink разрешает вышестоящего поставщика в следующем порядке:

  1. Exact match — ищет маршрут модели, соответствующий полному идентификатору модели.
  2. Provider Подстановочный знак — возвращается к маршрутам поставщика/* (например, openai/*)
  3. Global wildcard — возвращается к * маршрутам с подстановочными знаками.
  4. Ключ поставщика по умолчанию — только для известной модели каталога, используются активированные ключи, помеченные как ключи по умолчанию.

Посмотрите все доступные модели на Страница моделей.

Автомаршрутизатор

Auto Router v3 распределяет запрос по одному из 14 уровней задач, а затем использует текущую основную и резервную цепочку, настроенную для этого уровня. Платные и бесплатные столы управляются отдельно в консоли администратора.

  • auto — платная таблица маршрутизации. Успешно решенная модель оплачивается по опубликованной цене.
  • auto:free — свободная таблица маршрутизации. Звонки в пределах бесплатной квоты стоят 0$; после достижения квоты финансируемые аккаунты могут переключиться на платную автоматическую маршрутизацию, если не отключен платный резервный вариант.

Как использовать

Установите модель «auto» (платная) или «auto:free» (бесплатная), чтобы включить автоматическую маршрутизацию:

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

Как версия 3 выбирает уровень

Общие уровни бывают простыми, стандартными, сложными и логическими. Специализированные уровни — это кодирование, видение, изображения, видео, данные, поиск, социальные сети, электронная почта, календарь и торговля. Результаты границ с низкой достоверностью повышаются на один уровень вместо угадывания вниз.

  • Оценка уровней: сообщения, инструменты, длина, ключевые слова и структурные сигналы, выберите один из 14 уровней.
  • Жесткие переопределения: видение, формальные рассуждения и специализированные задачи могут напрямую выбирать уровень.
  • Поиск маршрута: выбранный режим считывает текущий основной уровень и до пяти резервных; отключенный уровень возвращает 503
  • Execution: BazaarLink пробует основную, а затем настроенную резервную цепочку по порядку.
  • Отслеживание ответов: решенная модель возвращается в теле ответа и заголовке X-Auto-Resolved-Model.

Таблицы текущих моделей

Приведенные ниже таблицы считываются из той же активной конфигурации, которая используется для вывода и консоли администратора. Администраторы могут изменить основную модель каждого уровня, резервный порядок и включенное состояние без развертывания.

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-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
standarddeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
complexdeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
reasoningdeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
codingdeepseek/deepseek-v4-flash-0731free
reflection/beamnvidia/nemotron-3.5-lightning-free
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-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
searchdeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
socialdeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
emaildeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
calendardeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled
tradingdeepseek/deepseek-v4-flash-0731free
nvidia/nemotron-3.5-lightning-freereflection/beam
enabled

Выбранные модели имеют ограниченный по скорости уровень бесплатного пользования. Бесплатное право на участие предоставляется платформой для каждой модели — назовите модель по ее обычному идентификатору; суффикс :free является необязательным псевдонимом (добавление его к платной модели не делает ее бесплатной).

После исчерпания бесплатной квоты
После исчерпания бесплатной квоты запросы сверх неё оплачиваются по указанной цене модели, если на счёте есть средства. Чтобы вместо этого получать 429, передайте `X-Free-Fallback: false` или отключите переход на платный уровень в настройках ключа. Без средств запросы сверх квоты возвращают 429. Когда запрос действительно понижается таким образом, в ответе появляется заголовок x-bl-free-fallback: daily или x-bl-free-fallback: rpm, указывающий, какой лимит сработал — так вы узнаёте о переключении уже в момент запроса, а не только по счёту. У запросов без понижения этого заголовка нет.
X-Auto-Resolved-Model
Фактическая выбранная модель возвращается в заголовке ответа X-Auto-Resolved-Model и в поле модели тела ответа.

Варианты модели

Поля маршрутизации клиента игнорируются
Поля provider (весь объект), transforms, route, service_tier верхнего уровня и preset удаляются перед отправкой upstream и не могут выбирать upstream или ценовой уровень. На эндпоинтах Chat Completions и Responses массив models поддерживается как локальный список резервных моделей: BazaarLink самостоятельно маршрутизирует каждую модель и применяет ее клиентскую цену; список не передается upstream. Суффиксы :nitro, :floor и :exacto, указанные клиентом, игнорируются. :eco остается экономичным тарифом BazaarLink и внутри преобразуется в BazaarLink :floor. :free остается отдельным вариантом модели в каталоге.

Независимые идентификаторы моделей

Варианты каталога, например :free, :extended и :thinking, могут обозначать записи с разными возможностями или ценами. Upstream-маршрут и цена для клиента определяются каталогом BazaarLink и правилами на стороне сервера.

:free
:extended
:thinking
:nitro
:floor
:exacto
Дополнительная стоимость веб-поиска
Поведение веб-поиска через plugins, :online или web_search_options остается прежним, но может взиматься дополнительная плата upstream. Она списывается с ключа, использованного в запросе: платформенного ключа BazaarLink или вашего ключа BYOK.
:online

Бесплатные модели

Выбранные модели имеют ограниченный по скорости уровень бесплатного пользования. Бесплатное право на участие предоставляется платформой для каждой модели — назовите модель по ее обычному идентификатору; суффикс :free является необязательным псевдонимом (добавление его к платной модели не делает ее бесплатной).

  • Вызовите обычный идентификатор модели (например, deepseek/deepseek-v4-flash). Запросы автоматически обслуживаются бесплатно в пределах бесплатной квоты.
  • Бесплатное использование для каждого пользователя ограничено количеством запросов в минуту и ​​дневным лимитом. Ограничения масштабируются в зависимости от уровня учетной записи (без кредита/зачислено).
  • Если вы превысите бесплатную квоту и у вас появятся кредиты, запросы автоматически перейдут на платный уровень по указанной цене. Отправьте X-Free-Fallback: false, чтобы отключить автоматический возврат и вместо этого получить 429. Без кредитов запросы на превышение квоты возвращают 429.
  • GET /v1/models перечисляет запись :free для каждой модели с уровнем бесплатного пользования; auto:free всегда маршрутизирует к свободной модели.

Модели с бесплатным уровнем прямо сейчас

Вызовите эти идентификаторы моделей напрямую, чтобы использовать бесплатную квоту. Список меняется по мере добавления или удаления моделей — запросите API для получения актуального набора.

qwen/qwen3.7-flash
reflection/beam-free
stealth/glyph-cluster
nvidia/nemotron-3.5-lightning-free
inclusionai/ling-3.1-flash-1019
deepseek/deepseek-v4-flash-0731free

Бесплатные ограничения квоты

Предмет
Значение
Запросов в минуту (RPM)10 / min
Дневной бюджет запроса60 / day
Множитель уровня аккаунта — без кредита× 1
Множитель уровня аккаунта — финансируемый× 2

Ваш дневной бюджет = дневной бюджет запроса выше × множитель уровня вашего аккаунта, рассчитываемый отдельно для каждой бесплатной модели. auto:free дополнительно обеспечивает ограничение количества параллельных IP-адресов. Отдельные модели могут иметь более жесткие или более мягкие ограничения, установленные платформой — в блоке «Уровень бесплатного пользования» на странице модели всегда отображаются действующие значения. Бесплатная квота измеряется в «юнитах», а не просто в количестве запросов: число юнитов, расходуемых одним запросом, растёт с длиной контекста промпта. Поэтому при одинаковой дневной квоте запросы с длинным контекстом дают заметно меньше фактических обращений, чем короткие промпты.

После исчерпания бесплатной квоты

После исчерпания бесплатной квоты запросы сверх неё оплачиваются по указанной цене модели, если на счёте есть средства. Чтобы вместо этого получать 429, передайте `X-Free-Fallback: false` или отключите переход на платный уровень в настройках ключа. Без средств запросы сверх квоты возвращают 429.

Когда запрос действительно понижается таким образом, в ответе появляется заголовок x-bl-free-fallback: daily или x-bl-free-fallback: rpm, указывающий, какой лимит сработал — так вы узнаёте о переключении уже в момент запроса, а не только по счёту. У запросов без понижения этого заголовка нет.

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

Управление организацией

Когда несколько человек используют BazaarLink, создайте организацию, чтобы группировать участников в команды и управлять ключами API, разрешенными моделями, бюджетами и выставлением счетов в одном месте. Организация владеет общим балансом, а команды и участники могут иметь свои собственные ежемесячные лимиты.

Управляйте своей организацией
Чтобы добавить команды, пригласить участников или изменить настройки организации, Откройте настройки и выберите организацию.

Трехуровневая бюджетная система

Каждый запрос API проверяет ограничения участников, команд и организаций. Ошибка ежемесячного бюджета или баланса возвращает HTTP 402; расход аварийного торможения возвращает HTTP 429.

  1. Member ежемесячный бюджет (OrgMember.monthlyBudget)
  2. Ежемесячный бюджет команды (Team.monthlyBudget)
  3. Org баланс кредитов (Организация.кредиты)

Отчеты об использовании

Откройте организацию и выберите «Отчеты», чтобы просмотреть ежемесячные расходы четырьмя способами:

  • Обзор: общие расходы, ставка маржи, график дневных тенденций
  • По команде: расходы на каждую команду, процент доли, разбивка по модели, использование бюджета.
  • By Model: расходы на модель, средняя цена ($/1 млн токенов)
  • По участнику: расходы на каждого участника — только org_admin

Все представления поддерживают экспорт CSV с префиксом BOM для прямой совместимости с Excel.

Создание организаций и управление ими

  1. Откройте «Настройки» и создайте организацию в разделе «Организации».
  2. Выберите название организации, чтобы открыть раздел управления
  3. Создавайте группы и при необходимости назначайте коды центров затрат и ежемесячные бюджеты.
  4. Пригласите участников по электронной почте, назначьте роль и команду.
  5. Issue API ключи для участников — использование автоматически помечается правильной командой/участником.
  6. Просмотрите страницу отчетов, чтобы узнать ежемесячные расходы с разбивкой по команде, модели или участнику.

Роли участников

org_adminАдминистратор организации. Управляет всеми командами, участниками, ключами API, разрешенными моделями, бюджетами, выставлением счетов, отчетами, настройками и экстренными тормозами.
billing_viewerПросмотрщик финансов. Может просматривать обзор, выставление счетов, список ключей API и отчеты, но не может изменять настройки или просматривать расходы на каждого участника.
команда_adminАдминистратор команды. Управляет только членами своей команды, приглашениями, ключами API, бюджетами и аварийными тормозами.
членПостоянный участник. Использует назначенные организации ключи API и подчиняется ограничениям участников, команд, организаций и моделей.

Чем еще может управлять организация?

Помимо участников и команд, область управления организацией обеспечивает:

  • API ключи: создавайте ключи для организации, команды или участника и ограничивайте их разрешенные модели.
  • Фильтрация контента: блокируйте, редактируйте или регистрируйте конфиденциальный текст до того, как он достигнет модели.
  • Разрешенные модели: ограничение моделей для организации, команды, участника или отдельного ключа API.
  • Бюджеты и экстренное торможение: установите ежемесячные лимиты и minute/hour защитите расходы
  • Отчеты и выставление счетов: просмотр расходов, использования модели, распределения команд, баланса, кредитных лимитов и платежей.
  • Журналы изменений и безопасности: отслеживание изменений настроек, попаданий в фильтры содержимого и событий безопасности.

Контентная фильтрация

Это правила, принадлежащие организации, которые проверяют текст перед его отправкой в модель через ключ организации API. Администратор организации может включать, редактировать и тестировать правила в разделе «Настройки» → «Фильтрация контента».

  • block: отклонить весь запрос с помощью HTTP 403 до того, как он достигнет модели.
  • отредактировать: заменить совпавший текст на [REDACTED], затем отправить очищенный текст
  • flag: отправить запрос без изменений и записать совпадение в журнал аудита организации.
  • Используйте встроенные шаблоны конфиденциальных данных и ввода подсказок или создавайте правила для ключевых слов и регулярных выражений.
  • До 100 правил; регулярные выражения проверяются на безопасность, а правила можно просмотреть с помощью тестового текста.
В настоящее время ограничено вводом текста
Filtering в настоящее время охватывает текст Chat Completions, строковый ввод в ответах и текстовое содержимое в сообщениях. Изображения, аудио, видео, некоторый структурированный или мультимодальный контент, а также выходные данные модели не проверяются. Не рассматривайте это как полное предотвращение потери данных или модерацию вывода.

Управление API (v1)

Используйте элемент управления API, чтобы составлять список организаций, создавать команды, добавлять участников или обновлять бюджеты, не нажимая на веб-интерфейс. `/v1/orgs` управляет организацией и участниками; отчеты о затратах используют отдельные пути `/api/orgs/:orgId/reports/*`, указанные ниже.

Аутентификация
GET /v1/orgs перечисляет организации, принадлежащие владельцу ключа, и принимает действительный ключ API или сеанс входа. Для запросов на чтение или изменение конкретной организации, команды или участника требуется ключ управления носителем, принадлежащий org_admin, или сеанс входа в систему этого org_admin. Создайте ключ управления на странице ключей организации API.

Организации

GET/v1/orgs

Перечислите все организации, к которым принадлежит вызывающий абонент, с указанием роли и места соединения.

GET/v1/orgs/:orgId

Получите подробную информацию об организации, включая количество команд и участников.

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

Команды

GET/v1/orgs/:orgId/teams

Список команд с указанием количества участников, упорядоченных по имени.

POST/v1/orgs/:orgId/teams
nameобязательно
string
Отображаемое имя группы (должно быть уникальным в пределах организации)
costCenterCode
string
Код учетного МВЗ
monthlyBudget
number | null
Ограничение ежемесячных расходов команды в USD
PATCH/v1/orgs/:orgId/teams/:teamId

Частичное обновление — включает только те поля, которые нужно изменить.

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

Члены

GET/v1/orgs/:orgId/members

Перечислите всех участников с вложенным пользователем (id/name/email) и информацией о команде.

POST/v1/orgs/:orgId/members
emailобязательно
string
Электронная почта существующего пользователя BazaarLink
role
string
org_admin | биллинг_просмотрщик | команда_администратор | участник (по умолчанию: участник)
teamId
string
Назначить команду (обязательно, если роль — team_admin)
monthlyBudget
number | null
Ограничение ежемесячных расходов на одного участника в USD

404, если у адреса электронной почты нет учетной записи BazaarLink. 409, если вы уже являетесь участником. Роль по умолчанию: участник.

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

Частичное обновление роли, идентификатора команды или ежемесячного бюджета.

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

Возвращает 400, если целью является последний org_admin.

# Add a member
curl https://api.bazaarlink.ai/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://api.bazaarlink.ai/v1/orgs/{orgId}/members/{memberId} \
  -X DELETE \
  -H "Authorization: Bearer sk-bl-YOUR_MANAGEMENT_KEY"

Отчеты API

Отчеты API обеспечивают работу страницы отчетов организации, а также могут использоваться для внутренних информационных панелей, ежемесячной сверки или автоматической загрузки CSV. org_admin имеет доступ к каждому отчету; billing_viewer может получить доступ к обзорным, командным и модельным отчетам, но не к расходам на каждого участника. Он принимает сеанс входа в систему или ключ управления носителем.

Укажите год и месяц (1–12). Обзор и по команде по умолчанию относятся к текущему месяцу, если они опущены, тогда как для по модели, по участнику и экспорта требуются оба значения. Предоставление обоих каждый раз позволяет избежать сюрпризов, связанных с конечной точкой.

Конечная точка
Описание
GET /api/orgs/:orgId/reports/overviewОбщие расходы, ставка маржи, дневной тренд
GET /api/orgs/:orgId/reports/by-teamРасходы на команду, доля %, разбивка по модели, использование бюджета
GET /api/orgs/:orgId/reports/by-modelРасходы на модель, средняя цена ($/1 млн токенов)
GET /api/orgs/:orgId/reports/by-memberРасходы на каждого участника — только org_admin
GET /api/orgs/:orgId/reports/exportCSV скачать; добавить ?view=обзор|по команде|по модели|по участнику
# 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

Ссылка на ответ об ошибке

401Ключ API недействителен или отозван
403Отказ RBAC (недостаточная роль) или модель не в белом списке разрешенных моделей
402Ежемесячный бюджет, кредитный лимит или доступный баланс недостаточны
429Ограничение скорости или ограниченное использование аварийного торможения; следовать Retry-After, если он присутствует
503Экстренное торможение или временное отключение обслуживания на всей платформе.

Разрешенные модели (белый список)

Ограничьте модели, которые могут вызывать ваша организация, команды или отдельные участники. Полезно для блокировки дорогих или непроверенных моделей, обеспечения соблюдения стандартов моделей или объединения команды с одним поставщиком.

Как это работает

  • Три независимых уровня — Организация, Команда, Участник — каждый содержит свой собственный список (String[] в базе данных).
  • Когда все три слоя пусты, разрешена любая модель (поведение по умолчанию).
  • Если один или несколько слоев непусты, эффективный список представляет собой пересечение непустых слоев — модель должна быть разрешена для прохождения на каждом ограниченном уровне.
  • Изменения вступают в силу в течение нескольких секунд (60 секунд в памяти + 5 минут в кэше Redis; оба очищаются при обновлении).

Формат шаблона

  • Точное совпадение — например. openai/gpt-4o (только эта модель).
  • Подстановочный знак поставщика — например. openai/* (любая модель с префиксом openai/).
  • Только строчные буквы. Макс. 200 записей в списке, 100 символов в записи.

Где управлять

Организационный портал → Разрешенные модели. org_admin может редактировать списки организаций/команд/членов; Team_admin может редактировать свою команду и ее участников.

Ошибка ответа при блокировке

Вызовы запрещенной модели возвращают HTTP 403 со следующим телом:

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

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

Управление API

Все конечные точки принимают ключ управления веб-сеансом или носителем (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"]}'

Автоматический выключатель (выключатель расхода)

A ограничение расходов с двумя окнами, которое блокирует дальнейшие запросы при резком росте затрат на исходящие ресурсы. Создан для предотвращения неконтролируемых сценариев, бесконечных циклов или злоупотреблений с украденными ключами до того, как они начнут стоить реальных денег.

Как это работает

  • В Redis отслеживаются два фиксированных окна для каждой области: стоимость восходящего потока за 1 минуту и ​​1 час (USD).
  • Если расходы какого-либо окна достигают порогового значения, все последующие запросы в этой области отклоняются до тех пор, пока окно не будет перезагружено.
  • По умолчанию: 5 долларов США в минуту, 20 долларов США в час. По умолчанию отключено — нужно включить самостоятельно.
  • Counters живут в Redis с помощью TTL — восстановление происходит автоматически, ручной сброс не требуется для поездок org/team/участника.

Scopes (участник переопределяет команду, переопределяет организацию)

Каждый слой может устанавливать свои собственные пороговые значения. Порядок разрешения следующий: участник → команда → организация → платформа по умолчанию — первое ненулевое значение выигрывает для каждого поля (cbEnabled, cbMinuteUsd, cbHourlyUsd). Уровень

  • Org — применяется ко всем ключам организации. Устанавливается в Оргпортале → Выключатель.
  • Уровень команды — применяется ко всем ключам, помеченным этой командой. Переопределяет org для этих ключей. Уровень
  • Member — применяется только к ключам, помеченным для этого участника. Переопределяет команду и организацию.

Поведение при отключении

При отключении запросы быстро завершаются сбоем (восходящий вызов не выполняется). Ответ — HTTP 429 с таким телом:

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."
  }
}
Глобальный или ограниченный масштаб
A отдельный глобальный автоматический выключатель всей платформы (управляемый оператором, не видимый на портале организации) возвращает HTTP 503 с заголовком Retry-After. Операторы установили его для защиты платформы от злоупотреблений со стороны нескольких арендаторов — его нельзя переопределить в настройках вашей организации.

Журнал аудита

Записывается каждое событие отключения и каждое изменение конфигурации:

  • Trip события — действия org.cb.tripped/team.cb.tripped/org_member.cb.tripped. Дедуплицируется до одной записи на область + окно в час, поэтому продолжительное отключение не переполняет журнал.
  • Изменения конфигурации — действия org.cb.update/team.cb.update/org_member.cb.update. Захватите значения before/after плюс актер.

Управление API

Администраторы организации могут читать и обновлять настройки через API. Все конечные точки принимают ключ управления веб-сеансом или носителем (sk-bl-...). Отправьте любое подмножество полей в теле PATCH; 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-ключей помогает поддерживать безопасность. Создайте новый ключ, обновите и проверьте интеграцию, затем отзовите старый ключ. Отсутствие простоя в этом процессе не гарантируется.

Примечание
API можно отозвать в любой момент с панели управления или через управление API. Отзыв происходит немедленно — все запросы, использующие этот ключ, мгновенно завершатся ошибкой.

Этапы вращения

  1. Создайте новый ключ API.
  2. Обновите приложение или переменные окружения, чтобы использовать новый ключ
  3. Убедитесь, что новый ключ работает правильно.
  4. Отключить или удалить старый ключ
# Key CRUD via Bearer auth requires a MANAGEMENT key (keyType: "management").
# Standard keys get 403 on /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://api.bazaarlink.ai/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://api.bazaarlink.ai/v1/models \
  -H "Authorization: Bearer sk-bl-NEW_KEY_VALUE"

# Step 4: Revoke old key (management key auth again)
DELETE https://api.bazaarlink.ai/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)
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_ntdСписанная сумма в новых тайваньских долларах
duration_msEnd-to-end latency in milliseconds
finish_reasonstop / length / content_filter / error
statusКод статуса ответа BazaarLink
app_nameX-Title header value (app attribution)

JSON Использование API

Для программного доступа запросите агрегированную статистику, сгруппированную по периоду, модели или ключу:

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

# With period filtering (day | week | month | year)
GET https://api.bazaarlink.ai/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, включая потребление токенов, анализ затрат и историю запросов.

Примечание
Счет за использование данных выставляется в формате USD. Записи отдельных запросов доступны на странице журналов или с помощью экспорта CSV. Агрегированная статистика (по периоду, модели или ключу) доступна через конечную точку `/v1/usage` с аутентификацией по токену носителя.

Справочник по полю ответа

FieldTypeDescription
modelstringModel ID used (e.g., openai/gpt-4o)
providerstringФиксированное значение BazaarLink: bazaarlink
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
costnumberСумма в USD, списанная с клиента за запрос
duration_msnumberEnd-to-end latency in milliseconds
throughputnumberGeneration speed in tokens/sec
finish_reasonstringstop | length | content_filter | error
statusnumberКод статуса ответа BazaarLink
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://api.bazaarlink.ai/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"]))

Пожаловаться на отзыв

Помогите нам улучшить BazaarLink, сообщая о проблемах, ошибках или предложениях. Мы активно отслеживаем все каналы обратной связи.

Как сообщить

Канал
Наилучший вариант для
Время ответа
Страница контактовОбщие отзывы, пожелания по функциям1-2 рабочих дня
Электронная почтаОтчеты об ошибках, технические проблемыВ течение 24 часов
API Заголовки ответовАвтоматические отчеты об ошибках и показателяхАвтоматическая

Что включить

  • Идентификатор запроса (из поля идентификатора ответа)
  • Использованная модель и отправленные параметры
  • Ожидаемое и фактическое поведение
  • Временные метки и частота возникновения проблем
  • Сообщения об ошибках или коды состояния HTTP

Посетите нашу страницу контактов, чтобы оставить отзыв.

FAQ

Чем BazaarLink отличается от прямого вызова OpenAI?
BazaarLink обеспечивает выставление счетов USD с ценами, указанными в NTD, унифицированными счетами, поддержкой в ​​Китае и единым API для всех основных моделей. Вы можете получить доступ к OpenAI, Anthropic, Google и другим сервисам с помощью одного и того же кода.
Нужно ли мне изменить существующий код?
Просто измените базовый ключ URL и API. Все остальные настройки (кроме идентификаторов моделей) остаются неизменными.
Хранит ли BazaarLink мои сообщения?
При обычных успешных запросах мы не сохраняем содержимое сообщений; храним только записи об использовании, необходимые для расчётов и эксплуатации (например, модель, число токенов, время и стоимость). Неудачные запросы, механизмы безопасности контента, задачи с видео и др. и включаемые вами функции — исключения, описанные в Политике конфиденциальности; режим ключа ZDR обеспечивает более строгое нулевое хранение данных.
Как мне получить единый счет (統一發票)?
Тайваньский электронный инвойс доступен только через фактически предлагаемый способ, отмеченный как подходящий при оплате, либо по подтверждённому корпоративному соглашению. Проверьте актуальную страницу до оплаты или заранее свяжитесь с отделом продаж для налогового номера, предложения или ежемесячного расчёта.
Какие способы оплаты поддерживаются?
Принимаются все основные кредитные карты (Visa, Mastercard, American Express).
Какие функции OpenAI SDK поддерживаются?
Завершение чата, потоковая передача, вызов инструментов, структурированный вывод (response_format) и предварительное заполнение помощником всей работы. Функции передаются вышестоящему провайдеру.
Могу ли я использовать BazaarLink с такими платформами агентов, как LangChain или CrewAI?
Да! Любая платформа, поддерживающая OpenAI API, работает с BazaarLink. Просто установите базовый URL и используйте ключ BazaarLink API. Примеры см. в разделе «Использование агентов».
Поддержка
Поддержка
Здравствуйте! Чем мы можем помочь?
Отправьте сообщение, и мы ответим в ближайшее время.