API ключей и лимитов

Создание, отзыв и настройки ключей через API.

Создать ключ

curl
curl https://api.closerouter.dev/v1/keys \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production worker",
    "is_anonymous": false,
    "max_price": { "input": "1", "output": "4" },
    "max_price_by_model": {
      "openai/gpt-5.4-mini": { "cache_read": "0.1" }
    },
    "spend_limit": {
      "amount_usd": "25",
      "period": "monthly"
    }
  }'

Получить список ключей

curl
curl https://api.closerouter.dev/v1/keys \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY"

Изменить максимальные цены

curl
curl https://api.closerouter.dev/v1/keys/{key_id}/limit \
  -X PATCH \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "max_price": { "input": "0.5" },
    "max_price_by_model": {
      "openai/gpt-5.4-mini": { "cache_read": "0.1", "cache_write": "0.5" }
    }
  }'

Снять лимиты

curl
curl https://api.closerouter.dev/v1/keys/{key_id}/limit \
  -X PATCH \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "spend_limit": null, "max_price": null, "max_price_by_model": {} }'

Отозвать ключ

curl
curl https://api.closerouter.dev/v1/keys/{key_id} \
  -X DELETE \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY"

Auto ключа

При создании в кабинете выбор Auto скрыт в «Дополнительных настройках». По умолчанию ключ наследует настройки модели и аккаунта, без Auto-подписи. В меню с тремя точками можно изменить режим существующего ключа.

POST /keys принимает необязательное auto_strategy: "cheap" | "fast" | "stable" | null. Без поля или при null ключ наследует настройки. Явный режим сохраняется буквально, даже если совпадает с режимом аккаунта, и показывает бейдж.

PATCH /keys/{key_id}/auto принимает {"auto_strategy":"fast"}; {"auto_strategy":null} возвращает наследование. Пропущенное или неизвестное значение даёт 400. На api.closerouter.dev требуется unrestricted API-ключ; на closerouter.dev/v1 — Dashboard JWT владельца. Настройка disabled ключа доступна через кабинет, revoked ключ — 404.

Приоритет и текущий режим

Приоритет: явный provider/strategy запроса → ручная цепочка → Auto ключа → Auto модели → Auto аккаунта → Cheap. Явный Auto в запросе обходит ручную цепочку. Закреплённый Auto ключа цепочку не обходит. Смена режима действует на новые запросы; текущие attempts/fallback сохраняют прежний план.

GET /providers и ответ PATCH /providers добавляют effective_auto_strategy и auto_strategy_source для текущего ключа; источник api_key означает закрепление. При ручной цепочке оба поля null. auto_strategy и auto_strategy_override сохраняют смысл настроек аккаунта и модели. PATCH /providers меняет настройку модели аккаунта, а не ключа. Справочные цены /models не меняются.

Разрешить выбранные модели

Удобнее выбрать модели в кабинете на странице ключей. REST-изменение доступно только с Dashboard JWT на closerouter.dev; обычный API-ключ не может расширить себе или соседнему ключу доступ.

curl
export CLOSEROUTER_DASHBOARD_TOKEN="your_dashboard_access_token"

curl https://closerouter.dev/v1/keys/{key_id}/model-access \
  -X PATCH \
  -H "Authorization: Bearer $CLOSEROUTER_DASHBOARD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model_access": {
      "type": "allowlist",
      "model_ids": [
        "anthropic/claude-haiku-4.5",
        "openai/gpt-5.4-mini"
      ]
    }
  }'

Разрешить все модели

Используйте Dashboard JWT владельца, как в предыдущем примере.

curl
curl https://closerouter.dev/v1/keys/{key_id}/model-access \
  -X PATCH \
  -H "Authorization: Bearer $CLOSEROUTER_DASHBOARD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "model_access": { "type": "all" } }'

Доступ к моделям

Новые и существующие ключи по умолчанию имеют model_access.type = "all".

allowlist принимает от 1 до 100 уникальных публичных ID моделей и атомарно заменяет предыдущий список; aliases сохраняются как канонические ID.

Если хотя бы одна модель из model и models[] запрещена, весь inference-запрос отклоняется с 403 api_key_model_access_denied до provider-вызова, usage и списания.

Права ограниченного ключа

Ограниченный ключ может читать GET /keys, но не может создавать, изменять или отзывать ключи: API возвращает 403 api_key_management_forbidden.

Лимиты расходов

Поле или действиеПравило
spend_limit.amount_usdspend_limit.amount_usd задается строкой в USD.
spend_limit.periodperiod может быть daily, weekly или monthly.
spend_limit: nullПередайте spend_limit: null, чтобы очистить лимит.
DELETE /keys/{key_id}DELETE /keys/{key_id} отзывает ключ; новые запросы с ним прекращаются сразу.

Максимальная цена

На странице /keys откройте «Лимиты ключа» и включите максимальную цену. Поиск по названию или ID находится над единым списком. Раскройте общие лимиты или строку модели: входные, выходные токены, запись и чтение кеша настраиваются вместе. Пустое поле модели наследует общий лимит. Нажмите «Сохранить». Цена и бюджет расходов настраиваются независимо.

POST /keys, GET /keys и PATCH /keys/{key_id}/limit используют max_price для общих настроек и max_price_by_model для объекта {"Model ID": {"input": "1"}}. До 100 моделей; aliases сохраняются как канонические публичные Model ID.

input, output, cache_read и cache_write необязательны: строки или числа в USD за миллион токенов, от 0, до 8 знаков после точки и 12 цифр до точки. Ноль — реальный нулевой предел; пустой объект не задаёт ограничений.

Наследование и изменение

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

При PATCH пропущенные верхние поля сохраняются. Переданный max_price полностью заменяет общие поля, а max_price_by_model — весь список моделей и их поля. max_price: null очищает общие настройки; max_price_by_model: {} или null очищает модельные. Для удаления одного поля или модели передайте полный оставшийся объект. Изменение только цен сохраняет spend_limit, и наоборот.

В /chat/completions, /responses и /messages передайте, например, "max_price": {"input": 0.5, "cache_read": 0.1}. Это работает для обычных и потоковых запросов, Auto, явного провайдера и разрешённых запасных попыток; поле не передаётся поставщику.

Проверка тарифа

Сравниваются максимальные клиентские ставки по базовому тарифу и всем ступеням контекста. Для cache_write берётся кратчайший доступный TTL, а не самая низкая цена: длинный TTL в запросе может оплачиваться выше этого предела. Если отдельных цен кеша нет, применяется обычная ставка входа. Подтверждённая бесплатная акция учитывается как $0; без неё действует обычный тариф.

Цена, равная пределу, допускается. Если ни один доступный маршрут не подходит, API возвращает 422 max_price_no_route до вызова поставщика, без списания. Неверный объект или цена дают 400 invalid_request. Эти настройки относятся только к текстовым моделям.

В error.metadata.price_limit указаны unit: usd_per_million_tokens, comparison: maximum_across_context_tiers и cache_write_comparison: shortest_available_ttl. models содержит публичный model, действующие limits и целые тарифы tariffs: base_rates, compared_rates и exceeded_fields. Например, при input: 0.061 базовая ставка 0.06 не проходит, если ставка длинного контекста 0.12: compared_rates.input будет строкой 0.12, а exceeded_fields — [input]. Цены передаются точными десятичными строками; ставка 0 сохраняется.

scope: request_selection означает только тарифы, рассмотренные с параметрами этого запроса, а не весь каталог или гарантию доступности. selection: primary относится к основному плану, recovery_only — только к аварийному восстановлению Auto. Диагностика ограничена пятью моделями, пятью тарифами на модель и 16 КиБ; truncated отмечает сокращение. Цена другого тарифа не смешивается с этим тарифом. Проверка перед запасной попыткой описывает только её тариф и не обещает отсутствия расходов на предыдущие попытки.