SOROKA Документация API

Быстрый старт

Четыре шага: ключ, первый запрос, задача с файлом результата, вебхук с новыми постами. Примеры — на curl и Python (pip install httpx).

  1. Ключ

    Ключ выдаётся в кабинете, раздел «Мой ключ». Полностью он показывается один раз — сохраните его в секреты сервиса и положите в переменную окружения, не в код:

    export API_KEY="…ключ из кабинета…"

    Проверьте ключ — этот вызов бесплатный и не тратит лимит:

    curl
    curl -s "https://soroka.tools/v1/me" \
      -H "Authorization: Bearer $API_KEY"
    Python
    import os
    
    import httpx
    
    r = httpx.get("https://soroka.tools/v1/me",
                  headers={"Authorization": f"Bearer {os.environ['API_KEY']}"})
    r.raise_for_status()
    print(r.json()["scopes"])

    В ответе — права ключа (scopes), лимиты и остаток кредитов. 401 — ключ не тот или не дошёл заголовок Authorization; подробнее — «Ошибки».

  2. Первый запрос

    Пять последних постов публичного канала:

    curl
    curl -s "https://soroka.tools/v1/tg/posts" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"chat": "@telegram", "limit": 5}'
    Python
    import os
    import time
    import uuid
    
    import httpx
    
    api = httpx.Client(base_url="https://soroka.tools/v1", timeout=60,
                       headers={"Authorization": f"Bearer {os.environ['API_KEY']}"})
    
    posts = api.post("/tg/posts", json={"chat": "@telegram", "limit": 5}).json()["items"]
    for p in posts:
        print(p["id"], p["date"], p["views"], (p["text"] or "")[:80])

    Каждый пост — id, дата, текст, просмотры, пересылки, медиа. Кредиты списываются только за полученные записи: пустой ответ и ошибки бесплатны.

  3. Задача

    Для большого объёма — задача: она собирает всё сама, а результат отдаёт файлом. Сначала узнайте цену (/jobs/estimate), потом поставьте задачу, дождитесь done и скачайте csv, xlsx или json.

    curl
    curl -s "https://soroka.tools/v1/jobs/estimate" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"kind": "parser.preset", "params": {"preset": "tg.channel_posts", "params": {"ref": "@telegram", "period_from": "2026-09-01", "limit": 300}}}'
    
    curl -s "https://soroka.tools/v1/jobs" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{"kind": "parser.preset", "params": {"preset": "tg.channel_posts", "params": {"ref": "@telegram", "period_from": "2026-09-01", "limit": 300}}}'
    
    curl -s "https://soroka.tools/v1/jobs/$JOB_ID" -H "Authorization: Bearer $API_KEY"
    
    curl -s "https://soroka.tools/v1/jobs/$JOB_ID/result?format=csv" \
      -H "Authorization: Bearer $API_KEY" -o posts.csv
    Python
    import os
    import time
    import uuid
    
    import httpx
    
    api = httpx.Client(base_url="https://soroka.tools/v1", timeout=60,
                       headers={"Authorization": f"Bearer {os.environ['API_KEY']}"})
    
    job = {"kind": "parser.preset",
           "params": {"preset": "tg.channel_posts",
                      "params": {"ref": "@telegram", "period_from": "2026-09-01", "limit": 300}}}
    
    print(api.post("/jobs/estimate", json=job).json()["credits"])       # {"min": 0, "max": 150}
    
    r = api.post("/jobs", json=job, headers={"Idempotency-Key": str(uuid.uuid4())})
    job_id = r.json()["job_id"]
    while (card := api.get(f"/jobs/{job_id}").json())["status"] in ("queued", "running"):
        time.sleep(5)
    
    if card["status"] == "done":
        csv = api.get(f"/jobs/{job_id}/result", params={"format": "csv"}).content
        open("posts.csv", "wb").write(csv)

    Idempotency-Key защищает от двойной задачи, если ответ потерялся по дороге: повтор с тем же ключом вернёт ту же задачу (подробнее). Какие ещё бывают шаблоны сбора — в «Основах».

  4. Вебхук

    Новые посты каналов можно получать на свой адрес: создайте подписку с delivery: webhook. Секрет вебхука приходит в ответе один раз.

    curl
    curl -s "https://soroka.tools/v1/tg/subscriptions" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{"name": "news", "chats": ["@telegram"], "events": ["post"],
           "delivery": "webhook", "webhook_url": "https://example.ru/hooks/tg"}'
    Python
    import os
    import time
    import uuid
    
    import httpx
    
    api = httpx.Client(base_url="https://soroka.tools/v1", timeout=60,
                       headers={"Authorization": f"Bearer {os.environ['API_KEY']}"})
    
    sub = api.post("/tg/subscriptions", headers={"Idempotency-Key": str(uuid.uuid4())}, json={
        "name": "news", "chats": ["@telegram"], "events": ["post"],
        "delivery": "webhook", "webhook_url": "https://example.ru/hooks/tg",
    }).json()
    print(sub["subscription_id"])
    # секрет показывается один раз — сохраните в секреты сервиса; потеряли —
    # PATCH /tg/subscriptions/{id} с {"rotate_webhook_secret": true} выдаст новый
    print(sub.get("webhook_secret"))

    Каждая пачка событий приходит POST-запросом с подписью. Проверьте её до разбора тела и ответьте 2xx — иначе пачка придёт повторно:

    import hashlib
    import hmac
    import time
    
    
    def verify_webhook(secret: str, headers, body: bytes) -> bool:
        """headers — заголовки запроса (без учёта регистра), body — тело как пришло, байтами."""
        ts = headers.get("X-Webhook-Timestamp", "")
        delivery = headers.get("X-Webhook-Delivery", "")
        signature = headers.get("X-Webhook-Signature", "")
        if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
            return False
        want = hmac.new(secret.encode(), f"{ts}.{delivery}.".encode() + body, hashlib.sha256).hexdigest()
        return any(part.strip().startswith("sha256=") and hmac.compare_digest(part.strip()[7:], want)
                   for part in signature.split(","))

    То же на JavaScript и PHP, повторы и формат событий — в «Вебхуках». Нет своего адреса — забирайте события страницами (delivery: pull) или потоком SSE, см. справочник.

Дальше