PFM Generator · Data Ingestion Spec · v3

Контракт данных
на основе вашего source-mapping

Это не общий запрос «дайте статистику». Это точная карта: какое поле берём, из какого источника-истины и под каким именем — собранная на основе вашего же разбора FB Insights ⨝ PFM. Цель — чтобы ваш дев собрал выгруз одним пуллом, а движок начал калиброваться под этот аккаунт.

📌 Опираюсь на ваш разбор: ваше деление подтверждаю — ≈11 полей FB only, ≈3 поля PFM only, остальное композит. Сшивка по adset_id через sub2={{adset.id}} — хеш tracker→adset у вас уже в системе.
1Источник истины по каждому полю

Сгруппировано по тому, кто authoritative. Имена полей — как в FB Insights / вашем PFM.

FB ONLY creative · engagement · placement · retention
SpendspendFB authoritative (PFM mirror — только мониторинг, lag ~60s)
Hook Rate (3s)video_3_sec_watched_actions / impressionsИменно 3-sec, не ThruPlay
Outbound CTRoutbound_clicks_ctrOutbound, не ctr (all clicks)
Retention 25/50/75/100video_p25..p100_watched_actionsКривая досмотра → точка обрыва
CPC / CPMcpc, cpmКонтекст аукциона
FrequencyfrequencyСигнал выгорания
Shares / Comments / Savesactions[post_share, comment, post_save]Вирусность
Dates: launch → stopadset.start_time + ad.effective_statusНе PFM tree mtime — он неточный (ваше замечание учёл)
Placementbreakdown=publisher_platform, platform_positionСегментация перед скорингом
Geo / Statebreakdown=region, countryГео-форматы по штату
Agebreakdown=age, genderПривязка к аватару
Video link / filead.creative.video_id/{video-id}?fields=permalink_url,sourceДля разметки деталей
PFM ONLY правда по деньгам (FB не видит)
Реальные лидыleadsT (tracker)Authoritative. FB actions[lead] занижен — НЕ берём
Landing CVRtracker clicks → leadsTFB не видит лендинг
Sales / ROAS / payoutconversions, conversionsSold, payoutФинальный денежный итог
КОМПОЗИТ сшивка двух источников
CPLspend (FB) / leadsT (PFM)FB spend ÷ PFM-лиды. По FB-лидам считать нельзя
Acc averagesCTR/CPM (FB) + CPL/ROAS (PFM)Бенчмарки аккаунта для калибровки гейта ≥80
НАША СТОРОНА вы не считаете — делаем сами
Verdictbrain v5 (наша логика)Кросс-чек, не независимый лейбл
Detail tagsнаша taxonomy: format/hook/cta/avatarРазмечаем по видео; если есть нейминг крео — ускоряет
Language (EN/ES)вручнуюНативно нет нигде — ваше замечание, ставим сами
2Пайплайн: один FB-пулл + PFM merge

Ровно как вы описали — один Insights pull (ad-level + breakdowns) + tree merge по adset_id.

FB Insights (level=ad + breakdowns) ⨝ adset_id → PFM tracker (leadsT, payout, CVR) merged row → ElementScores
# 1) FB Insights — основной пулл (ad-level) GET /act_<AD_ACCOUNT_ID>/insights level = ad time_range = {since, until} # первый раз — весь период fields = ad_id, adset_id, ad_name, spend, impressions, video_3_sec_watched_actions, video_p25_watched_actions, video_p50_watched_actions, video_p75_watched_actions, video_p100_watched_actions, outbound_clicks, outbound_clicks_ctr, cpc, cpm, frequency, actions # 2) Те же insights с разбивками (отдельные пуллы) breakdowns = publisher_platform, platform_position breakdowns = region breakdowns = age, gender # 3) Видео-ссылка по каждому ad GET /<ad_id>?fields=creative{video_id} GET /<video_id>?fields=permalink_url, source # 4) Даты/статус GET /<adset_id>?fields=start_time GET /<ad_id>?fields=effective_status # 5) PFM merge по adset_id (sub2={{adset.id}}) leadsT, conversions, conversionsSold, payout, landing_cvr, spend_mirror
3Что прислать — схема merged-строки

Одна строка на ad. CSV или JSON. Это и есть финальный контракт — что движок принимает на вход.

{ "adset_id": "123456789", // ключ сшивки "ad_id": "987654321", "video_url": "https://...", // FB ── creative diagnostics "spend": 820.0, "impressions": 41000, "hook_rate_3s": 0.35, // 3-sec / impressions "outbound_ctr": 2.8, "ret_p25": 0.71, "ret_p50": 0.48, "ret_p75": 0.29, "ret_p100": 0.12, "cpc": 0.62, "cpm": 11.4, "frequency": 1.8, "shares": 34, "comments": 12, "saves": 21, "placement": "facebook/feed", "geo_state": "TX", "age": "35-44", "launch_date": "2026-05-20", "stop_date": "2026-05-27", // PFM ── money truth "leadsT": 121, "cpl_pfm": 6.8, // spend / leadsT "landing_cvr": 11.2, "conversionsSold": 14, "payout": 980.0, "roas": 3.1, // optional — если есть нейминг крео "format": "Breaking News", "hook": "H6", "cta": "C3", "avatar": "A", "language": "EN" }
4Что НЕ просим — и почему (учёл ваши нюансы)
  • FB lead counts — занижены (нет tracker-видимости). Лиды берём только leadsT из PFM.
  • PFM tree mtime для дат — неточный. Даты берём из FB start_time / effective_status.
  • Verdict и detail tags от вас — это наша сторона (brain v5 / taxonomy). С вас — только сырьё.
  • CVR/sales из FB — нет conversion pixel на sale. Только PFM conversions/payout.
  • CTR = outbound_clicks_ctr, не all-clicks. ✔ согласовано
  • Hook = video_3_sec_watched_actions, не ThruPlay. ✔ согласовано
  • Spend — FB authoritative, PFM mirror как мониторинг. ✔ по вашему маппингу
  • Leads/CPL/ROAS — PFM как источник истины. ✔ по вашему маппингу
5Объём и частота
  • Первый раз: весь доступный период, ad-level. И виннеры, и слитые — отрицательные данные = анти-паттерны.
  • Дальше: раз в неделю свежие ad'ы (крео выгорают за ~7 дней).
  • Формат: CSV или JSON по схеме выше (раздел 3). Числами, не скриншотами.
  • Объём пайплайна: один FB Insights pull + breakdowns + PFM merge. Никакой ручной возни — у вас это один запрос.