Формула ИИ для разработчиков Справочник API Каталог ошибок OpenAPI
Разделы

#Чтение аналитики

Статус: Доступно. Все четыре метода (timeseries, traffic-sources, funnel, visibility) работают. Составы полей ниже сверены с реализацией; отличия от экранов кабинета оговорены в тексте.

Назначение: получать агрегированную аналитику Формула ИИ в свои системы и отчёты: временные ряды, источники трафика, воронку и видимость в поиске.

#Содержание

  1. Когда использовать
  2. Доступ
  3. Общее для всех методов
  4. Временные ряды
  5. Источники трафика
  6. Воронка
  7. Видимость
  8. Свежесть данных: data_as_of
  9. Ошибки
  10. Примеры
  11. Открытые вопросы

#Когда использовать

НужноМетод
График одной или нескольких метрик по дням или неделям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 запросов в минуту (Соглашения)
Пагинацияне используется: все методы возвращают агрегаты за запрошенный период целиком

Данные принадлежат арендатору ключа. Чужие данные и данные платформы недоступны.

#Общее для всех методов

#Временные ряды

GET /analytics/timeseries

Один или несколько рядов по дням либо неделям. Публичный API принимает период как from/to и шаг granularity.

#Параметры запроса

ПараметрТипОбязателенОграниченияПример
metricstringдаот 1 до 8 уникальных имён через запятуюsessions,clicks
fromstringдадата YYYY-MM-DD2026-09-01
tostringдадата не раньше from; окно не длиннее 365 дней. Позже последних полных суток (вчера, UTC) сужается до вчера; фактическая граница возвращается в to ответа. Если и from позже вчера — 4222026-09-30
granularitystringнетday (по умолчанию) или weekday
enginestringнетgoogle, yandex или bing; только для поисковых метрик (impressions, clicks, ctr, position). Значение bing доступно после проверки источникаgoogle
clusterstringнетидентификатор кластера запросов (UUID); чужой или несуществующий — 404 not_found3f1c8a52-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" }
  }
}
ПолеТипОписание
availabilitystringok, no_data или no_source; у каждого ряда своя
reasonstring | nullкод причины, если availability не ok
seriesarrayряд значений; дни без данных заполнены нулями
aggstringспособ свёртки: sum, avg
comparison.current / prevnumberзначение за период и за такой же предыдущий
comparison.delta_pctnumber | nullизменение в процентах; null, если база равна нулю
comparison.data_throughstringпоследняя дата, по которую данные полны
summaryobject | nulltotal, latest, non_zero_days; null, если ряда нет
enginestring | nullпоисковик ряда; null у метрик, не привязанных к поиску
cluster_appliedbooleantrue, если фильтр по кластеру применён; для метрик, не привязанных к запросам, всегда false
data_as_ofobjectдо какой даты полны данные источников этого ряда

При нескольких метриках возвращается {"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

Список источников первого визита за период: сессии, уникальные посетители и лиды по каждому источнику.

#Параметры запроса

ПараметрТипОбязателенОграниченияПример
fromstringдаYYYY-MM-DD2026-10-01
tostringдане раньше from2026-10-07
includestringнет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 }
  ]
}
ПолеТипОписание
sourcestringисточник из таблицы ниже
kindstringгруппа источника: search, ai_assistant, social, ads, direct, other
sessionsintegerсессии (посещения) из этого источника за период
visitorsinteger | nullуникальные посетители за день, просуммированные по периоду; null для сайтов в режиме маячка anonymous
leadsintegerлиды, источник которых определён как этот
seriesarrayтолько при include=series: те же sessions, visitors, leads по дням
sourcekindЧто это
google, yandex, bingsearchорганический поиск
chatgpt, perplexity, ai_otherai_assistantпереходы из ИИ-ассистентов (см. метки); ai_other — прочие ассистенты
socialsocialсоцсети
adsadsплатная реклама
directdirectпрямые заходы
otherotherпрочее

Источники без посещений за период в список не попадают. Тот же формат использован в Быстром старте.

«Уникальный посетитель» считается по хешам IP и User-Agent за день; для сайтов в режиме маячка anonymous такая оценка недоступна, и visitors равно null.

#Воронка

GET /analytics/funnel

Путь «показы → клики → сессии → лиды → сделки → выручка» за период.

#Параметры запроса

ПараметрТипОбязателенОграниченияПример
from, tostringдаYYYY-MM-DD2026-10-01, 2026-10-28
enginestringнет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[].keystringimpressions, clicks, sessions, leads, deals_created, deals_won, revenue
steps[].availabilitystringok, no_data, no_source
steps[].unitstringcount или money
steps[].sourcesarrayиз чего посчитан шаг
steps[].current / prevnumber | object | nullзначение и предыдущий период; для unit: "money" — объект денег {amount, currency}
steps[].data_throughstringпоследняя полная дата источника
by_channelarrayканалы search, ads, social, direct_other: availability, sources, клики, расходы (cost, объект денег), лиды; null означает «этим каналом не измеряется» и не равно 0; канал direct_other измерить пока нечем
by_productarrayразрез по продуктам: course_slug, name, sales_mode, leads, leads_prev, deals_won, deals_won_prev
search_by_enginearrayтолько при engine=both: движки раздельно
crmobjectavailability (ok или no_data) и необязательный reason

Лиды и сделки считаются так же, как в отчётах стратега; шаги deals_won и revenue берутся из CRM платформы или из офлайн-конверсий без двойного счёта (правила). Коэффициенты перехода между шагами сервер не возвращает: их считает клиент по числителю и знаменателю, а при нулевом или неизвестном знаменателе показывает «нет данных», а не «0 %». Статус no_source означает, что у рынка ячейки нет источника вовсе (например, Яндекс и Директ на EN и ID), и значение не равно нулю. Данные CRM пополняются в том числе офлайн-конверсиями.

#Видимость

GET /analytics/visibility

#Параметры запроса

ПараметрТипОбязателенОграниченияПример
from, tostringдаYYYY-MM-DD2026-10-01, 2026-10-28
comparebooleanнетсравнить с предыдущим периодомtrue
enginestringнетyandex, google, bothgoogle
clusterstringнетидентификатор кластера запросов (UUID); чужой или несуществующий — 404 not_found3f1c8a52-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"
}

Правила:

#Ошибки

Формат — application/problem+json; общий каталог — в Соглашениях.

HTTPКодКогда
404not_foundcluster чужой или не существует
422validation_failedнеизвестная метрика; метрик больше 8; период длиннее 365 дней; to раньше from; неверная гранулярность; недопустимое значение engine или include
401invalid_api_keyключ неверен, отозван или истёк
403scope_missingнет области analytics:read
403ip_not_allowedзапрос с адреса вне списка IP интеграции
429rate_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;
}

#Открытые вопросы

  1. Техническое. Недельная гранулярность. Проект задаёт from, to и granularity=day|week, а текущий маршрут кабинета принимает days (1–365) и недели не знает. Неделя добавляется при выделении публичного сервиса (агрегация в SQL); день недели в date уточнится.
  2. Техническое. Источник Bing в рядах включается после проверки источника: маршрут кабинета принимает только engine=google|yandex.
  3. Техническое. Определения sessions и visitors в traffic-sources строятся по хитам трекера и хешам IP и User-Agent за день, а не по сессиям счётчиков; единицы bounce_rate и ctr (проценты) и форма series в traffic-sources уточнятся в OpenAPI.
  4. Техническое. summary.delta_pct во внутреннем ответе сравнивает половины окна, а честное сравнение с предыдущим периодом — comparison. В публичном ответе остаётся только comparison.
  5. Техническое. Пределы на тяжёлые методы (funnel, visibility) отдельно от общего предела чтения не определены.
  6. Техническое. Код ошибки чтения. В каталоге кодов нет кода для внутренней ошибки чтения, поэтому в таблицах ошибок она показана как «5xx»; код нужно добавить в каталог.
  7. К владельцу. Разрез по странам (regions) недоступен: отдельная доработка.