Аутентификация
Один заголовок, один ключ и небольшой набор ошибок, у каждой из которых свой конкретный смысл.
Заголовок
Передавайте ключ в заголовке X-API-Key в каждом запросе. Никакого OAuth, обмена токенами и обновления токенов нет.
curl -X POST https://api.occultapi.com/api/astro/tithi/ \
-H "X-API-Key: yt_live_a1b2c3d4_x9K2mQ7vB4nR8sL1wY6tZ3pC5hJ0dF" \
-H "Content-Type: application/json" \
-d '{ "date_time": "2026-09-16T06:00:00+05:30", "latitude": 26.9124, "longitude": 75.7873, "timezone_as_float": 5.5 }'Формат ключа
Ключ выглядит так: yt_live_a1b2c3d4_x9K2mQ7vB4nR8sL1wY6tZ3pC5hJ0dF — бренд, окружение, открытый префикс из восьми символов и затем секрет.
yt_live_…тратит настоящие кредиты с вашего баланса.yt_test_…— для разработки; в истории использования такие вызовы так и помечены.
Префикс открыт и индексируется намеренно: если ключ утечёт в публичный репозиторий, его можно найти и отозвать по одному префиксу, и секретная часть для этого никому не нужна.
Показывается один раз, хранится как хеш
Ключ показывается ровно один раз — при создании. Мы храним только его хеш SHA-256, поэтому восстановить ключ не сможет ни администратор, ни тот, кто получит дамп базы. Это значит, что и мы действительно не можем прислать его вам повторно. Потом вы видите только префикс и последние четыре символа — этого достаточно, чтобы различать ключи в списке.
Потеряли ключ? Создайте новый и отзовите старый. Это быстрее, чем писать нам, — и мы всё равно не смогли бы сделать ничего другого.
Ошибки — и какие из них не связаны с аутентификацией
Все ошибки приходят в стандартном формате с is_error: true и стабильным машинным кодом в message. Опирайтесь на код, а не на текст.
| Статус | message | Что это значит | Что делать |
|---|---|---|---|
| 401 | invalid_api_key | Ключа нет, он искажён, отозван или просрочен. | Убедитесь, что заголовок X-API-Key действительно до нас доходит. Если вы меняли ключ, разверните новый. |
| 402 | insufficient_credits | Ключ в порядке. Баланс пуст. | Повысьте тариф или дождитесь ежемесячного обновления квоты. Это не ошибка аутентификации — перевыпуск ключа не поможет. |
| 403 | endpoint_not_allowed | Этот маршрут недоступен для API-ключей: неверный путь или метод либо эндпоинт выведен из работы. | Сверьте маршрут и метод со справочником. Не помогут ни повторный запрос, ни новый ключ. |
| 403 | scope_not_allowed | У ключа нет прав (scope), нужных этому эндпоинту. | Создайте ключ с нужными правами или оставьте список прав пустым — тогда доступны все. |
| 403 | ip_not_allowed | Для ключа задан список разрешённых IP, а запрос пришёл с адреса, которого в нём нет. | Отправляйте запросы с разрешённого IP или создайте ключ с нужными адресами — либо вовсе без них, чтобы разрешить любые. |
| 403 | account_suspended | Аккаунт заблокирован, поэтому все его ключи отклоняются. | Напишите в поддержку. Перевыпуск ключа не поможет. |
| 429 | api_key_rate_limited | Слишком много запросов за минуту с этого ключа. | Сделайте паузу и повторите запрос через столько секунд, сколько указано в заголовке Retry-After. |
| 400 | (ошибки в полях) | Ошибка в теле запроса. В message названо каждое неверное поле. | Прочитайте message — там всё конкретно. Кредиты не списываются. |
Повторим главное: 402 — это не ошибка аутентификации. Ключ в порядке, просто баланс пуст. Типичная ошибка — перевыпустить ключ, но это ничего не меняет.
Заголовки с кредитами
В каждом ответе указано, сколько стоил вызов и сколько осталось, — следить за расходом можно без дополнительного запроса.
X-Credits-Cost: 1 # what this endpoint costs
X-Credits-Charged: 1 # what you were actually billed — 0 on any error
X-Credits-Remaining: 149 # balance after this callЛогировать стоит X-Credits-Charged. У неудачного запроса там всегда 0: кредит резервируется до начала расчёта и возвращается, если расчёт не завершился чисто, поэтому, пока вы отлаживаете интеграцию, её ошибки не опустошат баланс.
Лимиты запросов
Лимиты действуют на каждый ключ в отдельности, считаются поминутно и нужны, чтобы ограничить ущерб от утёкшего ключа, а не чтобы урезать вас. При превышении вы получите 429 с заголовком Retry-After в секундах — подождите это время, а не повторяйте запрос сразу. В ответах также есть X-RateLimit-Limit и X-RateLimit-Remaining.
За ответ 429 кредиты никогда не списываются. Если вы упираетесь в лимит при обычной работе, попросите нас его поднять.
Как защитить ключ
- Вызывайте API с сервера, а не из браузера. Ключ во фронтенд-бандле или в мобильном приложении — открытый, как бы он ни назывался. Кто угодно может его прочитать и потратить ваш баланс.
- Храните ключ в переменной окружения или менеджере секретов. Никогда не коммитьте его.
- Заведите отдельные ключи для каждого окружения, чтобы отзыв одного не ронял остальные.
- Меняйте ключ так: создайте новый, разверните его и только потом отзовите старый. Именно в таком порядке — тогда ничего не простаивает.
- Если ключ мог утечь, сразу отзовите его. Отзыв действует мгновенно, а оставшиеся кредиты никуда не денутся.
Всё это настраивается на странице ключей.