Skip to content

Статистика ​

Методы для отчётов: та же статистика, что на «Панели» и на странице «Статистика», только в JSON - для своих дашбордов, выгрузок в таблицы и автоматических проверок. Что значат сами показатели, подробно разобрано в разделах «Дашборд и статистика» и «Статистика».

МетодАдресЧто делает
GET/stats/dashboardСводка за период: итоги, графики, GEO, устройства, топ PWA
GET/stats/funnelВоронка по дням и результаты сплитов
GET/stats/subsРазбивка по одной саб-метке (sub_1 … sub_20)

Замените ВАШ_КЛЮЧ и panel.example.com на свои.

Период ​

Все три метода требуют период - параметры date_from и date_to:

ПараметрОбязательноЧто это
date_fromдаПервый день периода, ГГГГ-ММ-ДД
date_toдаПоследний день периода включительно, не раньше date_from
  • Дни берутся целиком: date_from=2026-10-01&date_to=2026-10-01 - это весь день 1 октября.
  • Время - по UTC: день начинается в 00:00 UTC, а не по вашему часовому поясу.
  • Период - не длиннее месяца: date_to не может быть позже, чем date_from плюс один месяц. Нужна статистика за квартал - запросите по месяцам и сложите (кроме uniq и процентов - их складывать нельзя).

Без дат или с периодом длиннее месяца придёт 422:

json
{
  "data": null,
  "message": "The date to field must be a date before or equal to 2026-02-01.",
  "errors": { "date_to": ["The date to field must be a date before or equal to 2026-02-01."] }
}

Визиты по дате визита, события - по дате события

Визиты, уникальные и вайты считаются по дню, когда был визит. Установки, открытия, регистрации и депозиты - по дню, когда пришло событие. Поэтому на коротком периоде шаг воронки бывает больше 100% от предыдущего: события относятся к визитам, которые были раньше.

Цифры обновляются раз в несколько минут: свежий визит или депозит появится в отчётах с задержкой до 5 минут. Статистика видна только по PWA ваших команд, у admin - по всем.

Сводка ​

GET/stats/dashboard

Всё, что показывает «Панель», одним запросом. Параметры - только период.

bash
curl "https://panel.example.com/api/stats/dashboard?date_from=2026-09-29&date_to=2026-10-05" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json"
php
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$api = new GuzzleHttp\Client([
    'base_uri' => 'https://panel.example.com/api/',
    'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
    'timeout' => 30,
]);

$response = $api->get('stats/dashboard', ['query' => [
    'date_from' => '2026-09-29',
    'date_to' => '2026-10-05',
]]);
$metrics = json_decode($response->getBody(), true)['data']['metrics'];

echo "Установки: {$metrics['total_installs']['value']} ({$metrics['total_installs']['trend']}%)\n";
echo "Депозиты: {$metrics['total_deposits']['value']}, CR {$metrics['avg_cr']['value']}%\n";
python
# pip install requests
import requests

API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}

response = requests.get(f"{API}/stats/dashboard", headers=HEADERS, params={
    "date_from": "2026-09-29",
    "date_to": "2026-10-05",
}, timeout=30)
metrics = response.json()["data"]["metrics"]

print("Установки:", metrics["total_installs"]["value"], f'({metrics["total_installs"]["trend"]}%)')
print("Депозиты:", metrics["total_deposits"]["value"], f'CR {metrics["avg_cr"]["value"]}%')
js
// Node.js 18+, без зависимостей; сохраните как script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };

const params = new URLSearchParams({ date_from: '2026-09-29', date_to: '2026-10-05' });
const response = await fetch(`${API}/stats/dashboard?${params}`, {
  method: 'GET',
  headers,
  signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();

const { metrics } = data;
console.log('Установки:', metrics.total_installs.value, `(${metrics.total_installs.trend}%)`);
console.log('Депозиты:', metrics.total_deposits.value, `CR ${metrics.avg_cr.value}%`);
Ответ (сокращён)
json
{
  "data": {
    "metrics": {
      "previous_period": { "from": "2026-09-22", "to": "2026-09-29" },
      "total_visits": { "value": 12480, "trend": 14 },
      "total_uniques": { "value": 9870, "trend": 12.2 },
      "total_repeats": { "value": 2610, "trend": 21.4 },
      "total_whites": { "value": 1310, "trend": -7.7 },
      "total_installs": { "value": 2140, "trend": 8.1 },
      "total_opens": { "value": 1890, "trend": 11 },
      "total_registrations": { "value": 412, "trend": 8.4 },
      "total_deposits": {
        "value": 96,
        "trend": 18.5,
        "amounts": [
          { "currency": "USD", "amount": 4820.5 },
          { "currency": "EUR", "amount": 310 }
        ]
      },
      "avg_cr": { "value": 4.49, "trend": 6.1 }
    },
    "chart": [
      { "date": "2026-10-04", "visits": 610, "whites": 60, "installs": 110, "deposits": 4 },
      { "date": "2026-10-05", "visits": 640, "whites": 70, "installs": 120, "deposits": 6 }
    ],
    "geo": [
      { "code": "US", "installs": 1200, "cr": 5.1, "pct": 100 },
      { "code": "DE", "installs": 400, "cr": 3.5, "pct": 33 }
    ],
    "devices": [
      { "name": "Android", "installs": 1900, "pct": 89 },
      { "name": "iOS", "installs": 240, "pct": 11 }
    ],
    "pwas": [
      {
        "id": "WZAX", "name": "Promo EN", "icon_url": null,
        "domains": [{ "id": "K3LP", "domain": "promo-en.example.com" }],
        "visits": 12480, "installs": 2140, "cr": 4.5, "status": "active"
      }
    ],
    "activity": [
      { "id": "WZAX", "type": "deploy", "msg": "Promo EN is running", "icon_url": null, "time": "2 hours ago" }
    ]
  }
}

metrics - итоги за период. У каждого показателя value - значение, trend - изменение в процентах к равному по длине периоду перед ним (его даты - в previous_period). Если в прошлом периоде был ноль, а сейчас что-то есть, trend равен 100.

ПолеЧто это
total_visitsВсе визиты
total_uniquesУникальные - первые визиты посетителя на поток
total_repeatsПовторные: визиты минус уникальные
total_whitesВизиты, которые фильтр отправил на white-страницу
total_installsУстановки
total_opensОткрытия оффера из установленного PWA
total_registrationsРегистрации из постбеков
total_depositsДепозиты; amounts - суммы выплат по каждой валюте отдельно
avg_crКонверсия: депозиты ÷ установки × 100%. trend - изменение к прошлому периоду, по тем же правилам, что у остальных

chart - те же визиты, вайты, установки и депозиты по дням. День, в котором были только установки или депозиты без визитов, тоже есть - с нулями в visits и whites.

geo - топ-10 стран по установкам: code - код страны (XX - не определилась), cr - депозиты ÷ установки, pct - сколько процентов установок от первой страны в списке.

devices - установки по типам устройств (Android, iOS, Desktop), pct - доля от всех установок.

pwas - топ-10 PWA по установкам за период. status: active - включено, paused - выключено, archived - в архиве. domains - домены PWA (пустой список, если их нет).

activity - десять последних изменённых PWA, без привязки к периоду. Нужна для ленты в панели, в скриптах обычно не пригождается.

Ошибки
КодmessageКогда
422The date from field is required. (and 1 more error)Не передан период
422The date from field must be a valid date.Дата не распознана
422The date to field must be a date after or equal to date from.date_to раньше date_from
422The date to field must be a date before or equal to 2026-02-01.Период длиннее месяца (в тексте - последний допустимый день)

Воронка и сплиты ​

GET/stats/funnel

Воронка Визиты → Уник → Установки → Открытия → Рег → Деп по дням и итогом, плюс результаты сплитов.

ПараметрОбязательноЧто это
date_from, date_toдаПериод, см. выше
pwa_idнетТолько одно PWA. Чужое или несуществующее - 404
bash
curl "https://panel.example.com/api/stats/funnel?date_from=2026-09-29&date_to=2026-10-05" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json"
php
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$api = new GuzzleHttp\Client([
    'base_uri' => 'https://panel.example.com/api/',
    'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
    'timeout' => 30,
]);

$response = $api->get('stats/funnel', ['query' => [
    'date_from' => '2026-09-29',
    'date_to' => '2026-10-05',
]]);
$funnel = json_decode($response->getBody(), true)['data']['funnel'];

foreach ($funnel['rows'] as $day) {
    echo "{$day['date']}: {$day['installs']} установок, {$day['deps']} депозитов, CR {$day['cr']}%\n";
}
python
# pip install requests
import requests

API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}

response = requests.get(f"{API}/stats/funnel", headers=HEADERS, params={
    "date_from": "2026-09-29",
    "date_to": "2026-10-05",
}, timeout=30)
funnel = response.json()["data"]["funnel"]

for day in funnel["rows"]:
    print(day["date"], day["installs"], "установок,", day["deps"], "депозитов, CR", day["cr"])
js
// Node.js 18+, без зависимостей; сохраните как script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };

const params = new URLSearchParams({ date_from: '2026-09-29', date_to: '2026-10-05' });
const response = await fetch(`${API}/stats/funnel?${params}`, {
  method: 'GET',
  headers,
  signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();

for (const day of data.funnel.rows) {
  console.log(day.date, day.installs, 'установок,', day.deps, 'депозитов, CR', day.cr);
}
Ответ (сокращён)
json
{
  "data": {
    "funnel": {
      "rows": [
        {
          "date": "2026-10-05",
          "visits": 640, "uniq": 590, "uniques": 520, "repeats": 120, "whites": 70,
          "installs": 120, "opens": 105, "regs": 24, "deps": 6,
          "inst_pct": 20.3, "open_pct": 87.5, "reg_pct": 20, "dep_pct": 25, "cr": 5
        }
      ],
      "totals": {
        "date": null,
        "visits": 1250, "uniq": 1100, "uniques": 1020, "repeats": 230, "whites": 130,
        "installs": 230, "opens": 203, "regs": 44, "deps": 10,
        "inst_pct": 20.9, "open_pct": 88.3, "reg_pct": 19.1, "dep_pct": 22.7, "cr": 4.3
      }
    },
    "splits": [
      {
        "id": "Lm3T",
        "name": "Split US",
        "status": "active",
        "visits": 6100, "installs": 1030, "conversions": 44, "cr": 4.3,
        "flows": [
          {
            "flow_id": "Qp8R", "pwa_id": "WZAX", "pwa_name": "Promo EN", "weight": 50,
            "visits": 6100, "installs": 1030, "conversions": 44, "cr": 4.3
          }
        ]
      }
    ],
    "pwa": null
  }
}

funnel.rows - по строке на день, новые сверху. funnel.totals - итог за весь период (date - null).

ПолеЧто это
visitsВсе визиты
uniqУникальные люди - сколько разных посетителей пришло
uniquesУникальные визиты - первые визиты посетителя на поток. Один человек, прошедший с основного PWA на похожее, - это два uniques, но один uniq
repeatsПовторные: visits − uniques
whitesУшли на white-страницу
installs, opens, regs, depsУстановки, открытия оффера, регистрации, депозиты
inst_pctУстановки ÷ uniq
open_pctОткрытия ÷ установки
reg_pctРегистрации ÷ установки
dep_pctДепозиты ÷ регистрации
crДепозиты ÷ установки - главная конверсия

Все проценты - числа от 0 до 100 (на коротком периоде бывает больше, см. выше).

uniq нельзя складывать

totals.uniq пересчитан по всему периоду: человек, приходивший три дня подряд, в нём один раз, а в сумме дней - три. Поэтому totals.uniq меньше суммы uniq по дням, и это правильно. Остальные счётчики складываются как обычно.

splits - все сплиты ваших команд с результатами за период: итог по сплиту и по каждому потоку внутри (flows) - к какому PWA ведёт поток (pwa_id, pwa_name) и его вес (weight). conversions - это депозиты, cr - депозиты ÷ установки. С параметром pwa_id список сплитов пустой: сплит объединяет несколько PWA, и для одного приложения он не считается.

pwa - выбранное PWA (id и name), если передан pwa_id, иначе null.

Ошибки
КодmessageКогда
422The date from field is required. (and 1 more error)Не передан период
422The date from field must be a valid date.Дата не распознана
422The date to field must be a date after or equal to date from.date_to раньше date_from
422The date to field must be a date before or equal to 2026-02-01.Период длиннее месяца (в тексте - последний допустимый день)
404Not foundpwa_id чужого или несуществующего PWA

Саб-метки ​

GET/stats/subs

Какие значения одной саб-метки приносят установки и депозиты: например, какие кампании, креативы или адсеты за sub_1 … sub_20 реально конвертят.

ПараметрОбязательноЧто это
date_from, date_toдаПериод, см. выше
slotдаНомер саб-метки, от 1 до 20
limitнетСколько значений вернуть, от 1 до 100, по умолчанию 20
searchнетТолько значения, в которых есть эта подстрока (без учёта регистра)
filters[sub_N]нетСузить по другим меткам: filters[sub_1]=fb-ua-creo1 - только визиты с таким sub_1. Можно несколько
pwa_idнетТолько одно PWA: его визиты и его конверсии. Чужое или несуществующее - 404

Пример: какие адсеты (sub_2) работают внутри креатива fb-ua-creo1 (sub_1).

bash
curl -G "https://panel.example.com/api/stats/subs" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json" \
  --data-urlencode "date_from=2026-09-29" \
  --data-urlencode "date_to=2026-10-05" \
  --data-urlencode "slot=2" \
  --data-urlencode "filters[sub_1]=fb-ua-creo1"
php
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$api = new GuzzleHttp\Client([
    'base_uri' => 'https://panel.example.com/api/',
    'headers' => ['Authorization' => 'Bearer ВАШ_КЛЮЧ', 'Accept' => 'application/json'],
    'timeout' => 30,
]);

$response = $api->get('stats/subs', ['query' => [
    'date_from' => '2026-09-29',
    'date_to' => '2026-10-05',
    'slot' => 2,
    'filters' => ['sub_1' => 'fb-ua-creo1'],
]]);
$subs = json_decode($response->getBody(), true)['data']['subs'];

foreach ($subs as $sub) {
    $value = $sub['value'] ?? '(пусто)';
    echo "{$value}: {$sub['installs']} установок, CR {$sub['cr']}%\n";
}
python
# pip install requests
import requests

API = "https://panel.example.com/api"
HEADERS = {"Authorization": "Bearer ВАШ_КЛЮЧ", "Accept": "application/json"}

response = requests.get(f"{API}/stats/subs", headers=HEADERS, params={
    "date_from": "2026-09-29",
    "date_to": "2026-10-05",
    "slot": 2,
    "filters[sub_1]": "fb-ua-creo1",
}, timeout=30)
subs = response.json()["data"]["subs"]

for sub in subs:
    print(sub["value"] or "(пусто)", sub["installs"], "установок, CR", sub["cr"])
js
// Node.js 18+, без зависимостей; сохраните как script.mjs
const API = 'https://panel.example.com/api';
const headers = { Authorization: 'Bearer ВАШ_КЛЮЧ', Accept: 'application/json', 'Content-Type': 'application/json' };

const params = new URLSearchParams({
  date_from: '2026-09-29',
  date_to: '2026-10-05',
  slot: 2,
  'filters[sub_1]': 'fb-ua-creo1',
});
const response = await fetch(`${API}/stats/subs?${params}`, {
  method: 'GET',
  headers,
  signal: AbortSignal.timeout(30000),
});
const { data } = await response.json();

for (const sub of data.subs) {
  console.log(sub.value || '(пусто)', sub.installs, 'установок, CR', sub.cr);
}
Ответ
json
{
  "data": {
    "slot": 2,
    "pwa": null,
    "subs": [
      { "value": "adset-7", "visits": 5210, "installs": 980, "conversions": 51, "cr": 5.2 },
      { "value": null, "visits": 1200, "installs": 140, "conversions": 3, "cr": 2.1 }
    ]
  }
}

Значения отсортированы по установкам, лучшие сверху. value: null - визиты, у которых эта метка не заполнена. conversions - депозиты, cr - депозиты ÷ установки.

Ключ в filters может быть только sub_1 … sub_20.

Ошибки
КодmessageКогда
422The date from field is required. (and 1 more error)Не передан период
422The date from field must be a valid date.Дата не распознана
422The date to field must be a date after or equal to date from.date_to раньше date_from
422The date to field must be a date before or equal to 2026-02-01.Период длиннее месяца (в тексте - последний допустимый день)
422The slot field is required.Не передан slot
422The slot field must not be greater than 20.slot больше 20
422The limit field must not be greater than 100.limit больше 100
422Filter key must be sub_1..sub_20.Ключ в filters - не sub_1 … sub_20
404Not foundpwa_id чужого или несуществующего PWA