8 мин чтенияТуториалы

API аналитики ссылок: получайте статистику кликов с ключом API

Руководство по API аналитики ссылок: какие отчеты о кликах доступны по ключу API, параметры запроса, форматы JSON-ответов, постраничная навигация с курсором и скрипт ежедневного отчета для Slack.

Marius Voß
DevRel · edge infra
Обложка API аналитики ссылок: запрос curl с ключом API рабочего пространства возвращает JSON временного ряда кликов, разбивки и сводки рядом со столбчатой диаграммой из пикселей

API аналитики ссылок Elido - это одна конечная точка: GET /v1/workspaces/{workspace_id}/analytics/{report} на https://api.elido.app, аутентификация выполняется ключом API рабочего пространства. Она предоставляет 15 отчетов: временной ряд кликов, сводку вовлеченности, лучшие ссылки, ленту последних кликов с постраничной навигацией по курсору и разбивки по стране, рефереру, устройству, браузеру, хосту и назначению. По умолчанию берутся последние 30 дней, link_id ограничивает любой отчет одной короткой ссылкой, а экспорт CSV, воронки, когорты и LTV остаются в панели управления.

Если вам был нужен только URL, это весь ответ. В остальной части руководства собрано то, что мне хотелось бы видеть в начале каждой страницы об API аналитики кликов: точные параметры, возвращаемый JSON, места, где диапазон дат незаметно работает не так, как можно предположить, и скрипт из 30 строк, который каждое утро отправляет вчерашние показатели в Slack.

Большинство людей, выгружающих данные о кликах, замыкают цикл, который начинается с разметки кампании. Поэтому, если ваши ссылки еще не содержат согласованных UTM-меток, сначала исправьте это с помощью сквозного отслеживания UTM. Чистые исходные данные делают статистику достойной выгрузки.

Что возвращает API аналитики ссылок

Все отчеты доступны по одному пути, а имя отчета является последним сегментом. Имена со слешем (links/top, clicks/recent, breakdown/country) передаются без кодирования. Запросите что-либо вне списка разрешенных, и получите 404 с unknown analytics report.

ОтчетФормат ответаПодходит для
timeseries{items: [{ts, count}]}Графиков, сравнений по дням
summaryплоский объект из пяти метрикЕжедневных сводок, плиток KPI
links/top{items: [{link_id, slug, count}]}"Какие ссылки принесли результат за неделю"
clicks/recent{items: [click rows], next_cursor}Лент почти в реальном времени, собственного хранилища
breakdown/country, /referrer, /device, /browser, /host, /destination{items: [{key, count}]}Круговых диаграмм, разбиения по каналам
top-countries, top-referrers, top-destinations{items: [{key, count}]}Тех же данных с более простыми именами
top-regions, top-cities{points: [{country, region or city, count}]}Географического анализа ниже уровня страны

Обратите внимание на последнюю строку. Отчеты по регионам и городам помещают строки в points, а не в items, поскольку каждая строка содержит страну вместе с регионом или городом вместо одного ключа. Мне доводилось видеть, как универсальный парсер споткнулся об это ровно один раз. Одного раза достаточно.

Этот же интерфейс используют API и SDK, инструмент аналитики MCP-сервера и операция Get Analytics в узле n8n, поэтому знания отсюда пригодятся и там.

Аутентификация ключом API рабочего пространства

Ключи API начинаются с elido_ и принадлежат ровно одному рабочему пространству. Передавайте ключ как bearer-токен:

curl -s "https://api.elido.app/v1/workspaces/4821/analytics/summary" \
  -H "Authorization: Bearer $ELIDO_API_KEY"

Перед выполнением любого запроса маршрутизатор проверяет две вещи: принадлежит ли ключ рабочему пространству 4821 и есть ли у него analytics.view. Это разрешение есть у каждой встроенной роли, включая Viewer. Поэтому для задач отчетности создайте ключ Viewer. У задачи cron нет причин иметь возможность удалять ссылки, а ключ Viewer этого не может. Ключ без доступа получит 403.

link_id тоже не расширяет доступ. Проверяется идентификатор рабочего пространства в пути, поэтому идентификатор ссылки, взятый из чужого рабочего пространства, сопоставится с нулем строк и вернет пустой список. Это правильный сбой: скучно, зато ничего не утечет.

Параметры запроса для статистики кликов: даты, часовой пояс, фильтры

Шесть параметров покрывают почти каждый вызов API статистики коротких ссылок, который вам понадобится:

  • from и to в формате YYYY-MM-DD. Не указывайте оба - получите 30 дней по текущий момент. Укажите только to, и from по умолчанию будет на 30 дней раньше.
  • link_id ограничивает любой отчет одной ссылкой, а host - одним доменом перенаправления. Это удобно, когда рабочее пространство использует несколько брендированных доменов.
  • interval для timeseries: hour или day (по умолчанию). Любое другое значение завершит запрос ошибкой.
  • limit для разбивок и списков лидеров: от 1 до 200, по умолчанию 50. links/top выделяется: он возвращает 10, если не запросить больше.

Вот деталь, которая может больно ударить. Обе даты читаются как полночь UTC, а окно включает from, но останавливается перед to. Чтобы получить весь день 21 сентября, отправьте from=2026-09-21&to=2026-09-22. Отправьте to=2026-09-21 - и не получите ничего за этот день.

Есть еще часовой пояс. Передайте tz как имя часового пояса IANA или установите заголовок X-User-TZ, и timeseries будет отсекать часовые или дневные интервалы по местному времени. Меняются только интервалы. Окно from/to все еще использует UTC, поэтому для берлинского "вчера" нужно чуть более широкое окно, что обрабатывает скрипт ниже. Опечатка вроде Europe/Berln вернет 400 с unknown IANA timezone, и это лучше, чем незаметно неверный график.

curl -s -G "https://api.elido.app/v1/workspaces/4821/analytics/timeseries" \
  -H "Authorization: Bearer $ELIDO_API_KEY" \
  --data-urlencode "from=2026-09-01" \
  --data-urlencode "to=2026-09-22" \
  --data-urlencode "interval=day" \
  --data-urlencode "tz=Europe/Berlin" \
  --data-urlencode "link_id=918273"

Форматы ответов, с которыми можно работать в коде

Точка временного ряда содержит ts - метку времени RFC 3339 для начала интервала - и count. Интервалы с нулем кликов просто отсутствуют, поэтому перед построением графика заполните пропуски сами, иначе тихое воскресенье исчезнет с оси x.

{
  "items": [
    { "ts": "2026-09-19T00:00:00Z", "count": 412 },
    { "ts": "2026-09-21T00:00:00Z", "count": 388 }
  ]
}

Разбивки возвращают {"items": [{"key": "DE", "count": 1204}, ...]}, отсортированные по числу кликов. Сводка представляет собой плоский объект:

{
  "total_clicks": 5310,
  "unique_visitors": 3987,
  "returning_visitors": 611,
  "avg_clicks_per_visitor": 1.33,
  "bounce_rate": 0.85
}

Важны два определения. Уникальные посетители считаются по различным IP-адресам за период, поэтому офис за одним подключением считается один раз. И bounce_rate - это доля, а не процент: часть уникальных посетителей, кликнувших в окне только один раз. Этот показатель ничего не говорит о том, что произошло на вашей целевой странице, поэтому эти числа никогда не совпадают с сеансами GA4 (в статье клики и сеансы GA4 разобрано расхождение). До того как данные попадут к вам, из всех показателей отфильтровываются боты. Это те же значения, что вы видите в аналитике ссылок Elido.

Постраничная навигация по последним кликам с курсором

clicks/recent - отчет API отслеживания ссылок, который возвращает отдельные клики, сначала самые новые. В каждой строке есть ts, link_id, slug, host, referer, country_code, device, browser, destination, user_agent и ip. Размер страницы - от 1 до 500, по умолчанию 100.

Когда страница возвращается заполненной, ответ содержит next_cursor. Передайте его как ?cursor=, чтобы получить следующую, более старую страницу. null означает, что вы достигли конца окна.

Постраничная навигация с курсором для отчета clicks/recent API аналитики ссылок: первый запрос возвращает новейшую страницу кликов и next_cursor, клиент передает его обратно как ?cursor= для следующей более старой страницы, а null в next_cursor завершает цикл

Курсор указывает на метку времени и идентификатор ссылки последней строки. Два клика по одной ссылке в ту же миллисекунду могут совпасть на границе страниц, и в худшем случае появится одна дублирующаяся строка, но строка никогда не будет пропущена. При сохранении устраняйте дубликаты по полной строке. Это редко, но вставка из десяти строк лучше, чем объяснять финансам ошибку off-by-one.

Эти строки содержат IP-адреса и строки User-Agent, то есть персональные данные. Если вы копируете их в хранилище, держите его в ЕС и задайте срок хранения. В руководстве по резидентности данных ЕС для маркетинговых команд объясняется почему. В большинстве отчетов необработанные строки вообще не нужны, а ежедневный агрегат бережнее для всех.

Скрипт ежедневного отчета о кликах для Slack или таблицы

Вот задача, которую на самом деле хочет большинство людей: каждое утро отправлять в канал вчерашние клики и пять лучших ссылок. Она использует только стандартную библиотеку Python и входящий webhook Slack.

import datetime as dt, json, os, urllib.parse, urllib.request
from zoneinfo import ZoneInfo

BASE = "https://api.elido.app/v1/workspaces/{ws}/analytics/{report}"
WS, KEY = os.environ["ELIDO_WORKSPACE_ID"], os.environ["ELIDO_API_KEY"]
TZ = ZoneInfo("Europe/Berlin")

def report(name, **params):
    url = BASE.format(ws=WS, report=name) + "?" + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {KEY}"})
    with urllib.request.urlopen(req, timeout=20) as r:
        return json.load(r)

day = dt.datetime.now(TZ).date() - dt.timedelta(days=1)
# UTC window one day wider on each side, then keep only local hours of `day`
window = {"from": day - dt.timedelta(days=1), "to": day + dt.timedelta(days=2)}
hours = report("timeseries", interval="hour", tz="Europe/Berlin", **window)["items"]
total = sum(p["count"] for p in hours
            if dt.datetime.fromisoformat(p["ts"]).astimezone(TZ).date() == day)

top = report("links/top", limit=5, **{"from": day, "to": day + dt.timedelta(days=1)})
lines = [f"• {l['slug']}: {l['count']}" for l in top["items"]]
text = f"Clicks on {day} (Berlin): {total}\nTop links (UTC day):\n" + "\n".join(lines)

body = json.dumps({"text": text}).encode()
urllib.request.urlopen(urllib.request.Request(
    os.environ["SLACK_WEBHOOK_URL"], data=body,
    headers={"Content-Type": "application/json"}))

Запускайте ее из cron в 07:00 по местному времени. Почасовой прием делает итог настоящим берлинским днем, а не днем UTC. У links/top нет tz, поэтому его рейтинг остается в дне UTC, о чем говорится в сообщении.

Нужна таблица? Те же два вызова работают из Google Apps Script с UrlFetchApp и ежедневным триггером, добавляя по одной строке в день. Это также самый недорогой путь к панели Looker Studio.

Если вы все еще каждую неделю по понедельникам переносите числа со скриншотов, дайте скрипту ключ Viewer и верните себе утра.

Что остается только в панели управления

Интерфейс ключа API доступен только для чтения и намеренно уже панели управления. Эти возможности недоступны с ключом:

  • Экспорт кликов в CSV (clicks.csv). Для массовых файлов используйте кнопку «Скачать CSV» в панели управления.
  • Воронки, когорты, отчет LTV, тепловые карты времени и географии, а также представление качества трафика.

Если вам достаточно, чтобы файл по расписанию где-то появлялся, запланированные отчеты панели управления по электронной почте сделают это без кода. Для полной выгрузки, как при уходе к другому сервису, посмотрите, что можно экспортировать из аккаунта коротких ссылок, и как проверить полноту. Совмещенного вызова "все для одной ссылки" пока нет, поэтому для панели управления по отдельной ссылке нужен один запрос на отчет. В кратком руководстве по SDK рассказано, как запускать их параллельно и делать паузу при достижении лимитов запросов.

Опрос API аналитики кликов и webhook для работы в реальном времени

Честный ответ: сейчас данные о кликах доступны только по запросу (pull). Webhook Elido отправляют события ссылок и доменов с подписью и повторными попытками, но событие click.created для каждого клика запланировано и пока не отправляется. Все, что касается кликов в реальном времени, требует опроса clicks/recent.

Сравнение опроса API аналитики ссылок и webhook для данных о кликах: опрос clicks/recent с сохраненным курсором работает сейчас, а webhook охватывают события ссылок и доменов, и событие click.created для каждого клика запланировано, но не отправляется

Это менее болезненно, чем кажется. Опрос выполняйте каждую минуту или две, останавливайтесь, как только дойдете до уже сохраненной строки, и нагрузка останется небольшой, потому что тихая минута - это одна небольшая страница. Когда появится click.created, обработчику строки будет неважно, пришла ли она со страницы опроса или через push. Общие компромиссы изложены в статье webhook или опрос для отслеживания кликов, а если вы решаете, какие показатели вообще заслуживают отчета, что измерять в аналитике коротких ссылок - более короткое чтение.

Мое мнение: начните с ежедневной сводки. Почти каждая команда, которая спрашивает меня о кликах в реальном времени, довольна вчерашними показателями, доставленными до кофе.

Читайте основную статью → Как отслеживать UTM-кампании от начала до конца

По теме в блоге

Частые вопросы

Есть ли у Elido API аналитики кликов по коротким ссылкам?

Да. Ключ API рабочего пространства может вызвать GET /v1/workspaces/{workspace_id}/analytics/{report} на api.elido.app и получить 15 отчетов: временной ряд, сводку, лучшие ссылки, последние клики, шесть разбивок и пять списков лидеров. Ключу нужно разрешение analytics.view, которое уже есть у каждой встроенной роли, включая Viewer.

Как получить через API статистику кликов по одной короткой ссылке?

Добавьте link_id в строку запроса к любому отчету. Числовой идентификатор ссылки ограничит временной ряд, сводку, разбивки и последние клики этой одной ссылкой. Рабочее пространство в пути по-прежнему определяет доступ, поэтому идентификатор ссылки из другого рабочего пространства просто вернет пустой набор строк и не раскроет данные.

Можно ли экспортировать данные о кликах в CSV через API?

Не с ключом API. Экспорт кликов в CSV, воронки, когорты и отчет LTV доступны только в панели управления. Для автоматизированной выгрузки перебирайте отчет clicks/recent с его курсором и записывайте строки самостоятельно, либо настройте в панели управления отчет по электронной почте, если достаточно файла во входящих.

Какой часовой пояс использует API аналитики ссылок?

Даты from и to читаются как календарные дни UTC. Для отчета timeseries можно передать tz в виде имени IANA, например Europe/Berlin, или отправить заголовок X-User-TZ, и часовые либо дневные интервалы будут отсекаться в этой зоне. Неизвестное имя зоны возвращает ошибку 400.

Можно ли получать webhook для каждого клика по короткой ссылке?

Пока нет. Webhook click.created для каждого клика запланирован, но сейчас не отправляется, поэтому webhook пока охватывают только события ссылок и доменов. Для данных о кликах почти в реальном времени опрашивайте отчет clicks/recent через небольшой интервал и сохраняйте последний курсор между запусками.

Какая роль ключа API может читать аналитику кликов?

Любая встроенная роль. Для чтения аналитики нужно analytics.view, и оно уже есть у роли Viewer, поэтому для скрипта отчетности безопаснее всего выбрать ключ Viewer. Он может читать все разрешенные отчеты, но не сможет создать, изменить или удалить ссылки, если ключ когда-либо утечет с сервера cron.

Попробуйте Elido

Вставьте URL - получите короткую ссылку

Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.

Бесплатно, без регистрации · 2 в день

Попробуйте Elido

URL-сокращатель с хостингом в ЕС: собственные домены, глубокая аналитика, открытый API. Бесплатный тариф - без банковской карты.

Теги
link analytics api
click analytics api
short link stats api
url shortener analytics api
link tracking api
click data export

Читать дальше