Содержание12
- 1С чего начать
- 2Ключи: выпуск, замена, утечка
- 3Ответы шлюза, лимиты и квоты
- 4Как проверить свою обработку отказов
- 5Отладка: журнал вызовов и трасса
- 6Цепочки вызовов
- 7Уведомления о событиях
- 8Закрытые и партнёрские API
- 9Приложения, роли и журнал организации
- 10Калькулятор и доска запросов
- 11Что показывает кабинет
- 12Счета
1С чего начать
- 1Найдите API в каталоге. Публичные видны без регистрации, поиск идёт по названию, описанию и категории.
- 2Нажмите «Попробовать» на странице API: ответ придёт из спецификации, без ключа и без регистрации. Это мок — апстрим не вызывается и денег не стоит.
- 3Зарегистрируйтесь и создайте приложение. Приложение — это то, чему принадлежат ключи и подписки: обычно одно на сервис, а не одно на человека.
- 4Подпишитесь на нужный тариф. Бесплатный тариф, если он есть у API, подключается так же.
- 5Выпустите ключ. Он показывается один раз — сохраните сразу, второй раз его не покажет никто.
- 6Скопируйте фрагмент кода со страницы API: curl, TypeScript или Python с уже подставленными параметрами. Там же скачивается готовый клиент для TypeScript, Python или Go — архивом, а не пакетом: в npm и PyPI мы ничего не публикуем.
Первый вызов
curl 'https://apihub.tw1.su/v1/demo-geo/geocode?q=Тверь' \ -H 'X-API-Key: ahk_live_…'
Один домен на все API: меняется только первый сегмент пути после /v1. Ключ можно передать и как Bearer-токен. В строке запроса ключ не принимается намеренно — адрес попадает в историю браузера, в закладки и в журналы всех прокси по дороге.
2Ключи: выпуск, замена, утечка
Ключ принадлежит приложению, и подписки тоже. Один ключ открывает все API, на которые подписано его приложение, и ровно в тех пределах, что задают их тарифы. Мы храним только отпечаток ключа, поэтому показать его второй раз невозможно физически, а не по правилам.
| Что | Значение |
|---|---|
| Вид | ahk_live_ или ahk_test_, 20 символов секрета и 6 символов контрольной суммы |
| Контрольная сумма | Нужна не нам, а сканерам утечек: без неё ключ неотличим от случайной строки |
| LIVE | Вызовы идут в настоящий апстрим и попадают в счёт |
| TEST | Вызовы никогда не доходят до апстрима: ответ собирается из спецификации |
| Отзыв | Действует сразу, а не по истечении кэша |
Если ключ повреждён при копировании — обрезан, с переносом строки или лишним пробелом, — шлюз отвечает malformed_api_key, а не «ключ неизвестен». Разница важная: во втором случае вы пошли бы проверять права и отзывы, то есть искать не там.
Замена ключа делается одной кнопкой и без простоя: новый ключ выдаётся сразу, старый работает ещё сутки. Раскатайте новый по своим серверам и не делайте ничего больше — старый погаснет сам.
- Платформа следит за тем, откуда зовут ваш ключ. Вызов с незнакомого адреса, частота вдесятеро выше обычной для этого ключа, вызовы из разных сетей в одну минуту — три признака, по которым мы придерживаем ключ до одного запроса в секунду и сообщаем вам.
- Придерживаем, а не отзываем: ваш переезд на новый сервер выглядит для проверки ровно как утечка, и отзыв по подозрению сломал бы работающую интеграцию. Отзываете вы.
- На странице приложения видно, откуда звали каждый ключ, сколько раз и когда адрес встретился впервые. Свои серверы отметьте кнопкой «это мой сервер»: отмеченный адрес перестаёт считаться новым, и проверка больше не тревожит вас из-за него.
- Адрес, которого вы не узнаёте, — повод заменить ключ, а не гадать.
3Ответы шлюза, лимиты и квоты
| Код | Что случилось | Что делать |
|---|---|---|
| missing_api_key | Ключа нет в запросе, а API не публичный | Заголовок X-API-Key или Bearer-токен |
| malformed_api_key | Ключ нашего вида, но контрольная сумма не сходится | Скопируйте ключ заново целиком |
| invalid_api_key | Ключ неизвестен, отозван или истёк | Выпустите новый |
| not_subscribed | Ключ верный, но приложение не подписано на этот API | Оформите подписку |
| rate_limit_exceeded | Превышен предел запросов в секунду | Притормозите и повторите |
| quota_exceeded | Исчерпана месячная квота жёсткого тарифа | Дождитесь нового периода или смените тариф |
| upstream_timeout | Апстрим провайдера не ответил в срок | Не тарифицируется; смотрите «наши замеры» на странице API |
| upstream_unavailable | Апстрим ответил ошибкой или недоступен | Не тарифицируется |
| api_not_found | По этому адресу нет опубликованного API | Проверьте первый сегмент пути после /v1 |
В каждом ответе шлюза есть X-Request-Id — идентификатор именно этого вызова. Это первое, что стоит назвать в обращении в поддержку: по нему поднимается вся трасса. У успешных вызовов есть и остатки: X-RateLimit-Limit, X-Quota-Limit, X-Quota-Remaining.
Жёсткий лимит означает 429 на границе квоты. Мягкий пропускает вызовы сверх квоты и тарифицирует их по цене перерасхода, указанной в тарифе. Какой у вашего тарифа — написано в его карточке до подписки, а не после первого счёта.
Ответ, отданный из кэша площадки, помечен заголовком X-Apihub-Cache: hit. Квоту он не расходует, а стоит столько, сколько указано в тарифе отдельной строкой — обычно заметно меньше вызова, а часто и вовсе ноль. Что кэшируется и насколько, решает провайдер и объявляет в спецификации.
4Как проверить свою обработку отказов
Интеграция, которую не проверяли на отказах, ломается в первый же плохой день у провайдера. Проверить это можно, не дожидаясь плохого дня и не трогая настоящий апстрим.
Тестовый ключ плюс имитация задержки и ошибок
curl 'https://apihub.tw1.su/v1/demo-geo/geocode?q=Тверь' \ -H 'X-API-Key: ahk_test_…' \ -H 'X-Sandbox-Chaos: latency=2000,error=503,rate=0.3'
- latency — задержка в миллисекундах перед ответом, error — код, который вернуть, rate — доля вызовов, к которым это применяется.
- Действует только на моках, то есть на тестовых ключах и анонимных пробах. Дать возможность подмешивать ошибки в настоящий трафик значило бы дать способ вредить провайдеру.
- Вызовы тестовым ключом не стоят денег и не расходуют квоту.
5Отладка: журнал вызовов и трасса
В журнале виден каждый ваш вызов: код ответа, время, стадии. Раскрыв запись, вы увидите трассу — сколько заняла проверка ключа, квота, апстрим и наша собственная работа отдельной цифрой, а не спрятанная в «прочее».
- Заголовки и тела видны, только если провайдер включил захват. Записывается выборка успешных вызовов и все ошибочные: отлаживают именно неудачные.
- Два вызова можно сравнить между собой. Сравнение структурное: другой порядок ключей и отступы в JSON расхождением не считаются, а пропавшее поле — считается.
- Экспорт в curl готов к вставке в терминал. Ключ в нём не подставлен: мы его не храним, и заглушка вместо него вводила бы в заблуждение.
- Спор «ваш API не работает» — «вы шлёте неверный запрос» кончается здесь: видно, что именно ушло на апстрим и что он ответил.
6Цепочки вызовов
Цепочка превращает несколько вызовов в один ваш эндпоинт: выход одного API идёт на вход другому. Собирается формой, без кода, и живёт в разделе потребителя, потому что принадлежит тому, кто её вызывает.
Вызов цепочки
curl 'https://apihub.tw1.su/w/card-from-address?address=Тверь, Советская 12' \ -H 'X-API-Key: ahk_live_…'
- Каждый шаг — обычный тарифицируемый вызов по вашей подписке, с вашей квотой и в вашем счёте. Собрать цепочку из API, на который вы не подписаны, нельзя.
- Шаги, не зависящие друг от друга, выполняются одновременно. Порядок платформа выводит сама из того, кто чьи поля читает.
- Если шаг отказал, цепочка останавливается и называет упавший шаг. Шаги, успевшие отработать, остаются в счёте: их провайдеры свою работу сделали, и не платить за неё было бы просто способом не платить.
- Есть режим замены: провайдеры пробуются по очереди, побеждает первый ответивший. Ответ каждого приводится к общей форме, которую задаёте вы, — иначе смена провайдера означала бы правку вашего кода.
- В заголовке ответа X-Apihub-Workflow-Steps видно, сколько шагов выполнено, а X-Apihub-Workflow-Skipped — сколько пропущено.
7Уведомления о событиях
Платформа сообщает о событиях на ваш адрес: выпуск новой версии API, ломающее изменение, исчерпание квоты, выставленный счёт, подозрение на утечку ключа. Почты нет — только вебхук, и это осознанно: машинный канал не теряется в папке «Промоакции».
Проверка подписи на вашей стороне
// X-Apihub-Signature: t=1786377351,v1=9f8c…
const [t, v1] = header.split(',').map((p) => p.split('=')[1]);
const expected = hmacSha256(secret, `${t}.${rawBody}`);
if (!timingSafeEqual(expected, v1)) reject();
if (Math.abs(now() - Number(t)) > 300) reject(); // старый запрос- Метка времени входит в подпись: перехваченный вчерашний запрос не выдать за свежий.
- Доставка «хотя бы один раз». В заголовке X-Apihub-Delivery есть идентификатор, по которому вы отличите повтор, — обрабатывайте события идемпотентно.
- Семь попыток с задержкой от минуты до суток. Дальше доставка уходит в недоставленные, и её видно в журнале доставок рядом с адресом — оттуда же она повторяется кнопкой.
- Адрес можно выключить, не удаляя: события перестают уходить, история доставок остаётся. Адрес, который отказывает подряд слишком долго, выключается сам — иначе очередь копилась бы в пустоту.
- Адрес должен быть внешним: на внутренние адреса мы не ходим. Секрет показывается один раз при создании адреса.
8Закрытые и партнёрские API
Публичный каталог — не единственный способ отдавать API. Провайдер может держать его закрытым и выдать доступ вашей организации поимённо; тогда API появится у вас в разделе «Доступные по приглашению», а в общем каталоге его не будет.
- Доступ выдаётся организации, а не человеку: сотрудник уходит — доступ остаётся у компании.
- Отзыв доступа гасит ваши подписки на этот API сразу. Всё, что уже отработано, остаётся в счёте.
- Ваш идентификатор для выдачи доступа — короткое имя организации; оно видно в настройках.
9Приложения, роли и журнал организации
Приложение — то, чему принадлежат ключи и подписки. Обычно одно на ваш сервис, а не одно на человека: так счёт читается по сервисам, а уход сотрудника ничего не ломает.
- Удаление приложения отзывает его ключи и гасит его подписки. За уже отработанное счёт придёт: подписка гасится, а не стирается.
- Журнал действий организации показывает, кто и что делал: выпуск и отзыв ключей, подписки, отписки, адреса вебхуков, отметки адресов ключа. Записи неизменяемы и хранятся год.
- В журнале виден автор каждой записи. У задачи по расписанию автора нет вовсе, и она так и помечена.
| Роль | Что может |
|---|---|
| OWNER | Всё, включая деньги: счета, выплаты, смену тарифов |
| ADMIN | Всё, кроме владения организацией |
| DEVELOPER | Приложения, ключи, подписки, отладка. Денег не видит |
Позвать сотрудника можно на экране «Сотрудники»: адрес почты и роль. Почты у платформы нет, поэтому ссылку вы передаёте сами — тем способом, которому доверяете.
- Приглашение именное: принять его может только тот, кто вошёл под указанным адресом. Пересланное чужому оно не сработает — роль здесь открывает доступ к ключам и счетам, и пропуск на предъявителя тут слишком дёшев.
- Ссылка показывается один раз, живёт неделю и отзывается кнопкой. Действующее приглашение на один адрес одно: иначе «пригласить» нажимают трижды и потом гадают, какая ссылка настоящая.
- Роль владельца приглашением не выдаётся: владелец в организации один, и его смена — отдельное действие.
- Убрать сотрудника может владелец или администратор. Уходит членство, а не учётная запись: человек уходит из компании, а его следы в журнале остаются с его именем.
- Себя убрать или понизить нельзя — вернуть доступ было бы некому.
10Калькулятор и доска запросов
Два инструмента, которые не требуют ни ключа, ни регистрации, и оба существуют до того, как вы что-то выбрали.
- Калькулятор считает, во что обойдётся ваш объём на разных тарифах одного и разных API: вводите вызовы в месяц и видите итог по каждому, включая перерасход. Сравниваются тарифы внутри площадки, а не наши цены с прямыми ценами провайдеров: назвать вторые может только сам провайдер, а он не введёт число, которое покажет нас дороже.
- Доска запросов — чего людям не хватает. Если нужного API в каталоге нет, напишите туда: запрос виден провайдерам, за него голосуют, и по числу голосов видно спрос. Читать доску можно без регистрации — спрос должен видеть тот, кто как раз решает, приходить ли сюда.
11Что показывает кабинет
- Сводка: вызовы, доля успешных и график по дням за сутки, неделю или месяц. Период переключается, и данные за него считаются заново, а не подкрашиваются.
- Подписки с остатком квоты — то же число, что шлюз возвращает в заголовке X-Quota-Remaining.
- Журнал вызовов и трасса — отдельным экраном, о нём ниже.
- Счета и выплаты — только чтение. Кнопки «оплачено» в кабинете получателя нет намеренно: должник, закрывающий собственный долг сам, — это не право доступа, а дыра.
12Счета
- Счёт выставляется за календарный месяц и только после того, как сошлась сверка. Не сошлась — счёт не выставляется, пока не разберёмся: счёт по неполным данным хуже, чем поздний.
- В счёте есть разбивка: по каждому API — сколько вызовов, по какой цене, сколько абонплаты и сколько перерасхода. Итог без разбивки можно только принять на веру или оспорить целиком.
- Абонплата берётся, даже если вызовов не было: она за то, что площадка держит инфраструктуру, а не за объём.
- Смена тарифа посреди месяца делит и абонплату, и квоту по дням — иначе смена тарифа удваивала бы бесплатный объём.
- Суммы берутся из книги операций и нигде не пересчитываются: второе число рядом с расчётом однажды разошлось бы с первым.
- Выставленный счёт не меняется никогда. Исправление — аннулирование с причиной и новый счёт.
- Отписка прекращает доступ сразу, но за уже отработанный период счёт придёт: подписка гасится, а не стирается.