Adset.ProAdset.ProKnowledge base
Home/Публічне HTTP API/Статистика: звіти та експорт

Статистика: звіти та експорт

Statistics API повертає агреговані звіти трекера — метрики × групування × фільтри за період. Це ті ж дані, що показує Конструктор звітів в кабінеті. Підходить для BI-систем, регулярних вивантажень та зовнішніх дашбордів.

Ключі метрик, групувань та фільтруваних полів зібрані в статті Статистика: довідник полів. Отримання токена, загальний формат відповідей та помилок — в головній статті розділу.

Скоупи

Скоуп Доступ В дефолті PAT
api:stats POST /api/stats/query — звіти так
api:stats:export POST /api/stats/export/csv — вивантаження CSV так
api:stats:meta GET /api/stats/meta/* — довідники так

Усі операції вимагають права запиту статистики — воно є у всіх ролей. BUYER бачить тільки свою статистику, TEAM_LEAD — статистику команди з урахуванням налаштувань доступу до ресурсів, TEAM_OWNER та TECH — команду, ADMIN — все.

Ендпойнти

Базовий префікс — /api/stats. Тіло запитів — JSON, відповіді — application/json (для експорту — text/csv).

Метод Шлях Скоуп Призначення
POST /api/stats/query api:stats Звіт: метрики × групування + фільтри, з пагінацією
POST /api/stats/export/csv api:stats:export Та ж вибірка в CSV (без пагінації, до 100 000 рядків)
GET /api/stats/meta/metrics api:stats:meta Каталог метрик
GET /api/stats/meta/groups api:stats:meta Каталог групувань
GET /api/stats/meta/filters api:stats:meta Список фільтруваних полів
GET /api/stats/meta/distinct?field=&q=&limit= api:stats:meta Підказки значень поля (autocomplete)
GET /api/stats/meta/os-versions?q=&limit= api:stats:meta Підказки версій ОС

Для /api/stats/** діє окремий ліміт частоти — 3 запити на секунду з одного IP (burst 10). Понад ліміт шлюз відповідає 429.

POST /api/stats/query

Тіло запиту (StatsQueryDto):

{
  "time": {
    "preset": "last7",            // АБО from/to
    "from":  "2026-05-01 00:00:00",
    "to":    "2026-05-20 23:59:59",
    "timezone": "UTC"
  },
  "groups":  ["day", "cmp_campaign"],
  "metrics": ["clicks", "cpa_accept", "revenue", "roi"],
  "filters": [
    { "field": "user_country", "op": "in", "value": ["US", "CA"] },
    { "field": "cmp_offer",    "op": "eq", "value": "65f0…" }
  ],
  "pagination": { "page": 1, "limit": 100 },
  "sort": { "field": "clicks", "order": "desc" },
  "attributionWindow": { "hours": 24, "eventType": "click" }
}

Поля запиту

Поле Тип Обов'язково Опис
time TimeRangeDto так Часовий інтервал звіту
groups string[] ні Ключі групувань (див. довідник). Порожній масив — агрегат «всього»
metrics string[] ні Ключі метрик (див. довідник). За замовчуванням ["clicks"]
filters FieldFilterDto[] ні Фільтри по полях (див. нижче)
pagination { page, limit } ні page ≥ 1, 1 ≤ limit ≤ 100000 (за замовчуванням 100)
sort { field, order } ні order ∈ {asc, desc}; field — ключ метрики або групування з запиту
attributionWindow { hours, eventType } ні Вікно атрибуції для Push-метрик: 1 ≤ hours ≤ 720, eventType ∈ {click, view}

time (TimeRangeDto)

Поле Опис
preset один з пресетів нижче; має пріоритет над from/to
from 'YYYY-MM-DD' або 'YYYY-MM-DD HH:mm:ss' (роздільник — пробіл або T). Без мілісекунд і без суфікса таймзони (Z, +03:00) — такий формат поверне помилку валідації
to те ж; необов'язковий, якщо задано from
timezone IANA-таймзона (Europe/Moscow), за замовчуванням UTC. Межі інтервалу та групування за часом обчислюються в ній

Потрібно передати або preset, або from (опціонально з to).

Пресет Період
today сьогодні з 00:00 до поточного моменту
yesterday повні попередні доби
last7 останні 7 днів, включаючи сьогодні
last30 останні 30 днів
thisWeek з понеділка поточного тижня
prevWeek попередній повний тиждень (Пн–Нд)
thisMonth з 1-го числа поточного місяця
prevMonth попередній повний місяць

filters[] (FieldFilterDto)

Кожен фільтр — { "field", "op", "value" }. Поле повинно входити в список GET /api/stats/meta/filters.

Оператор op Семантика Тип value
eq дорівнює рядок/число
neq не дорівнює рядок/число
in значення зі списку масив
not_in значення немає у списку масив
gt / gte більше / більше або дорівнює число
lt / lte менше / менше або дорівнює число
between в діапазоні [min, max] — масив з 2 елементів
like підрядок без урахування регістру (ClickHouse ILIKE) рядок з %

Серверні фільтри. Поля cmp_team та cmp_user завжди перевизначаються сервером відповідно до ролі власника токена: задане клієнтом значення cmp_team ігнорується, а cmp_user перетинається з дозволеним набором користувачів. Обмежити звіт чужими даними через API неможливо.

Правила

  • groups та metrics приймають тільки ключі з довідників; невідомий ключ — помилка 422.
  • Якщо у групування є «name»-варіант (cmp_campaign ↔ cmp_campaign_name), він додається в рядки автоматично — передавати його окремо не потрібно.
  • attributionWindow впливає тільки на метрики Push Attribution (push_postclick_*); без нього ці метрики повернуть нулі.
  • Метрики LTV/Cohort (ltv_*, ftds, registrations…) використовуються разом з групуваннями cohort_*, reg_cohort_*, lifetime_days*.
  • Для query рекомендується limit ≤ 10 000; для повного вивантаження використовуйте CSV.

Приклад відповіді

{
  "data": {
    "rows": [
      {
        "day": "2026-05-13T00:00:00+00:00",
        "cmp_campaign": "65f0…",
        "cmp_campaign_name": "Brand A — RU",
        "clicks": 18432,
        "cpa_accept": 122,
        "revenue": 2840.55,
        "roi": 0.36
      }
    ],
    "total": { "clicks": 18432, "cpa_accept": 122, "revenue": 2840.55 },
    "page": 1,
    "limit": 100,
    "rowCount": 1
  },
  "traceId": "01HX…"
}

rows — рядки звіту (ключі групувань + метрики), total — підсумок по всій вибірці без урахування пагінації, rowCount — кількість рядків на поточній сторінці. Частки (roi, click_to_dep тощо) приходять як числа в діапазоні 0..1, гроші — в USD.

POST /api/stats/export/csv

Те ж тіло StatsQueryDto. Відповідь — text/csv; charset=utf-8, ім'я файлу stats-report-YYYY-MM-DD.csv. Пагінація ігнорується, вивантаження обмежене 100 000 рядків.

curl -X POST 'https://adset.pro/api/stats/export/csv' \
  -H 'Authorization: Bearer pat_…' \
  -H 'Content-Type: application/json' \
  --data-binary @query.json -o report.csv

Довідники GET /api/stats/meta/*

Довідники — живе джерело ключів: якщо в платформі з'явилася нова метрика, вона відразу є в meta/metrics. Відповіді мають вигляд { "data": [ … ], "traceId" }; кешуйте їх на стороні інтеграції.

meta/metrics

{
  "key": "roi",
  "type": "calculated",
  "title": "ROI",
  "group": "Finance",
  "format": "percent",
  "dependencies": ["revenue", "cost"],
  "table": "events"
}

type — direct (прямий агрегат) або calculated (обчислюється з dependencies); format — підказка для форматування: ceil (ціле), finance (гроші), percent (частка 0..1), number; table — таблиця ClickHouse, в якій метрика існує.

meta/groups

{ "key": "cmp_campaign", "title": "Campaign", "group": "Campaign", "tables": ["events", "events_push", "events_push_attributed"] }

tables — в яких таблицях групування валідне; групування та метрики в одному запиті повинні перетинатися хоча б по одній таблиці.

meta/filters

{ "field": "user_country", "type": "list", "group": "Traffic", "name": "Country" }

meta/distinct

Підказки значень поля: GET /api/stats/meta/distinct?field=user_country&q=us&limit=20. Поле повинно входити в meta/filters.

{
  "data": [
    { "label": "US", "value": "US" },
    { "label": "Australia", "value": "AU" }
  ],
  "traceId": "01HX…"
}

Для сутностей (cmp_campaign, cmp_offer, cmp_cpa…) value — це ObjectId, label — ім'я. Цей же ендпойнт зручно використовувати, щоб знайти id для фільтра за назвою.

meta/os-versions

Те ж, що distinct?field=user_os_ver, але з додатковою нормалізацією версій ОС.

Приклади

Звіт по дням та кампаніям за минулий тиждень

curl -X POST 'https://adset.pro/api/stats/query' \
  -H 'Authorization: Bearer pat_…' \
  -H 'Content-Type: application/json' \
  -d '{
    "time": { "preset": "prevWeek", "timezone": "Europe/Moscow" },
    "groups": ["day", "cmp_campaign"],
    "metrics": ["clicks", "cpa_accept", "revenue", "roi"],
    "filters": [
      { "field": "user_country", "op": "in", "value": ["US","CA","GB"] }
    ],
    "pagination": { "page": 1, "limit": 50 },
    "sort": { "field": "revenue", "order": "desc" }
  }'

Підказки по країнам

curl -G 'https://adset.pro/api/stats/meta/distinct' \
  -H 'Authorization: Bearer pat_…' \
  --data-urlencode 'field=user_country' \
  --data-urlencode 'q=u' \
  --data-urlencode 'limit=10'

LTV-когорта по тижнях

curl -X POST 'https://adset.pro/api/stats/query' \
  -H 'Authorization: Bearer pat_…' \
  -H 'Content-Type: application/json' \
  -d '{
    "time": { "preset": "last30" },
    "groups": ["cohort_week", "lifetime_days"],
    "metrics": ["ftds", "ltv_d0", "ltv_d1_7", "ltv_d8_30", "ltv_total", "ltv_per_ftd"],
    "pagination": { "page": 1, "limit": 1000 }
  }'

Push Attribution з вікном 48 годин

curl -X POST 'https://adset.pro/api/stats/query' \
  -H 'Authorization: Bearer pat_…' \
  -H 'Content-Type: application/json' \
  -d '{
    "time": { "preset": "last7" },
    "groups": ["day", "event_push_id"],
    "metrics": ["push_views", "push_clicks", "push_postclick_accepts", "push_click_to_accept_rate"],
    "attributionWindow": { "hours": 48, "eventType": "click" }
  }'

Експорт CSV

curl -X POST 'https://adset.pro/api/stats/export/csv' \
  -H 'Authorization: Bearer pat_…' \
  -H 'Content-Type: application/json' \
  --data-binary @query.json -o report.csv

Помилки

HTTP Коли
400 time is required не передано time
400 time.preset or time.from/time.to required в time немає ні preset, ні from
422 validationError невірний формат дати, невідомий op, метрика або групування; деталі — в details[]
403 forbidden + Insufficient OAuth scope. Required: api:stats… у токена немає потрібного скоупа (наприклад, PAT без api:stats:export викликає CSV)
429 перевищено ліміт 3 запити/с на /api/stats/**

Загальний формат помилок та коди 401/403 описані в головній статті розділу.

Пов'язані статті