Kommo + Iterable: cross-channel маркетинг из воронки продаж без ручной сегментации
Iterable — enterprise cross-channel маркетинговая платформа: email, SMS, push-уведомления, in-app сообщения и web push из единого рабочего пространства. В отличие от ActiveCampaign или Customer.io, Iterable ориентирован на компании с высоким объёмом и сложными cross-channel journey — B2C и B2B с mobile app, несколькими языками и продвинутой сегментацией. Без интеграции с Kommo: статус сделки в CRM и сегмент в Iterable живут независимо — маркетинг не знает когда клиент закрылся как Won, а CRM не знает что клиент отписался.
Iterable vs Customer.io vs ActiveCampaign
| Параметр | Iterable | Customer.io | ActiveCampaign |
|---|---|---|---|
| Каналы | Email, SMS, Push, In-App, Web Push | Email, SMS, Push, In-App | Email, SMS |
| Целевой сегмент | Enterprise B2C/B2B | Mid-market B2B SaaS | SMB |
| Workflow сложность | Высокая (drag-drop + code) | Средняя | Средняя |
| Mobile push | Нативно | Да | Нет |
| Цена | Enterprise (от $500+/мес) | От $100/мес | От $29/мес |
| Лучше для | 100k+ пользователей, mobile app | SaaS onboarding, behavioral | Email automation SMB |
Iterable выбирают компании с мобильным приложением, multi-channel customer journey и потребностью управлять lifecycle от первого касания до retention в единой системе.
Что синхронизируется
Kommo -> Iterable:
— Won -> updateUser (профиль пользователя) + startWorkflow (onboarding sequence)
— Смена этапа воронки -> trackEvent (CRM stage change event для Iterable Journey)
— Потеря сделки (Lost) -> trackEvent "deal_lost" -> остановить nurture-workflows
Iterable -> Kommo:
— unsubscribeEvent -> Note в сделку: «Клиент отписался от рассылки»
— emailBounce -> Note: «Email bounced — проверить адрес»
— Workflow-reached milestone -> Note: «Iterable: клиент завершил onboarding sequence»
Iterable API: обновление пользователя и запуск workflow
Base URL: https://api.iterable.com/api. Аутентификация: заголовок Api-Key: {api_key} (из Iterable -> Integrations -> API Keys).
import requests
ITERABLE_API_KEY = "your_api_key"
ITERABLE_BASE = "https://api.iterable.com/api"
ITERABLE_HEADERS = {
"Api-Key": ITERABLE_API_KEY,
"Content-Type": "application/json",
}
def update_iterable_user(email: str, data_fields: dict) -> dict:
# updateUser upserts по email - создаёт если нет, обновляет если есть
payload = {
"email": email,
"dataFields": data_fields,
}
resp = requests.post(
f"{ITERABLE_BASE}/users/update",
headers=ITERABLE_HEADERS,
json=payload,
)
resp.raise_for_status()
return resp.json()
def track_iterable_event(email: str, event_name: str, data_fields: dict = None) -> dict:
# Событие появляется в Iterable Journey для trigger-условий
payload = {
"email": email,
"eventName": event_name,
"dataFields": data_fields or {},
}
resp = requests.post(
f"{ITERABLE_BASE}/events/track",
headers=ITERABLE_HEADERS,
json=payload,
)
resp.raise_for_status()
return resp.json()
def trigger_iterable_workflow(workflow_id: int, email: str,
data_fields: dict = None) -> dict:
# Запустить конкретный Workflow для пользователя
payload = {
"workflowId": workflow_id,
"listId": None,
"subscribers": [
{
"email": email,
"dataFields": data_fields or {},
}
],
}
resp = requests.post(
f"{ITERABLE_BASE}/workflows/triggerWorkflow",
headers=ITERABLE_HEADERS,
json=payload,
)
resp.raise_for_status()
return resp.json()
# ID Iterable Workflows (из Iterable -> Journeys -> ваш workflow -> Settings)
ONBOARDING_WORKFLOW_ID = 12345
NURTURE_WORKFLOW_ID = 12346
Интеграция: Kommo Won -> Iterable
def on_kommo_deal_won(lead: dict, contact: dict):
email = get_contact_email(contact)
name = contact.get("name", "")
company = get_custom_field(lead, COMPANY_FIELD_ID) or ""
plan = get_custom_field(lead, PLAN_FIELD_ID) or "starter"
# Обновить профиль пользователя в Iterable
update_iterable_user(email, {
"firstName": name.split()[0] if name else "",
"lastName": " ".join(name.split()[1:]) if len(name.split()) > 1 else "",
"companyName": company,
"plan": plan,
"crmDealId": str(lead["id"]),
"dealValue": lead.get("price", 0),
"wonAt": lead.get("closed_at", ""),
"isCustomer": True,
})
# Событие won для trigger-условий в Journey
track_iterable_event(email, "deal_won", {
"deal_id": lead["id"],
"plan": plan,
"value": lead.get("price", 0),
})
# Запустить onboarding workflow
trigger_iterable_workflow(
ONBOARDING_WORKFLOW_ID,
email,
data_fields={"plan": plan, "company": company},
)
create_kommo_note(
lead["id"],
f"Iterable: пользователь обновлён, onboarding workflow запущен (план: {plan})",
)
def on_kommo_stage_change(lead: dict, contact: dict, new_stage_id: int):
email = get_contact_email(contact)
stage_name = STAGE_ID_TO_NAME.get(new_stage_id, str(new_stage_id))
track_iterable_event(email, "crm_stage_changed", {
"stage_id": new_stage_id,
"stage_name": stage_name,
"deal_id": lead["id"],
})
def on_kommo_deal_lost(lead: dict, contact: dict):
email = get_contact_email(contact)
update_iterable_user(email, {"isCustomer": False, "churnedAt": ""})
track_iterable_event(email, "deal_lost", {
"deal_id": lead["id"],
"loss_reason": get_custom_field(lead, LOSS_REASON_FIELD_ID) or "",
})
Iterable -> Kommo: обратная синхронизация
Iterable поддерживает webhooks (Integrations -> Webhooks). При критичных событиях — Note в Kommo:
@app.route("/webhooks/iterable", methods=["POST"])
def iterable_webhook():
payload = request.json
event_type = payload.get("eventName") or payload.get("type", "")
email = payload.get("email", "")
lead_id = find_kommo_lead_by_email(email)
if not lead_id:
return "", 200
if event_type in ("emailUnsubscribe", "smsUnsubscribe"):
channel = "email" if "email" in event_type.lower() else "SMS"
create_kommo_note(lead_id,
f"Iterable: клиент отписался от {channel}-рассылки")
elif event_type == "emailBounce":
bounce_type = payload.get("bounceType", "")
create_kommo_note(lead_id,
f"Iterable: email bounced ({bounce_type}) - проверить адрес")
elif event_type == "inAppClick":
button = payload.get("buttonIdentifier", "")
create_kommo_note(lead_id,
f"Iterable: клиент нажал '{button}' в in-app сообщении")
return "", 200
Сегментация без ручной работы
Без интеграции маркетинг регулярно запрашивает у продаж «список Won за месяц» -> импортирует CSV в Iterable -> запускает onboarding. С интеграцией это происходит автоматически: каждый Won -> updateUser с isCustomer: true -> Iterable-сегмент «Customers» обновляется в реальном времени -> кампании по сегменту работают без ручного импорта.
Iterable List API позволяет также создавать динамические сегменты по dataFields:
def subscribe_to_list(email: str, list_id: int) -> dict:
resp = requests.post(
f"{ITERABLE_BASE}/lists/subscribe",
headers=ITERABLE_HEADERS,
json={"listId": list_id, "subscribers": [{"email": email}]},
)
resp.raise_for_status()
return resp.json()
Реальный кейс
B2B SaaS (US, 15,000 пользователей, мобильное приложение, Kommo + Iterable):
- До: Won -> sales op вручную экспортировала CSV раз в неделю -> импортировала в Iterable -> запускала onboarding. Задержка 2–7 дней от закрытия до первого onboarding email.
- После: Won -> Python webhook ->
updateUser+triggerWorkflow-> первый email через 5 минут. Потеря сделки ->deal_lostevent -> Journey останавливает nurture sequence автоматически. - Дополнительно: push-уведомления в мобильном приложении теперь сегментированы по CRM-плану (starter/growth/enterprise). In-app сообщения показываются только клиентам со статусом
isCustomer: trueв Iterable.
Для кого актуально
- B2B/B2C с мобильным приложением и потребностью в cross-channel journey
- SaaS с onboarding email sequence которая должна стартовать в момент Won, а не через неделю
- Компании где маркетинг каждую неделю запрашивает актуальный список клиентов из продаж
- Enterprise с 10k+ контактов в Iterable где ручной импорт уже невозможен
Часто задаваемые вопросы
Iterable vs Customer.io для интеграции с Kommo — что проще?
Архитектура API аналогична: updateUser, trackEvent, triggerWorkflow. Customer.io немного проще для SaaS onboarding — меньше конфигурации. Iterable мощнее для mobile push и cross-channel. Для Kommo-интеграции код отличается только URL и заголовком авторизации. Выбор платформы — вопрос каналов (если нужен push — Iterable), объёма и бюджета.
Как синхронизировать потерянную сделку — остановить workflows?
trackEvent "deal_lost" -> в Iterable Journey добавить Filter условие: прекратить workflow если пользователь получил событие deal_lost. Или использовать updateUser с isActive: false -> Journey filter isActive == true. Главное не оставлять активный onboarding для Lost клиентов — это портит впечатление.
Iterable поддерживает GDPR — как обрабатывать запросы на удаление?
Iterable -> API: DELETE /users/{email} удаляет пользователя и все связанные данные. При получении GDPR-запроса от клиента: Kommo Note -> ответственный -> дёргает Iterable API + GDPR-процесс в Kommo. Iterable также поддерживает Data Subject Request через UI.
Как передать custom fields из Kommo в Iterable?
Любое кастомное поле Kommo -> dataFields объект в updateUser. Iterable создаёт поле автоматически при первой передаче — нет необходимости предварительно регистрировать поля. Типы: string, number, boolean, array (для тегов). Используется в сегментации (Iterable Dynamic Segments) и персонализации шаблонов (Handlebars в Iterable editor).
Итого
- API:
Api-Key: {key}заголовок, base URLhttps://api.iterable.com/api updateUser— upsert по email, все CRM данные передаются вdataFieldstriggerWorkflow— запуск Journey в момент события (Won, stage change)trackEvent— CRM-события как Iterable triggers (stage_changed, deal_lost)- Обратная синхронизация: unsubscribe/bounce webhook -> Kommo Note
- Задержка Won -> первый email: 5 минут вместо недели
Если у вас Kommo + Iterable и маркетинг работает с устаревшими сегментами из еженедельного CSV — опишите структуру Journey и каналы. Exceltic.dev настроит real-time синхронизацию.