Основы
Адрес и версии
Все пути — под https://soroka.tools/v1. Версия — в пути. Внутри v1 изменения только совместимые: новые
пути, новые необязательные поля запроса, новые поля ответа, новые значения kind и code в
ошибках. Поэтому незнакомые поля ответа нужно игнорировать, а незнакомый kind обрабатывать как
platform_unknown.
Несовместимое — только в /v2. Путь, который уходит, получает заголовки Deprecation и
Sunset не меньше чем за 90 дней;
дата и замена — в журнале изменений.
Ключи и права
Каждый запрос несёт ключ в заголовке:
Authorization: Bearer <ключ>
- Ключ показывается полностью один раз, у нас хранится только его отпечаток. Потерялся — выпустите новый, старый отзовите.
- Один ключ — один сервис. Нужны разные права — разные ключи.
- Ключу можно задать срок жизни и список разрешённых адресов (CIDR): запрос с другого адреса получит
403 ip_not_allowed. - Ключ — в секретах сервиса, не в коде и не в логах. В логах допустим только префикс.
Права ключа (scopes):
| право | что даёт |
|---|---|
tg:read | чтение Telegram: сущности, история, диалоги |
tg:people | данные о людях в Telegram: участники, профили, фото, реакции и голоса поимённо |
tg:stream | поток обновлений (слушатели чатов) |
tg:join | вступление в чаты/каналы и выход из них |
tg:write | отправка сообщений, удаление диалогов |
tg:media | скачивание медиа |
vk:read | методы VK на чтение и страницы vk.com |
vk:people | данные о людях во ВКонтакте: профили, друзья, участники сообществ |
vk:write | методы VK на запись |
proxy:lease | аренда прокси для своих HTTP-запросов |
jobs | долгие задачи и их результаты |
webhooks | вебхуки событий организации: адреса, тест, журнал доставок |
Нет права — 403 auth_failed, code=no_scope, в поле missing — каких прав не хватает.
Действующие права ключа показывает GET /v1/me.
Форматы
- Запросы и ответы — JSON в UTF-8. Потоки — NDJSON (
application/x-ndjson, объект на строку) и SSE (text/event-stream). - Время — ISO-8601 в UTC (
2026-09-22T19:00:00Z), длительности — целые секунды. - Наши идентификаторы (подписки, задачи) — UUID строкой, события — целое строкой (
"18446"). - Канал или чат в запросе:
@name,https://t.me/nameилиpeer_idчислом (канал —-100…). - Тело запроса — не больше 1 МБ, больше —
413 payload_too_large.
Пагинация
Списки отдаются страницами по курсору:
GET https://soroka.tools/v1/jobs?limit=50&cursor=eyJpZCI6…
→ {"items": [...], "next_cursor": "eyJpZCI6…"}
limit — от 1 до 500 (по умолчанию 50). Курсор непрозрачный: не разбирайте и не собирайте его сами,
он живёт сутки. next_cursor: null — страниц больше нет. Порядок — от новых к старым. События
подписок листаются не курсором, а after — номером последнего события.
Заголовки ответа
| заголовок | смысл |
|---|---|
X-Request-Id | идентификатор запроса; он же в теле ошибки. Можно прислать свой (до 64
символов A-Z a-z 0-9 _ -). Называйте его в поддержке. |
X-RateLimit-Limit | лимит ключа в минуту |
X-RateLimit-Remaining | сколько осталось в текущей минуте |
X-RateLimit-Reset | секунд до начала следующей минуты (окно — календарная минута UTC) |
X-Quota-Limit, X-Quota-Remaining | суточная квота ключа, если задана, и остаток |
Retry-After | на 429 и 503: через сколько секунд повторить |
X-Soroka-Account | метка аккаунта, который выполнил вызов Telegram или ВКонтакте |
Подробно о лимитах, квотах и кредитах — «Лимиты и кредиты».
Задачи
Задача — долгий сбор, который мы выполняем целиком: POST /v1/jobs отвечает сразу
(202, job_id), дальше задача идёт queued → running →
done (или failed, cancelled). Готовый результат —
GET /v1/jobs/{job_id}/result?format=json|csv|xlsx. Цену «от–до» до запуска показывает
POST /v1/jobs/estimate; сколько списано — result_summary.credits в карточке.
Шаблоны сбора ("kind": "parser.preset", ключ шаблона — в params.preset):
| шаблон | источник | что собирает | параметры | единица, кредитов |
|---|---|---|---|---|
tg.channel_posts |
Telegram | Посты канала — все публикации за период: текст, просмотры, пересылки, вложения | period_from/period_to, limit, media |
пост канала: 0,5 |
tg.search |
Telegram | Поиск слов в канале — посты канала, где встречаются нужные слова | query, period_from/period_to, limit |
пост канала: 0,5 |
tg.channel_info |
Telegram | Карточка канала — подписчики, описание, связанный чат обсуждений | — | карточка канала или чата: 1,5 |
tg.chat_messages |
Telegram | Сообщения чата — кто и что писал в группе за период: автор, ответы, вложения | period_from/period_to, limit, media |
сообщение чата: 1 |
tg.chat_membersнужно право tg:people |
Telegram | Участники чата — состав группы: кто в ней есть, юзернеймы и имена | limit |
участник чата: 1 |
tg.chat_search |
Telegram | Поиск слов в чате — сообщения группы, где встречаются нужные слова | query, period_from/period_to, limit |
сообщение чата: 1 |
tg.chat_info |
Telegram | Карточка чата — название, описание, сколько участников | — | карточка канала или чата: 1,5 |
vk.wall_posts |
ВКонтакте | Посты стены — стена сообщества или страницы за период | period_from/period_to, limit, with_comments |
запись или комментарий: 0,5 |
vk.group_membersнужно право vk:people |
ВКонтакте | Участники сообщества — список участников открытого сообщества | limit |
участник сообщества: 0,5 |
vk.newsfeed_search |
ВКонтакте | Поиск постов по словам — все посты ВК с нужными словами за период | query, period_from/period_to, limit |
найденный пост: 1 (не меньше 10 за запрос) |
vk.groups_search |
ВКонтакте | Поиск сообществ — сообщества по словам в названии, с размером | query, limit |
карточка сообщества: 1 |
У всех шаблонов Telegram — ref (до 20 каналов через пробел или запятую), у ВКонтакте — ссылка на
сообщество в ref или слова в query. limit — потолок записей.
Подписки на события
Подписка — список каналов и способ доставки. Она не привязана ни к чему, кроме ключа: как и откуда читать каналы, решаем мы, и при сбоях догоняем пропущенное сами. Каждое сообщение приходит один раз.
| доставка | как | когда удобно |
|---|---|---|
webhook | пачки до 100 событий POST-ом на ваш https-адрес, с подписью | есть свой сервер с публичным адресом |
pull | GET …/events?after=<id>&wait=25 — страницы с долгим ожиданием | скрипт по расписанию, адреса нет |
stream | SSE-поток GET …/stream, продолжение с Last-Event-ID | постоянно работающий процесс |
События: new — новое сообщение, post — пост целиком (альбом склеен в один),
edit, delete, action — служебное. Обычно берут либо new, либо
post. События хранятся 7 дней. Пример события:
{"id": "18446", "kind": "post",
"chat": {"peer_id": -1005678901234, "username": "telegram", "title": "Telegram News"},
"message": {"id": 512, "date": "2026-09-23T09:15:00+00:00", "text": "…", "views": 18400, "media": []},
"source": "poll", "received_at": "2026-09-23T09:15:02Z"}
Закрытые чаты — по приглашению в chats[].ref; как подписка решает, нужно ли вступать, — в разделе
справочника «Вступления».