Що потрібно від вас
Рівно дві речі — фід угод і фід лідів. Це HTTP-ендпоїнти (GET), які за вказаний період повертають JSON-масив записів. Все інше — рекламу, GA4, агрегацію, кеші, графіки — робить GalaVision.
Мінімальний обсяг роботи. Якщо у вас Bitrix24 — писати нічого не треба, достатньо вхідного webhook. Якщо CRM саморобна — це один контролер на кожен фід, зазвичай пів дня роботи.
Як це працює
- Ви віддаєте нам URL фіду (з токеном у шляху або в query).
- GalaVision періодично запитує фід за вікном дат і кешує відповідь.
- Записи нормалізуються: дати, суми, статуси, UTM-мітки.
- Угоди зшиваються з рекламними витратами за
utm_source / utm_medium / utm_campaignі показуються в дашборді як дохід, ROAS, CAC, CPL.
Фід читається тільки на читання. Ми нічого не пишемо у вашу систему.
Загальний контракт
Запит
GET https://crm.example.com/feed/deals?date_from=2026-07-01&date_to=2026-07-31&token=SECRET
Accept: application/json
| Параметр | Тип | Опис |
|---|---|---|
date_from | string | Початок вікна, YYYY-MM-DD, включно |
date_to | string | Кінець вікна, YYYY-MM-DD, включно |
token | string | Статичний секрет. Можна замінити на заголовок
Authorization: Bearer … або секретний шлях |
Відповідь
Масив об'єктів у корені або обгортка з полем result / items —
підтримуються обидва варіанти. Кодування UTF-8, Content-Type: application/json.
[
{ "ID": "10231", "OPPORTUNITY": 12400.00, ... },
{ "ID": "10232", "OPPORTUNITY": 890.50, ... }
]
Вимоги
- Відповідь має вкладатися в 60 секунд на вікні в один місяць.
- Якщо записів багато — підтримайте пагінацію параметрами
start/limitі поверніть загальну кількість у поліtotal. - Ідемпотентність: той самий запит за закритий період має повертати ті самі дані.
- Помилка — звичайний HTTP-код (4xx/5xx), не «200 з текстом помилки».
Фід продажів (угоди)
Один запис = одна угода. У вікно потрапляють угоди за датою закриття
(CLOSEDATE). Назви полів наведені в «бітріксовому» стилі, бо він найпоширеніший —
але приймаються й ваші, ми зіставимо їх при налаштуванні.
| Поле | Тип | Обов'язково | Опис |
|---|---|---|---|
ID | string | так | Унікальний ідентифікатор угоди |
OPPORTUNITY | number | так | Сума угоди в базовій валюті, без пробілів |
CLOSEDATE | date | так | Дата закриття / оплати, YYYY-MM-DD |
STAGE_SEMANTIC_ID | enum | так | S — успішна,
F — провалена, P — у роботі |
STAGE_RAW | string | бажано | Людська назва етапу, для розшифровок |
DATE_CREATE | date | бажано | Дата створення — дає довжину циклу угоди |
BEGINDATE | date | ні | Дата початку роботи над угодою |
UTM_SOURCE | string | так* | Мітка джерела з першого візиту |
UTM_MEDIUM | string | так* | Мітка каналу |
UTM_CAMPAIGN | string | бажано | Кампанія — дає розріз до оголошення |
CONTACT_ID | string | так | Ідентифікатор клієнта — потрібен для «нових / повторних» |
COMPANY_ID | string | ні | Для B2B-угод |
IS_RETURN_CUSTOMER | Y/N | бажано | Якщо не передасте — порахуємо за CONTACT_ID |
UF_CRM_COMPANY_TYPE | string | бажано | Сегмент: «Гурт» / «Роздріб» або ваші назви |
SOURCE_ID | string | ні | Джерело в термінах CRM (WEB, CALL, …) |
ASSIGNED_BY | string | ні | Відповідальний менеджер |
* UTM обов'язкові для наскрізної аналітики. Без них система працюватиме, але не зможе віднести дохід до конкретного каналу — залишиться лише загальний ROAS.
Приклад
{
"ID": "10231",
"OPPORTUNITY": 12400.00,
"CLOSEDATE": "2026-07-14",
"DATE_CREATE": "2026-07-09",
"STAGE_SEMANTIC_ID": "S",
"STAGE_RAW": "Оплачено",
"UTM_SOURCE": "google",
"UTM_MEDIUM": "cpc",
"UTM_CAMPAIGN": "pmax_catalog",
"CONTACT_ID": "50231",
"COMPANY_ID": "1043",
"IS_RETURN_CUSTOMER": "N",
"UF_CRM_COMPANY_TYPE": "Гурт",
"SOURCE_ID": "WEB",
"ASSIGNED_BY": "Олена"
}
Фід лідів
Один запис = одне звернення. У вікно потрапляють ліди за датою зміни статусу
(CLOSEDATE); дата появи передається окремо.
| Поле | Тип | Обов'язково | Опис |
|---|---|---|---|
ID | string | так | Ідентифікатор ліда |
Date.Lead | date | так | Коли лід з'явився |
CLOSEDATE | date | так | Коли лід отримав фінальний статус |
STAGE_SEMANTIC_ID | enum | так | P у роботі,
S перейшов в угоду, F відмова / брак |
STAGE_RAW | string | бажано | Назва етапу словами |
Source | string | так | Джерело звернення: сайт, дзвінок, форма, маркетплейс |
UTM_SOURCE | string | бажано | Мітка, якщо звернення з реклами |
UTM_MEDIUM | string | бажано | Мітка каналу |
Client.Id | string | бажано | Ідентифікатор клієнта — щоб не рахувати дублі |
Responsible person | string | ні | Менеджер — дає розріз по відділу продажу |
UF_CRM_COMPANY_TYPE | string | ні | Сегмент клієнта |
Приклад
{
"ID": "L88120",
"Date.Lead": "2026-07-11",
"CLOSEDATE": "2026-07-13",
"STAGE_SEMANTIC_ID": "S",
"STAGE_RAW": "Конвертовано в угоду",
"Source": "Форми зв'язку",
"UTM_SOURCE": "facebook",
"UTM_MEDIUM": "cpc",
"Client.Id": "50231",
"Responsible person": "Ігор",
"UF_CRM_COMPANY_TYPE": "Роздріб"
}
UTM і зшивання з рекламою
Наскрізна аналітика тримається на одному: мітка, з якою клієнт прийшов, має дожити до запису в CRM.
- Записуйте UTM першого візиту в cookie / localStorage і підставляйте у приховані поля форми та в тіло дзвінка.
- Не перезаписуйте мітку на кожному візиті — інакше весь дохід дістанеться ретаргетингу й прямим заходам.
- Значення передавайте у нижньому регістрі, без зайвих пробілів.
- Кампанію не змінюйте заднім числом: перейменована кампанія розривається на два рядки в звіті.
- Якщо мітки немає — передавайте порожній рядок, а не
nullчи"(not set)".
Валюта. Усі суми в одній базовій валюті проєкту. Якщо у вас мультивалютність — конвертуйте на боці CRM за курсом дати угоди.
Варіант: Google-таблиця
Якщо писати ендпоїнти нема кому, підійде таблиця: аркуш deals і аркуш
leads, перший рядок — заголовки з таблиць вище, далі рядки даних.
- Дати — текстом у форматі
YYYY-MM-DD, щоб локаль не переставляла місяць і день. - Суми — числом, без пробілів і символу валюти.
- Доступ — «перегляд за посиланням» або сервісний акаунт, який ми надамо.
- Наповнення таблиці можна автоматизувати сценарієм CRM або Zapier / Make.
Обмеження цього способу — глибина: таблиця зазвичай містить менше полів, тому частина розрізів (менеджери, етапи) буде недоступна.
Вимоги до якості даних
- Історія. Бажано віддавати щонайменше 13 місяців назад — модель «План / факт» використовує річну ретроспективу.
- Стабільність ID. Ідентифікатор угоди не має змінюватися між вивантаженнями.
- Оновлення заднім числом. Якщо угода змінила статус пізніше — вона має з'явитися у відповіді за той період, куди потрапляє її нова дата закриття.
- Дублі. Один
ID— один рядок у відповіді. - Тестові угоди й внутрішні замовлення краще фільтрувати на боці CRM.
ТЗ: чек-лист для розробника
Мінімальний обсяг робіт, який можна віддати в задачу як є:
- Реалізувати
GET /feed/dealsз параметрамиdate_from,date_to,token; повертає JSON-масив угод за датою закриття з полями з розділу «Фід продажів». - Реалізувати
GET /feed/leadsза тим самим принципом з полями розділу «Фід лідів». - Забезпечити збереження UTM першого візиту в картці клієнта / угоди.
- Додати перевірку токена та обмеження за IP або rate-limit.
- Перевірити відповідь на вікні в 1 місяць: час < 60 с, коректний UTF-8,
дати у
YYYY-MM-DD. - Прогнати контрольну звірку: сума
OPPORTUNITYпоSTAGE_SEMANTIC_ID = Sза минулий місяць має збігатися зі звітом CRM. - Передати нам URL обох фідів і секрет захищеним каналом.
Орієнтовний обсяг: 4–8 годин для типової CRM з готовою моделлю угод.
Часті питання
Чи можна віддавати не JSON, а CSV?
Можна, але JSON надійніший: у CSV регулярно ламаються коми в назвах і локаль дат.
Якщо все ж CSV — роздільник ,, лапки подвійні, кодування UTF-8 з BOM.
Як бути з персональними даними?
Не передавайте їх. Імена, телефони й пошту система не використовує — достатньо
знеособлених CONTACT_ID / Client.Id.
Чи потрібен webhook «на подію»?
Ні. Ми опитуємо фід за розкладом — це простіше і стійкіше до збоїв, ніж push, який доведеться повторювати при помилці.
Що робити зі скасованими угодами?
Віддавайте їх зі статусом F. Видаляти рядок не треба — інакше історія
за минулі періоди мовчки зміниться.
Питання по інтеграції — Telegram.