#Чтение аналитики
Статус: Доступно. Все четыре метода (
timeseries,traffic-sources,funnel,visibility) работают. Составы полей ниже сверены с реализацией; отличия от экранов кабинета оговорены в тексте.
Назначение: получать агрегированную аналитику Формула ИИ в свои системы и отчёты: временные ряды, источники трафика, воронку и видимость в поиске.
#Содержание
- Когда использовать
- Доступ
- Общее для всех методов
- Временные ряды
- Источники трафика
- Воронка
- Видимость
- Свежесть данных: data_as_of
- Ошибки
- Примеры
- Открытые вопросы
#Когда использовать
| Нужно | Метод |
|---|---|
| График одной или нескольких метрик по дням или неделям | GET /analytics/timeseries |
| Откуда приходят посетители, включая ИИ-ассистентов | GET /analytics/traffic-sources |
| Путь от показов в поиске до выручки | GET /analytics/funnel |
| Доля видимости, позиции, цитирование ИИ | GET /analytics/visibility |
| Готовые экраны «Обзор» и «Пульс» целиком | Дашборды |
#Доступ
| Базовый адрес | https://<домен ячейки>/api/public/v1 (RU https://formula-cream.pro, EN https://wfacademy.org, ID https://wfacademy.id) |
| Аутентификация | Authorization: Bearer <ключ> (Аутентификация) |
| Область | analytics:read |
| Платно | нет |
| Персональные данные | нет: только агрегаты. Строки визитов, IP и хеши наружу не отдаются |
| Предел чтения | 600 запросов в минуту (Соглашения) |
| Пагинация | не используется: все методы возвращают агрегаты за запрошенный период целиком |
Данные принадлежат арендатору ключа. Чужие данные и данные платформы недоступны.
#Общее для всех методов
- Период задаётся параметрами
fromиto— датамиYYYY-MM-DD(включительно). Параметр кабинетаdaysв публичном API не используется. - Окна считаются полными сутками; текущий неполный день в расчётах сравнения не участвует.
- Деньги везде — объект
{"amount": "строка", "currency": "RUB"}; сумма строкой (Соглашения). Валюта — валюта ячейки. - Свежесть данных. Каждый блок и каждый ряд несёт поле
data_as_of— объект{источник: дата}: до какой даты данные источника полны (раздел ниже). В ответах-списках (data— массив) поле лежит на верхнем уровне рядом сdata. - Отсутствие данных не равно нулю. Там, где источник не подключён или данных ещё нет, поле помечено
availability(ok,no_data,no_source,not_connected), а значение —null. - Ошибка чтения базы — это
5xx, а не пустой ответ. - Новые поля в ответах могут появляться: клиент их игнорирует.
#Временные ряды
GET /analytics/timeseries
Один или несколько рядов по дням либо неделям. Публичный API принимает период как from/to и шаг granularity.
#Параметры запроса
| Параметр | Тип | Обязателен | Ограничения | Пример |
|---|---|---|---|---|
metric | string | да | от 1 до 8 уникальных имён через запятую | sessions,clicks |
from | string | да | дата YYYY-MM-DD | 2026-09-01 |
to | string | да | дата не раньше from; окно не длиннее 365 дней. Позже последних полных суток (вчера, UTC) сужается до вчера; фактическая граница возвращается в to ответа. Если и from позже вчера — 422 | 2026-09-30 |
granularity | string | нет | day (по умолчанию) или week | day |
engine | string | нет | google, yandex или bing; только для поисковых метрик (impressions, clicks, ctr, position). Значение bing доступно после проверки источника | google |
cluster | string | нет | идентификатор кластера запросов (UUID); чужой или несуществующий — 404 not_found | 3f1c8a52-7d0e-4b69-9a14-c2e5b86d0f37 |
#Метрики
Публичный перечень первой версии — 13 метрик. Внутренние метрики кабинета (стоимость вовлечения api_cost, comments_*, yt_*) не публикуются.
| Метрика | Что измеряет | Источник | Единица | Свёртка за период |
|---|---|---|---|---|
sessions | сессии на сайте | Яндекс Метрика, Google Analytics 4 | число | сумма |
pageviews | просмотры страниц | Google Analytics 4 | число | сумма |
visitors | уникальные посетители по дням | трекер платформы | число | сумма дневных значений |
bounce_rate | доля отказов | Google Analytics 4 | проценты | среднее |
impressions | показы в поиске | поисковые консоли | число | сумма |
clicks | клики из поиска | поисковые консоли | число | сумма |
ctr | доля кликов от показов | поисковые консоли | проценты | отношение сумм кликов и показов |
position | средняя позиция | поисковые консоли | позиция | среднее |
ai_referrals | переходы из ИИ-ассистентов | трекер платформы | число | сумма |
bot_hits | заходы роботов и ИИ-краулеров | серверный маячок модуля | число | сумма |
leads | новые лиды | CRM платформы | число | сумма |
deals_won | выигранные сделки | CRM платформы и офлайн-конверсии | число | сумма |
revenue | выручка | CRM платформы и офлайн-конверсии | деньги | сумма |
С параметром engine поисковые метрики берутся из выбранной системы: google — Search Console, yandex — Яндекс Вебмастер, bing — Bing Webmaster. bot_hits требует серверного маячка (модуль или PHP-вариант трекера); без него метрика получает availability: "no_source".
deals_won и revenue не считают одну и ту же сделку дважды: правила замены сделки конверсией и возвратов — на странице Офлайн-конверсии.
#Ответ (одна метрика)
{
"data": {
"metric": "clicks",
"availability": "ok",
"reason": null,
"from": "2026-09-01",
"to": "2026-09-30",
"granularity": "day",
"agg": "sum",
"engine": "yandex",
"series": [
{ "date": "2026-09-01", "value": 412 },
{ "date": "2026-09-02", "value": 398 }
],
"comparison": {
"current": 12340,
"prev": 11020,
"delta_pct": 11.98,
"data_through": "2026-09-28"
},
"summary": { "total": 12340, "latest": 401, "non_zero_days": 30 },
"cluster_applied": false,
"data_as_of": { "yandex_webmaster": "2026-09-28" }
}
}
| Поле | Тип | Описание |
|---|---|---|
availability | string | ok, no_data или no_source; у каждого ряда своя |
reason | string | null | код причины, если availability не ok |
series | array | ряд значений; дни без данных заполнены нулями |
agg | string | способ свёртки: sum, avg |
comparison.current / prev | number | значение за период и за такой же предыдущий |
comparison.delta_pct | number | null | изменение в процентах; null, если база равна нулю |
comparison.data_through | string | последняя дата, по которую данные полны |
summary | object | null | total, latest, non_zero_days; null, если ряда нет |
engine | string | null | поисковик ряда; null у метрик, не привязанных к поиску |
cluster_applied | boolean | true, если фильтр по кластеру применён; для метрик, не привязанных к запросам, всегда false |
data_as_of | object | до какой даты полны данные источников этого ряда |
При нескольких метриках возвращается {"data": {"items": [ … ]}} в порядке запроса; у каждого элемента свои data_as_of и availability.
Для метрики revenue значения series[].value, comparison.current, comparison.prev, summary.total и summary.latest — объекты денег:
{ "date": "2026-09-01", "value": { "amount": "1240.00", "currency": "GBP" } }
При granularity=week точка ряда описывает неделю; date — первый день недели (понедельник, UTC). Первая и последняя недели периода могут быть неполными.
Для сравнения платформа читает 2 × период + 10 дней, чтобы выровнять источники с разной задержкой.
#Источники трафика
GET /analytics/traffic-sources
Список источников первого визита за период: сессии, уникальные посетители и лиды по каждому источнику.
#Параметры запроса
| Параметр | Тип | Обязателен | Ограничения | Пример |
|---|---|---|---|---|
from | string | да | YYYY-MM-DD | 2026-10-01 |
to | string | да | не раньше from | 2026-10-07 |
include | string | нет | series: добавить ряд по дням в каждый элемент | series |
Экран кабинета принимает период только числом дней 7, 14, 28, 90; публичный метод принимает любые from и to.
#Ответ
{
"data": [
{ "source": "google", "kind": "search", "sessions": 820, "visitors": 640, "leads": 9 },
{ "source": "yandex", "kind": "search", "sessions": 460, "visitors": 390, "leads": 5 },
{ "source": "chatgpt", "kind": "ai_assistant", "sessions": 190, "visitors": 150, "leads": 4 },
{ "source": "social", "kind": "social", "sessions": 96, "visitors": 88, "leads": 1 },
{ "source": "direct", "kind": "direct", "sessions": 410, "visitors": 330, "leads": 2 }
],
"data_as_of": { "tracker": "2026-10-07" }
}
С параметром include=series каждый элемент получает поле series — значения по дням:
{
"source": "google", "kind": "search", "sessions": 820, "visitors": 640, "leads": 9,
"series": [
{ "date": "2026-10-01", "sessions": 120, "visitors": 95, "leads": 1 },
{ "date": "2026-10-02", "sessions": 131, "visitors": 101, "leads": 2 }
]
}
| Поле | Тип | Описание |
|---|---|---|
source | string | источник из таблицы ниже |
kind | string | группа источника: search, ai_assistant, social, ads, direct, other |
sessions | integer | сессии (посещения) из этого источника за период |
visitors | integer | null | уникальные посетители за день, просуммированные по периоду; null для сайтов в режиме маячка anonymous |
leads | integer | лиды, источник которых определён как этот |
series | array | только при include=series: те же sessions, visitors, leads по дням |
source | kind | Что это |
|---|---|---|
google, yandex, bing | search | органический поиск |
chatgpt, perplexity, ai_other | ai_assistant | переходы из ИИ-ассистентов (см. метки); ai_other — прочие ассистенты |
social | social | соцсети |
ads | ads | платная реклама |
direct | direct | прямые заходы |
other | other | прочее |
Источники без посещений за период в список не попадают. Тот же формат использован в Быстром старте.
«Уникальный посетитель» считается по хешам IP и User-Agent за день; для сайтов в режиме маячка anonymous такая оценка недоступна, и visitors равно null.
#Воронка
GET /analytics/funnel
Путь «показы → клики → сессии → лиды → сделки → выручка» за период.
#Параметры запроса
| Параметр | Тип | Обязателен | Ограничения | Пример |
|---|---|---|---|---|
from, to | string | да | YYYY-MM-DD | 2026-10-01, 2026-10-28 |
engine | string | нет | yandex, google, both; по умолчанию — поисковик рынка ячейки. both показывает движки раздельно и не складывает их | google |
#Ответ
{
"data": {
"engine": "google",
"from": "2026-10-01",
"to": "2026-10-28",
"steps": [
{
"key": "clicks",
"availability": "ok",
"sources": ["g:search_console"],
"unit": "count",
"current": 4210,
"prev": 3880,
"delta_pct": 8.5,
"data_through": "2026-10-25"
},
{
"key": "revenue",
"availability": "ok",
"sources": ["crm"],
"unit": "money",
"current": { "amount": "5240.00", "currency": "GBP" },
"prev": { "amount": "4100.00", "currency": "GBP" },
"delta_pct": 27.8,
"data_through": "2026-10-28"
}
],
"by_channel": [
{ "channel": "search", "availability": "ok", "sources": ["g:search_console"], "clicks": 4210, "cost": null, "leads": 31 }
],
"crm": { "availability": "ok" }
},
"data_as_of": { "g:search_console": "2026-10-25", "crm": "2026-10-28" }
}
| Поле | Тип | Описание |
|---|---|---|
steps[].key | string | impressions, clicks, sessions, leads, deals_created, deals_won, revenue |
steps[].availability | string | ok, no_data, no_source |
steps[].unit | string | count или money |
steps[].sources | array | из чего посчитан шаг |
steps[].current / prev | number | object | null | значение и предыдущий период; для unit: "money" — объект денег {amount, currency} |
steps[].data_through | string | последняя полная дата источника |
by_channel | array | каналы search, ads, social, direct_other: availability, sources, клики, расходы (cost, объект денег), лиды; null означает «этим каналом не измеряется» и не равно 0; канал direct_other измерить пока нечем |
by_product | array | разрез по продуктам: course_slug, name, sales_mode, leads, leads_prev, deals_won, deals_won_prev |
search_by_engine | array | только при engine=both: движки раздельно |
crm | object | availability (ok или no_data) и необязательный reason |
Лиды и сделки считаются так же, как в отчётах стратега; шаги deals_won и revenue берутся из CRM платформы или из офлайн-конверсий без двойного счёта (правила). Коэффициенты перехода между шагами сервер не возвращает: их считает клиент по числителю и знаменателю, а при нулевом или неизвестном знаменателе показывает «нет данных», а не «0 %». Статус no_source означает, что у рынка ячейки нет источника вовсе (например, Яндекс и Директ на EN и ID), и значение не равно нулю. Данные CRM пополняются в том числе офлайн-конверсиями.
#Видимость
GET /analytics/visibility
#Параметры запроса
| Параметр | Тип | Обязателен | Ограничения | Пример |
|---|---|---|---|---|
from, to | string | да | YYYY-MM-DD | 2026-10-01, 2026-10-28 |
compare | boolean | нет | сравнить с предыдущим периодом | true |
engine | string | нет | yandex, google, both | google |
cluster | string | нет | идентификатор кластера запросов (UUID); чужой или несуществующий — 404 not_found | 3f1c8a52-7d0e-4b69-9a14-c2e5b86d0f37 |
#Ответ
Каждый раздел самостоятелен и несёт собственную доступность (availability: ok, no_data, not_connected), код причины reason, код источника source и data_as_of — до какой даты полны данные. Пустой раздел бывает трёх видов: источник не подключён, данных за окно нет, показатель нечем считать; ноль во всех трёх случаях означал бы «нас не видно» там, где мы не спрашивали.
{
"data": {
"share": {
"availability": "ok", "source": "g:search_console", "data_as_of": { "g:search_console": "2026-10-25" },
"data": {
"value": 14.2,
"comparison": { "current": 14.2, "prev": 12.9, "delta_pct": 10.1 },
"keywords": 312,
"volume_total": 48200
}
},
"distribution": {
"availability": "ok", "source": "g:search_console", "data_as_of": { "g:search_console": "2026-10-25" },
"data": { "top3": 18, "top10": 74, "top30": 210, "outside": 530, "total": 832, "median": 21.5, "average": 29.3 }
},
"sov": {
"availability": "ok", "source": "serp", "data_as_of": { "serp": "2026-10-25" },
"data": {
"rows": [ { "domain": "example.com", "appearances": 140, "share_pct": 22.4, "keywords": 96, "is_ours": true, "competitor_id": null, "competitor_status": null } ],
"keywords": 120,
"appearances_total": 625,
"redacted": true,
"others": { "domains": 41, "appearances": 485, "share_pct": 77.6 }
}
},
"aeo": {
"availability": "ok", "source": "aeo", "data_as_of": { "aeo": "2026-10-27" },
"data": {
"series": [ { "date": "2026-10-27", "value": 12.5, "probes": 24 } ],
"engines": [ { "engine": "perplexity", "probes": 24, "cited": 3, "rate": 12.5 } ],
"probes": 96, "cited": 11, "rate": 11.5,
"comparison": { "current": 11.5, "prev": 9.0, "delta_pct": 27.8 }
}
},
"regions": { "availability": "not_connected", "reason": "no_country_dimension", "source": "g:search_console", "data_as_of": {}, "data": { "rows": [] } }
}
}
| Раздел | Что показывает |
|---|---|
share | доля видимости: позиции, взвешенные по объёму запросов, в процентах; value: null значит «считать не из чего», а не ноль |
distribution | сколько запросов в топ-3, топ-10, топ-30 и за их пределами; медиана и средняя позиция |
sov | доля голоса: сколько раз домен встретился в топ-10 по ключам окна. Без права на сырые данные конкурентов (competitors.raw) имена скрыты (redacted: true), остальное свёрнуто в others |
aeo | цитирование сайта в ответах ИИ-ассистентов: ряд по дням, срез по движкам (probes — замеров, cited — с цитированием), доля цитирований в процентах |
regions | не подключено: разрез по странам пока недоступен (reason: no_country_dimension) |
Значения в примере вымышлены. Названия разделов в публичном ответе (share, distribution, sov, aeo, regions) взяты из внутреннего ответа и могут быть переименованы.
#Свежесть данных: data_as_of
Источники приходят с разной задержкой: Search Console и Bing запаздывают примерно на 2–3 дня, счётчики и CRM — почти без задержки. Чтобы вы не принимали недостающие дни за падение, ответ сообщает, до какой даты данные каждого источника полны.
"data_as_of": {
"tracker": "2026-10-10",
"yandex_webmaster": "2026-10-08",
"g:search_console": "2026-10-08"
}
Правила:
- Поле
data_as_of— объект{источник: дата}— присутствует в каждом блоке и в каждом ряду: в элементеdata(объект), в каждом элементеitems, в каждом разделе видимости. У ответов, гдеdata— массив (traffic-sources), поле лежит на верхнем уровне ответа рядом сdata. - Последние дни окна по источникам с задержкой могут быть неполными; сравнения платформа выравнивает по
data_throughисточника. - Источник, для которого данных нет совсем, в объект не попадает; о причине сообщает
availability.
#Ошибки
Формат — application/problem+json; общий каталог — в Соглашениях.
| HTTP | Код | Когда |
|---|---|---|
| 404 | not_found | cluster чужой или не существует |
| 422 | validation_failed | неизвестная метрика; метрик больше 8; период длиннее 365 дней; to раньше from; неверная гранулярность; недопустимое значение engine или include |
| 401 | invalid_api_key | ключ неверен, отозван или истёк |
| 403 | scope_missing | нет области analytics:read |
| 403 | ip_not_allowed | запрос с адреса вне списка IP интеграции |
| 429 | rate_limited | превышен предел |
| 5xx | — | ошибка чтения данных; не пустой ответ |
#Примеры
#curl
curl -sS 'https://formula-cream.pro/api/public/v1/analytics/timeseries?metric=clicks,impressions&from=2026-09-01&to=2026-09-30&engine=yandex' \
-H 'Authorization: Bearer sap_ru_live_EXAMPLE0KEYI_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE'
#JavaScript
const base = 'https://wfacademy.org/api/public/v1';
const url = new URL(`${base}/analytics/funnel`);
url.search = new URLSearchParams({ from: '2026-10-01', to: '2026-10-28', engine: 'google' });
const response = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.API_KEY}` },
});
if (!response.ok) throw new Error(`API: ${response.status}`);
const { data } = await response.json();
console.log(data.steps.map((s) => `${s.key}: ${s.current}`).join('\n'));
#Python
import os, requests
response = requests.get(
"https://wfacademy.id/api/public/v1/analytics/visibility",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
params={"from": "2026-10-01", "to": "2026-10-28", "compare": "true"},
timeout=10,
)
response.raise_for_status()
print(response.json()["data"]["share"]["data"]["value"])
#PHP
<?php
$ch = curl_init('https://formula-cream.pro/api/public/v1/analytics/traffic-sources?from=2026-10-01&to=2026-10-07');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('API_KEY')],
]);
$data = json_decode(curl_exec($ch), true);
foreach ($data['data'] as $row) {
echo $row['source'], ': ', $row['sessions'], PHP_EOL;
}
#Открытые вопросы
- Техническое. Недельная гранулярность. Проект задаёт
from,toиgranularity=day|week, а текущий маршрут кабинета принимаетdays(1–365) и недели не знает. Неделя добавляется при выделении публичного сервиса (агрегация в SQL); день недели вdateуточнится. - Техническое. Источник Bing в рядах включается после проверки источника: маршрут кабинета принимает только
engine=google|yandex. - Техническое. Определения
sessionsиvisitorsвtraffic-sourcesстроятся по хитам трекера и хешам IP и User-Agent за день, а не по сессиям счётчиков; единицыbounce_rateиctr(проценты) и формаseriesвtraffic-sourcesуточнятся в OpenAPI. - Техническое.
summary.delta_pctво внутреннем ответе сравнивает половины окна, а честное сравнение с предыдущим периодом —comparison. В публичном ответе остаётся толькоcomparison. - Техническое. Пределы на тяжёлые методы (
funnel,visibility) отдельно от общего предела чтения не определены. - Техническое. Код ошибки чтения. В каталоге кодов нет кода для внутренней ошибки чтения, поэтому в таблицах ошибок она показана как «5xx»; код нужно добавить в каталог.
- К владельцу. Разрез по странам (
regions) недоступен: отдельная доработка.