API-ключи
Ключ — это доступ к вашему балансу. Создаётся в консоли за секунды, показывается один раз, отзывается мгновенно.
Как создать ключ
Откройте консоль, перейдите в раздел «Ключи» и нажмите «Создать ключ». Форма спрашивает имя — назовите ключ по
сервису и окружению, которые им пользуются: backend-prod,
bot-staging, analytics-batch. Ключей может быть сколько угодно,
баланс у них общий.
- Секрет показывается один раз. Сразу после создания — и больше никогда. Скопируйте его в хранилище секретов, не откладывая на потом.
- У нас хранится только хеш. В базе лежит криптографический хеш ключа, префикс для опознания в списке и метаданные: имя, дата создания, дата последнего использования. Восстановить секрет технически невозможно — ни вам, ни поддержке.
- Потеряли — выпустите новый. Это занимает секунды и не требует обращения в поддержку. Старый ключ отзовите, чтобы он не висел рабочим.
- Отзыв мгновенный. Отозванный ключ перестаёт работать сразу, включая запросы, которые в этот момент только собирались уйти. Уже начатые ответы досчитываются.
Формат ключа и заголовок
Ключ состоит из префикса sk-td- и 32 символов латиницы и цифр. Префикс нужен, чтобы
ключ TokenDock опознавался глазом и сканерами секретов в репозиториях.
- Формат
- sk-td-{32 символа}
- Пример
- sk-td-4f9c1a2e8b7d3056a1c9e4f2b8d70a63
- Заголовок
- Authorization: Bearer sk-td-…
- Где виден
- В списке ключей — только префикс: sk-td-4f9c…0a63
- Протокол
- Только HTTPS. Запрос по HTTP отклоняется до проверки ключа
Ключ передаётся в заголовке Authorization по схеме Bearer — так же, как у OpenAI.
Query-параметров с ключом нет и не будет: они утекают в логи прокси и историю браузера.
curl https://api.tokendock.cloud/v1/models \
-H "Authorization: Bearer sk-td-4f9c1a2e8b7d3056a1c9e4f2b8d70a63" В рабочем коде ключ подставляется из переменной окружения. Так его не видно в истории команд, в дампе конфигурации и в скриншотах терминала.
# Ключ живёт в переменной окружения, а не в коде
export TOKENDOCK_API_KEY="sk-td-4f9c1a2e8b7d3056a1c9e4f2b8d70a63"
curl https://api.tokendock.cloud/v1/chat/completions \
-H "Authorization: Bearer $TOKENDOCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "openai/gpt-4.1-mini", "messages": [{"role": "user", "content": "ping"}]}' import os
from openai import OpenAI
# KeyError на старте лучше, чем 401 в проде под нагрузкой
client = OpenAI(
base_url="https://api.tokendock.cloud/v1",
api_key=os.environ["TOKENDOCK_API_KEY"],
) Хорошие практики
Правила простые и скучные — именно поэтому они работают. Каждое из них уменьшает радиус поражения, если ключ всё-таки утечёт.
- Переменные окружения, а не код. В проекте —
.env, добавленный в.gitignore. На сервере и в CI — штатное хранилище секретов, а не переменные в конфиге сборки и не файл рядом с деплоем. - Отдельный ключ на окружение и сервис. Прод, стейджинг, локальная разработка, каждый бэкенд-сервис — свой ключ. Тогда отзыв одного ключа не останавливает всё остальное, а в расходах видно, кто сколько потратил.
- Ротация по расписанию. Раз в квартал и обязательно при уходе человека, у которого был доступ. Порядок без простоя: выпустить новый ключ, выкатить его, убедиться по расходам, что старый больше не используется, отозвать старый.
- Немедленный отзыв при сомнении. Ключ мелькнул в скриншоте, в тикете, в логе CI — отзывайте. Новый ключ стоит минуту работы, разбор чужих трат — гораздо дороже.
- Никогда в клиентском коде. Ключ в браузерном JavaScript, в мобильном приложении или в десктопном клиенте — это ключ, отданный пользователю: он виден в исходниках бандла и в панели сети. Ходите в API со своего бэкенда, а клиенту отдавайте собственный короткоживущий токен.
- Никаких общих ключей. Один ключ на команду в общем чате невозможно ни отозвать без боли, ни сопоставить с расходом.
Прокси-слой на своей стороне решает сразу три задачи: ключ остаётся на сервере, к запросу добавляется авторизация вашего пользователя, а расход считается по вашим правилам. Если продукт публичный, это единственный безопасный вариант.
Лимиты и бюджет на ключ
Ключ — это не только доступ, но и рамка расхода. Ограничения задаются в консоли на карточке ключа и действуют поверх аккаунтских лимитов: ключ не может получить больше, чем разрешено аккаунту.
- Месячный бюджет. Потолок расхода в рублях. Исчерпан — ключ отвечает 402, остальные ключи работают.
- Дневной лимит. Страховка от разогнавшегося цикла: ограничивает расход за сутки, обнуляется в полночь по московскому времени.
- RPM и TPM ключа. Собственные пороги ниже аккаунтских — чтобы фоновая задача не съедала окно у продуктового трафика.
Бюджет — это ограничение, а не блокировка аккаунта: остальные ключи продолжают работать, данные и настройки остаются на месте. Как только вы поднимете потолок, ключ снова начнёт отвечать.
Лимиты и квоты целикомЧто делать при утечке
Порядок действий один и тот же, попал ли ключ в публичный репозиторий, в чужой скриншот или в лог стороннего сервиса. Первый шаг делайте сразу, остальные — следом.
Не пытайтесь «проследить», используют ли ключ, прежде чем отозвать его. Отзыв бесплатен и обратим выпуском нового ключа — потраченный чужими запросами баланс не обратим.
Что мы храним
По каждому запросу сохраняются только метаданные — того минимума, что нужен для тарификации, детализации расходов и разбора инцидентов. Тело запроса и тело ответа не сохраняются: промпты, сообщения, документы и сгенерированный текст в наши логи не попадают.
- Время запроса
- Дата и время с точностью до секунды
- Ключ
- Идентификатор и префикс ключа, которым сделан запрос
- Модель
- id модели из каталога
- Токены
- Число входных и выходных токенов из поля usage
- Стоимость
- Сумма списания по строке расхода
- Технические поля
- HTTP-код ответа, длительность запроса, request_id
- Секрет ключа не хранится ни в каком виде — только его хеш и префикс.
- Метаданные нужны, чтобы вы видели расход по каждому ключу и модели, а поддержка могла найти запрос по
request_id. - Провайдер, который выполняет запрос, обрабатывает содержимое по своим правилам — это отдельный от нас слой.