Руководство apiton
Как получать уведомления об адресе TON через API
v2.Watch в API apiton следит за адресом вместо вас, и вашему коду не
нужно читать блокчейн в цикле. Вы называете адрес, а apiton сохраняет событие на каждое изменение и
присылает его на ваш сервер или хранит, пока вы его не заберёте. Если код не нужен вовсе, уведомления
в Telegram присылает @apitonBot: нажмите 🔔 Следить в карточке.
Подписка — это один адрес, а что это за адрес, сервер определяет сам:
- NFT: юзернейм Telegram, номер +888, домен .ton, подарок или любой другой NFT. Отслеживаются продажа и аукцион.
- Любой другой адрес: отслеживаются его транзакции от выбранной вами суммы.
| Событие | Что значит |
|---|---|
listed |
выставлен на продажу |
price |
изменилась цена продажи |
delisted |
продажа или аукцион закончились, владелец тот же |
sold |
продажа или аукцион закончились, владелец новый |
auction_start |
начался аукцион |
bid |
более высокая ставка |
auction_ending |
до конца аукциона меньше 2 часов |
tx |
транзакция кошелька |
1. Получите ключ
Отправьте /get_api боту @apitonBot. Ключ выглядит как 123456789:aB3dE…
и передаётся в заголовке Authorization: Bearer каждого вызова. Бесплатного ключа достаточно. Без
ключа v2.Watch отвечает unauthenticated: у подписки должен быть владелец.
2. Создайте подписку
curl -X POST https://app.apiton.org/v2.Watch/Create \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 123456789:aB3dE…' \
-d '{"address":"UQCdqXGvONLwOr3zCNX5FjapflorB6ZsOdcdfLrjsDLt3AF4",
"webhook_url":"https://example.com/apiton","min_amount":1}'
В ответе будут подписка и webhook_secret, начинающийся с whsec_. Он показывается один раз,
сохраните его сразу. Этим секретом подписаны доставки, и это не ваш API-ключ.
address: raw,EQ…илиUQ…, только основная сеть, без имён.ton. Конвертер адресов переводит одну форму в другую.webhook_url: необязательный. HTTPS на порту 443 или 8443, публичный хост. Редиректы не выполняются.min_amount: для кошелька — наименьшая сумма, которая создаёт событие, в GRAM, по умолчанию 1.0значит каждая транзакция.
Подписка начинается с текущего состояния: то, что случилось до Create, событий не создаёт.
3. Проверяйте подпись webhook
Каждое событие приходит как POST с JSON и заголовками X-Apiton-Signature, X-Apiton-Timestamp
и X-Apiton-Event-Id. Подпись — это sha256= и hex HMAC-SHA256 от <timestamp>.<body> на вашем
секрете. Проверяйте её по исходному телу запроса: если разобрать JSON и собрать заново, байты
будут другими.
import hashlib, hmac, time
def verify(secret: str, headers, body: bytes) -> bool:
ts = headers.get("X-Apiton-Timestamp", "0")
if abs(time.time() - int(ts)) > 300:
return False # повторно отправленный запрос
want = hmac.new(secret.encode(), ts.encode() + b"." + body, hashlib.sha256).hexdigest()
return hmac.compare_digest("sha256=" + want, headers.get("X-Apiton-Signature", ""))
- Сначала ответ, потом работа. Доставленной считается только доставка с ответом 2xx за 5 секунд, даже если ваша обработка успела закончиться.
- Отбрасывайте повторы. Доставка идёт как минимум один раз: если ваш 2xx потеряется, событие
придёт снова с тем же
id. - Проверьте через
Test. Он сразу отправит тестовое событие и скажет, что ответил ваш сервер:
curl -X POST https://app.apiton.org/v2.Watch/Test \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 123456789:aB3dE…' -d '{"id":"41"}'
4. Если ваш сервер недоступен
Неудачная доставка повторяется через 1, 5 и 30 минут, затем каждые 30 минут. Примерно через 24 часа
сбоев webhook ставится на паузу, и пока Test не пройдёт, ничего не отправляется. List показывает
состояние каждого webhook и последнюю ошибку. Ничего не теряется: события можно прочитать в течение
7 дней.
5. Без сервера: читайте по курсору
Не передавайте webhook_url. События всё равно сохраняются, и их может забирать скрипт или задача
в cron:
curl -X POST https://app.apiton.org/v2.Watch/Poll \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 123456789:aB3dE…' \
-d '{"after_id":"0","limit":50}'
Передавайте next_after_id как следующий after_id. Идентификаторы только растут, поэтому
сохранённый курсор не пропустит событие. Каждый Poll — это один запрос вашего плана, а доставки
webhook бесплатны. 10 000 запросов в месяц на бесплатном ключе — это один Poll раз в 4,5 минуты и
больше ничего.
6. Лимиты
| План | Подписок | Чтение адреса | Webhook в час | Цена за 30 дней |
|---|---|---|---|---|
| free | 3 | раз в 3 минуты | 10 | 0 |
| builder | 30 | раз в 30 секунд | 100 | 5 GRAM или 1 000 Stars |
| pro | 30 | раз в 30 секунд | 100 | 30 GRAM или 6 000 Stars |
События сверх часового лимита остаются в Poll. У Premium из бота здесь те же цифры, что у free.
Платные планы показывает /upgrade в @apitonBot.
7. Что ещё важно
- Смена статуса приходит на одно чтение позже. О
listed,soldи других сообщается, когда совпали два чтения подряд: одно неудачное чтение не создаст ложное событие. Ценам и ставкам хватает одного. - Загруженный кошелёк. Одно чтение возвращает до 16 транзакций. Кошелёк, у которого их между
двумя чтениями больше, получит 16 последних и
truncated: true; остальные читайте черезAddress/Transactions.
Полный обработчик есть в статье блога (на английском), а все поля описаны в справочнике на docs.apiton.org.