Admin API: отчёты
17 методов для отчётов: построение и CSV, фоновые выгрузки, сохранённые отчёты, свои метрики, журнал кликов, решение клоаки и данные лида.
Методы этой страницы строят те же отчёты, что конструктор отчётов в панели, и отдают данные по отдельным кликам. Авторизация описана на странице Admin API: обзор и авторизация, формат запросов и общие коды ошибок — на странице Формат запросов, ответов и ошибок.
Методы и права токена
- Токену Сводные отчёты (
reports:read) доступны три метода:POST /api/v1/reports,POST /api/v1/reports/exportиGET /api/v1/custom-metrics. - Остальным 14 методам нужен Полный доступ (
full).
Токен reports:read строит отчёт только по разрешённым группировкам и фильтрам. Их список — в разделе Ограничения доступа «Сводные отчёты». На отчёт с другими полями сервер отвечает 403 с кодом token_scope.
Фоновые выгрузки и сохранённые отчёты принадлежат пользователю, который создал токен. Через API видны и те, что он создал в панели.
Запрос отчёта
Одно и то же тело принимают три метода: POST /reports, POST /reports/export и POST /report-exports.
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
from | string, дата RFC 3339 | да | Начало периода. Обе границы входят в период |
to | string, дата RFC 3339 | да | Конец периода |
dimensions | array of string | нет | Группировки, до 12. Без группировок отчёт состоит из одной строки |
metrics | array of string | нет | Метрики. По умолчанию: clicks, conversions, leads, sales, revenue, cost, profit, roi, cr, approval |
filters | array of object | нет | Условия, связанные через И |
filter_groups | array of object | нет | Группы условий, до 16 |
timezone | string | нет | Часовой пояс в формате IANA, например Europe/Warsaw. По умолчанию UTC. Значение Local не принимается |
attribution | string | нет | click, conversion или default. По умолчанию default — настройка трекера |
sort | object | нет | {"field": "...", "direction": "asc"}. По умолчанию clicks по убыванию |
limit | integer | нет | Строк на странице, от 1 до 1000. 0 или без поля — 1000 |
offset | integer | нет | Сколько строк пропустить, не меньше 0 |
compare | boolean | нет | Сравнение с предыдущим периодом |
Часовой пояс задаёт границы часов, дней, недель и месяцев в группировках и день расхода. Что считается по дате клика, а что по дате конверсии — на странице Период, часовой пояс и атрибуция.
Группировки
| Группа | Значения dimensions |
|---|---|
| Объекты | campaign, stream, offer, lander, source, campaign_group |
| Гео и сеть | country, region, city, connection, isp, ip |
| Устройство | device, device_model, os, os_version, browser, browser_version, lang, user_agent |
| Время | hour, day, week, month, year, dow, hour_of_day |
| Признаки | bot, unique, cloak, proxy, empty_referer |
| Параметры клика | click_id, external_id, creative_id, keyword, adset_name, ad_name, referer, sub_id_1 … sub_id_30 |
- Значения группировок в ответе — всегда строки.
- В
campaign,stream,offer,landerиsourceприходят идентификаторы, а не названия. - Признаки приходят как
1или0. - Неделя начинается с понедельника. В
dowпонедельник —1, воскресенье —7. - Значение
sub_id_12не раскрывается: в строке***или пусто.
Метрики
Встроенные метрики: clicks, unique_clicks, bots, lp_clicks, lp_ctr, leads, sales, rejected, conversions, cost, revenue, revenue_expected, profit, profit_expected, roi, roi_expected, cr, approval, cpa, epc, cpl. Формулы — на странице Метрики отчётов и формулы.
В metrics также можно передать:
- ключ своей метрики — поле
name; - колонку типа конверсии —
cv_и идентификатор типа без дефисов. Идентификаторы отдаётGET /api/v1/conversion-types, см. Admin API: конверсии и постбек.
Суммы приходят числом в USD, проценты — числом без знака %.
Фильтры
Условие — объект из трёх строк:
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
field | string | да | Поле клика или встроенная метрика |
op | string | да | Оператор |
value | string | да | Значение, до 2048 символов. Число тоже передаётся строкой |
Операторы зависят от вида поля:
| Вид поля | Поля | Операторы |
|---|---|---|
| Текст | Группировки, кроме времени, признаков и click_id, а также subid и ad_campaign_id | eq, ne, contains, not_contains, starts, ends, regexp, not_regexp, has, not_has |
| Признак | bot, unique, cloak, proxy, empty_referer, ipv4, ipv6 | eq, ne |
| Метрика | Встроенные метрики | gt, gte, lt, lte, eq, ne |
hasиnot_hasпроверяют, заполнено ли поле. Значениеvalueне учитывается.- У признака значения
0,false,no,off,нети пустая строка означают «нет», любое другое — «да». - У метрики
value— конечное число. - По группировкам времени фильтровать нельзя: период задают
fromиto.
Группа в filter_groups — объект {"mode": "or", "filters": [...]}. Поле mode принимает and или or, массив filters не может быть пустым. Группы связаны между собой и с filters через И. В группе or нельзя смешивать поля клика и метрики. Всего в запросе не больше 64 условий. Значения операторов и примеры — на странице Фильтры отчёта.
Сортировка
sort.field — одна из выбранных группировок либо метрика, встроенная или своя. sort.direction — asc или desc. Остальные группировки идут следом по возрастанию.
Построение отчёта
Построить отчёт
POST /api/v1/reportsВозвращает страницу отчёта и итоги по всем строкам. Права токена: reports:read или full. Тело — запрос отчёта. Отчёт строится не дольше 70 секунд.
Ответ — код 200:
| Поле | Тип | Описание |
|---|---|---|
columns | array of string | Ключи колонок: сначала группировки, затем метрики в порядке запроса |
rows | array of array | Строки. Значения идут в порядке columns |
totals | object или null | Итоги по всем строкам отчёта, а не по странице. Ключи — запрошенные метрики. Если строк нет — null |
total_rows | integer | Сколько строк в отчёте всего |
limit, offset, row_limit | integer | Применённые размер страницы и смещение. row_limit равен limit |
truncated | boolean | true, если в rows попали не все строки отчёта |
has_more | boolean | true, если после этой страницы есть ещё строки |
attribution | string | Применённая атрибуция: click или conversion |
timezone | string | Часовой пояс, в котором посчитан отчёт |
Сверяйте timezone в ответе с запрошенным: если пояс недоступен на сервере, отчёт считается в UTC.
Чтобы получить следующую страницу, повторите запрос с offset, увеличенным на limit, пока has_more равно true.
Пример запроса:
curl -X POST https://panel.example.com/api/v1/reports \
-H "Api-Key: <токен>" \
-H "Content-Type: application/json" \
-d '{
"from": "2026-10-01T00:00:00Z",
"to": "2026-10-07T23:59:59Z",
"timezone": "Europe/Warsaw",
"dimensions": ["campaign", "country"],
"metrics": ["clicks", "leads", "cost", "revenue", "roi"],
"filters": [
{"field": "bot", "op": "eq", "value": "0"},
{"field": "clicks", "op": "gte", "value": "100"}
],
"sort": {"field": "roi", "direction": "desc"},
"limit": 100
}'Пример ответа:
{
"columns": ["campaign", "country", "clicks", "leads", "cost", "revenue", "roi"],
"rows": [
["c41a9e07-52bd-4f13-8a60-9d7e6f5a4b3c", "PL", 1520, 42, 310.5, 504, 62.318840579710144],
["7b0c1d52-3f4e-4a6b-9c8d-1e2f3a4b5c6d", "CZ", 830, 17, 190, 204, 7.368421052631579]
],
"totals": {"clicks": 2350, "cost": 500.5, "leads": 59, "revenue": 708, "roi": 41.45854145854146},
"truncated": false,
"row_limit": 100,
"total_rows": 2,
"limit": 100,
"offset": 0,
"has_more": false,
"attribution": "click",
"timezone": "Europe/Warsaw"
}Сравнение с предыдущим периодом
При "compare": true в ответ добавляются два поля:
previous_rows— строки предыдущего периода. Строка с тем же номером вrowsотносится к той же группе. Если у группы нет данных в одном из периодов, её метрики равны0.previous_totals— итоги предыдущего периода.
Предыдущий период — такой же длины и заканчивается перед from. Условия:
- период не длиннее 366 дней;
- среди группировок не больше одной из
hour,day,week,month,year; - в каждом из двух периодов не больше 100 000 строк.
Метрика сортировки, которой нет в metrics, добавляется в columns последней колонкой. Без sort это clicks. Как читать сравнение — на странице Сравнение периодов и динамика по дням.
Ошибки:
| Код | code | Когда |
|---|---|---|
403 | token_scope | Токен reports:read, а в группировках или фильтрах есть поле вне разрешённого списка |
422 | validation | Не указаны from и to; неизвестная группировка, метрика, поле фильтра или оператор; больше 12 группировок; limit вне диапазона; неверные sort, attribution или timezone; не выполнены условия сравнения. Причина — в message |
503 | unavailable | Временный сбой. В ответе заголовок Retry-After: 5 |
503 | report_unavailable | Отчёт не построен: сбой аналитики или превышено время. Повторите запрос позже или сузьте отчёт |
Получить отчёт файлом CSV
POST /api/v1/reports/exportСтроит тот же отчёт и сразу отдаёт его файлом. Права токена: reports:read или full. Тело — запрос отчёта. Поля limit и offset на состав файла не влияют: в файл попадают все строки.
Ответ — код 200, тип text/csv; charset=utf-8, имя файла вида report-20261007-101500.csv. Первая строка — ключи колонок, строки итогов нет. Содержимое файла описано в разделе Что внутри CSV, колонки файла сравнения — в разделе CSV сравнения.
Пределы: 100 000 строк и 32 МиБ.
Ошибки те же, что у POST /reports, и ещё две:
| Код | code | Когда |
|---|---|---|
422 | validation | В отчёте больше 100 000 строк: export exceeds 100000 rows; narrow the report filters. Сузьте период или фильтры |
500 | internal | Файл больше 32 МиБ. Сузьте отчёт или уберите часть колонок |
Фоновые выгрузки CSV
Фоновая выгрузка строит тот же файл без ожидания ответа: запрос ставит отчёт в очередь, готовый файл хранится 24 часа с момента создания. Всем методам нужен доступ full. То же в панели — на странице Сохранённые отчёты и выгрузка CSV.
Объект выгрузки:
| Поле | Тип | Описание |
|---|---|---|
id | uuid | Идентификатор выгрузки |
state | string | pending — в очереди, running — строится, ready — файл готов, failed — ошибка |
error_code | string | Причина ошибки, у остальных состояний — пустая строка |
row_count | integer | Число строк в готовом файле |
compare | boolean | true у выгрузки сравнения периодов |
created_at | string, дата RFC 3339 | Время создания |
expires_at | string, дата RFC 3339 | Время, после которого выгрузка удаляется |
Значения error_code
report_limit_or_validation— в отчёте больше 100 000 строк или настройки отчёта больше не проходят проверку;file_too_large— файл больше 32 МиБ;scope_changed— у создателя токена изменились роль или доступ к кампаниям;interrupted— сборка прерывалась несколько раз;report_failed— отчёт не построен.
Создать выгрузку
POST /api/v1/report-exportsСтавит отчёт в очередь. Тело — запрос отчёта. Поле offset не учитывается, limit на состав файла не влияет. Атрибуция default фиксируется в момент запроса.
Ответ — код 202 и объект выгрузки в состоянии pending.
| Код | code | Когда |
|---|---|---|
422 | validation | Укажите корректный период отчёта — нет from или to либо to раньше from. Остальные причины те же, что у POST /reports |
429 | export_quota | У пользователя уже 2 выгрузки в состояниях pending и running или в команде 20 неистёкших выгрузок |
Список выгрузок
GET /api/v1/report-exportsВозвращает неистёкшие выгрузки создателя токена: массив объектов, до 20, новые первыми. Параметров нет. Опрашивайте список, пока state нужной выгрузки не станет ready или failed.
Скачать файл
GET /api/v1/report-exports/{id}/fileОтдаёт готовый файл: код 200, тип text/csv; charset=utf-8, имя report-<id>.csv. Параметр пути id — идентификатор выгрузки.
| Код | code | Когда |
|---|---|---|
403 | scope_changed | После создания выгрузки изменились права её владельца. Создайте новую выгрузку |
404 | not_found | Выгрузки с таким id у создателя токена нет: срок истёк или она удалена |
409 | not_ready | Состояние не ready: Выгрузка ещё не готова |
curl https://panel.example.com/api/v1/report-exports/5e2f8a10-9b3c-4d7e-8f21-0a1b2c3d4e5f/file \
-H "Api-Key: <токен>" \
-o report.csvУдалить выгрузку
DELETE /api/v1/report-exports/{id}Удаляет выгрузку в любом состоянии и освобождает место в квоте. Ответ — код 204 без тела. Ошибка: 404, код not_found.
Сохранённые отчёты
Сохранённый отчёт — название и набор настроек конструктора: то, что в панели открывается из списка сохранённых отчётов. Всем методам нужен доступ full. Объект:
| Поле | Тип | Описание |
|---|---|---|
id | uuid | Идентификатор |
name | string | Название, от 1 до 120 символов |
definition | object | Настройки отчёта |
created_at, updated_at | string, дата RFC 3339 | Время создания и последнего изменения |
Поля definition. Объект занимает не больше 32 КиБ, поле вне этого списка даёт ошибку 422:
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
version | integer | да | Всегда 1 |
mode | string | да | flat — таблица, drilldown — детализация |
dimensions | array of string | нет | От 0 до 12 группировок без повторов |
metrics | array of string | да | От 1 до 64 метрик без повторов |
filters | array of object | нет | До 64 условий, формат как в запросе отчёта |
filter_groups | array of object | нет | Группы условий |
attribution | string | да | default, click или conversion |
sort | object | да | field и direction |
page_size | integer | да | От 1 до 1000 |
date_range | object | да | preset, tz, для интервала — from и to |
Период и режим в definition
date_range.preset:today,yesterday,this_week,last_7,this_month,prev_month,last_30,this_year,all,range,range_time.- У
rangeдатыfromиtoпишутся как2026-10-01, уrange_time— как2026-10-01T09:30. У остальных значенийfromиtoне сохраняются. date_range.tz— часовой пояс IANA. Пустое значение сохраняется какUTC.- В режиме
drilldownнужна хотя бы одна группировка. Группировкиyear,month,week,day,hour,dow,hour_of_dayиsub_id_12доступны только в режимеflat.
Список сохранённых отчётов
GET /api/v1/report-viewsВозвращает массив сохранённых отчётов создателя токена. Недавно изменённые идут первыми. Параметров нет.
Сохранить отчёт
POST /api/v1/report-viewsСоздаёт сохранённый отчёт. В теле два обязательных поля: name и definition. Ответ — код 201 и объект.
Ошибка 422 с кодом validation: неверное название, настройки больше 32 КиБ, неизвестное поле в definition, неизвестная группировка, метрика или оператор. Причина — в message.
Изменить сохранённый отчёт
PUT /api/v1/report-views/{id}Заменяет название и настройки целиком. Тело и проверки те же, что при создании. Ответ — код 200 и объект. Ошибки: 422 с кодом validation, 404 с кодом not_found.
Удалить сохранённый отчёт
DELETE /api/v1/report-views/{id}Ответ — код 204 без тела. Ошибка: 404, код not_found.
Свои метрики
Пользовательская метрика — колонка отчёта по формуле из встроенных метрик. Метрики общие для всей команды. Список доступен токенам reports:read и full, создание, изменение и удаление — только full. Объект:
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
id | uuid | — | Идентификатор, задаётся трекером |
name | string | да | Ключ метрики для metrics и sort.field. Латинские буквы, цифры и _. Не совпадает со встроенной метрикой и не начинается с cv_ |
formula | string | да | Формула, например revenue / clicks * 100. Правила — в разделе Формула |
title | string | нет | Название колонки в панели |
format | string | нет | number, currency или percent. По умолчанию number |
decimals | integer | нет | Знаков после запятой. По умолчанию 0 |
Список своих метрик
GET /api/v1/custom-metricsВозвращает массив метрик. Параметров нет.
Создать метрику
POST /api/v1/custom-metricsТело — поля объекта без id. Ответ — код 201 и объект.
Ошибка 422 с кодом validation: name и formula обязательны, имя совпадает с базовой метрикой, имя — только латиница, цифры и _ или сообщение, которое начинается с ошибка в формуле:. Разбор сообщений — в разделе Сообщения об ошибках.
Изменить метрику
PUT /api/v1/custom-metrics/{id}Передавайте все поля: name, formula, title и decimals заменяются значениями из тела. Пустой format оставляет прежний формат. Ответ — код 200 и объект. Ошибки: 422 с кодом validation, 404 с кодом not_found.
Удалить метрику
DELETE /api/v1/custom-metrics/{id}Ответ — код 204 без тела. Ошибка: 404, код not_found.
Клики
Три метода отдают данные по отдельным кликам. Всем нужен доступ full. Поиск клика по IP, subid или external_id и полная карточка клика описаны на странице Admin API: логи и диагностика.
Журнал кликов
GET /api/v1/reports/clicksВозвращает последние клики по всем кампаниям за период, новые первыми.
| Параметр | Где | Тип | Обязательность | Описание |
|---|---|---|---|---|
from | запрос | string, дата RFC 3339 | нет | Начало периода. По умолчанию — 24 часа назад |
to | запрос | string, дата RFC 3339 | нет | Конец периода. По умолчанию — текущее время |
limit | запрос | integer | нет | Число кликов, от 1 до 1000. По умолчанию и при значении вне диапазона — 200 |
Дата, которую не удалось разобрать, заменяется значением по умолчанию. Знак + в смещении часового пояса кодируйте как %2B или передавайте время в UTC с буквой Z.
Ответ — код 200 и объект {"items": [...]}. Поля клика: time, click_id, campaign_id, source_id, offer_id, country, city, device, os, browser, ip, is_bot, cost, external_id, sub_id_1.
Ошибки: 503 с кодом no_analytics — аналитика недоступна, 400 с кодом report_error — запрос не выполнен.
Решение клоаки по клику
GET /api/v1/reports/click-cloak?subid=<subid>Возвращает решение клоаки по клику. Параметр запроса subid обязателен — это click_id из журнала кликов.
Ответ — код 200. Если решение по клику не сохранено, приходит {"found": false}. Иначе — {"found": true, "verdict": {...}}:
Поле verdict | Тип | Описание |
|---|---|---|
result | string | money — прошёл на целевой поток, white — отсеян, challenge — ожидает JS-проверку |
stage | string | Этап, на котором принято решение: server или challenge |
score | integer | Балл JS-челленджа |
human | boolean | Признан ли посетитель живым на этапе challenge |
reasons | array of string | Причины решения. Расшифровка — на странице Диагностика: почему клик ушёл на вайт |
details | string | Пояснение текстом |
ts | integer | Время решения, Unix-время в миллисекундах |
Ошибки: 400 с кодом bad_request — нет параметра subid; 404 с кодом not_found и сообщением click not found — клика нет.
Данные лида по клику
GET /api/v1/reports/click-lead?subid=<subid>Возвращает контактные данные, которые форма лендинга привязала к клику. Параметр запроса subid обязателен.
Ответ — код 200 и объект {"found": true, "lead": {...}}. Поля lead: email, phone, first_name, last_name. Если данных по клику нет, found равно false, а поля lead пустые.
Ошибки те же, что у решения клоаки.