Kommo + Kit (ConvertKit): email automation from the sales pipeline
Kit (known as ConvertKit before 2024) is an email automation platform with powerful tag-based segmentation and a visual sequence builder. Without a Kommo integration, a marketer manually adds a new customer to Kit after Won, the sales manager has no visibility into which email campaigns the customer is enrolled in, and an unsubscribe event is not reflected in the CRM. With the integration, a pipeline stage change in Kommo automatically triggers the correct Kit sequence with the right tags, and every significant email event appears in the deal card.
Kit vs Customer.io: when to choose which
Kit is aimed at the creator economy and content businesses — courses, SaaS with educational onboarding, community products. Key strengths: visual automations, tags as the primary segmentation mechanism, integrations with Teachable/Kajabi/Gumroad.
Customer.io is behavioral marketing for product-led SaaS: product events -> campaigns. API-first approach, complex conditions based on user properties.
For Kommo integration, both are implemented in a similar way. Customer.io integration is chosen when event-driven sending based on in-product actions is needed. Kit is the right choice when onboarding is built around email sequences with tag logic.
What is synchronized
Kommo -> Kit:
— Won -> create or update a subscriber in Kit (upsert by email)
— Won -> add tags customer, plan:{plan_name}, source:{channel}
— Won -> add to onboarding sequence
— Stage change -> update tags (remove trial, add active)
Kit -> Kommo:
— subscriber.unsubscribed -> Note + task for the manager: “Customer unsubscribed from Kit”
— subscriber.bounced -> Note + task to verify email
— Sequence completed -> Note: “Onboarding campaign completed”
Architecture
Kommo Webhook: deal moved to Won
↓ Backend
1. GET /api/v4/leads/{id} + contacts
-> email, name, plan, source from custom fields
2. Kit API v4: POST /subscribers (upsert)
-> email, first_name, custom fields (plan, kommo_deal_id)
3. Kit API v4: POST /tags/{tag_id}/subscribers
-> add tags: customer, plan:{plan}, source:{source}
4. Kit API v4: POST /sequences/{seq_id}/subscribers
-> add to onboarding sequence
5. Kommo: POST /leads/{id}/notes
-> "Kit: subscriber added, tags: customer, plan:growth"
Kit Webhook: subscriber.unsubscribed
↓ Backend
1. From payload: subscriber.email
2. Find deal by contact email in Kommo
3. Kommo: POST /leads/{deal_id}/notes
-> "Kit: customer unsubscribed from mailing list"
4. Kommo: POST /tasks
-> "Clarify communication preferences - customer unsubscribed from Kit"
Kit API v4: key requests
Base URL: https://api.kit.com/v4/.
Authentication: Bearer token — Authorization: Bearer {api_key}.
API key: Kit -> Settings -> Developer -> API keys.
Create or update a subscriber:
import requests
KIT_API_KEY = "your_kit_api_key"
KIT_BASE_URL = "https://api.kit.com/v4"
headers = {
"Authorization": f"Bearer {KIT_API_KEY}",
"Content-Type": "application/json"
}
def upsert_subscriber(email: str, first_name: str, custom_fields: dict) -> dict:
# Kit v4 upsert: if a subscriber with this email exists - updates; if not - creates
resp = requests.post(
f"{KIT_BASE_URL}/subscribers",
headers=headers,
json={
"email_address": email,
"first_name": first_name,
"fields": custom_fields,
"state": "active"
}
)
resp.raise_for_status()
return resp.json()
def add_tag_to_subscriber(subscriber_id: str, tag_id: str) -> None:
resp = requests.post(
f"{KIT_BASE_URL}/tags/{tag_id}/subscribers",
headers=headers,
json={"subscriber_id": subscriber_id}
)
resp.raise_for_status()
def add_to_sequence(subscriber_id: str, sequence_id: str) -> None:
resp = requests.post(
f"{KIT_BASE_URL}/sequences/{sequence_id}/subscribers",
headers=headers,
json={"subscriber_id": subscriber_id}
)
resp.raise_for_status()
def on_deal_won(lead: dict, contact: dict):
email = get_contact_email(contact)
first_name = contact["name"].split()[0]
plan = get_custom_field(lead, PLAN_FIELD_ID) or "starter"
source = get_custom_field(lead, SOURCE_FIELD_ID) or "unknown"
subscriber = upsert_subscriber(email, first_name, {
"plan": plan,
"kommo_deal_id": str(lead["id"]),
"source": source
})
subscriber_id = subscriber["subscriber"]["id"]
# Tags from a dict: tag name -> tag_id (retrieve from Kit API in advance)
tags_to_add = [TAG_IDS["customer"], TAG_IDS.get(f"plan_{plan}")]
for tag_id in tags_to_add:
if tag_id:
add_tag_to_subscriber(subscriber_id, tag_id)
# Add to onboarding sequence
add_to_sequence(subscriber_id, ONBOARDING_SEQUENCE_ID)
create_kommo_note(
lead["id"],
f"Kit: subscriber added (tags: customer, plan:{plan}), "
f"onboarding sequence started"
)
Retrieve tag and sequence IDs:
def get_tags() -> dict:
resp = requests.get(f"{KIT_BASE_URL}/tags", headers=headers)
resp.raise_for_status()
tags = resp.json().get("tags", [])
return {tag["name"]: tag["id"] for tag in tags}
def get_sequences() -> dict:
resp = requests.get(f"{KIT_BASE_URL}/sequences", headers=headers)
resp.raise_for_status()
seqs = resp.json().get("sequences", [])
return {seq["name"]: seq["id"] for seq in seqs}
Handling Kit Webhooks:
from flask import Flask, request
app = Flask(__name__)
@app.route("/webhooks/kit", methods=["POST"])
def kit_webhook():
# Kit webhook has no built-in HMAC verification in v4
# Protection: secret path + IP whitelist
payload = request.json
event = payload.get("type")
subscriber = payload.get("subscriber", {})
email = subscriber.get("email_address")
if not email:
return "", 200
deal_id = find_kommo_deal_by_contact_email(email)
if not deal_id:
return "", 200
if event == "subscriber.unsubscribed":
create_kommo_note(deal_id, "Kit: customer unsubscribed from email list")
create_kommo_task(deal_id,
"Clarify communication preferences - customer unsubscribed from Kit")
elif event == "subscriber.bounced":
create_kommo_note(deal_id, "Kit: email not delivered (bounce)")
create_kommo_task(deal_id, "Verify and update customer email - Kit recorded a bounce")
return "", 200
Kit Webhook setup: Settings -> Developer -> Webhooks -> Add endpoint. In Kit v4, verification is via secret path + IP whitelist (Kit publishes the list of IP addresses).
Tag segmentation strategy: mapping
Tags in Kit are the primary segmentation mechanism. A well-thought-out mapping from Kommo:
| Event in Kommo | Tag in Kit |
|---|---|
| Won (any plan) | customer |
| Won, Growth plan | plan_growth |
| Won, Scale plan | plan_scale |
| Source = LinkedIn | source_linkedin |
| Churn (customer lost) | churned |
| Upgrade | upgraded, remove plan_growth, add plan_scale |
Tags are atomic: added/removed via separate API calls. They merge rather than overwrite. This allows building Kit automations with logic such as “has tag X AND tag Y -> campaign Z”.
Real-world case
Creator-SaaS (US, educational platform, Kommo + Kit, 60–80 new customers per month):
- Before: a marketer exported the Won list from Kommo once a day and imported it into Kit. The first email was delayed by 24–48 hours. Tags were applied manually — errors were common.
- After: Won -> Kit subscriber + tags + onboarding sequence within 5 seconds. First welcome email — within an hour of closing the deal.
- Additionally:
subscriber.bounced-> task to update email -> saved 8% of contacts with incorrect emails in the first month.
Who this is relevant for
- SaaS and course businesses with email onboarding through Kit
- Teams where the marketer works in Kit and sales in Kommo — two separate systems without a connection
- 30+ new customers per month — manual sync creates delays and errors
- Products with multiple plans — tag segmentation for each plan
Frequently asked questions
Kit or Mailchimp for Kommo integration?
Mailchimp integration works through audiences and tags. Kit works exclusively through tags — more flexible segmentation for complex onboarding scenarios. Mailchimp is better for mass campaigns to base segments. Kit is better for sequences triggered by events.
How do I find tag and sequence IDs in Kit?
GET /v4/tags — list of tags with IDs. GET /v4/sequences — list of sequences. We recommend saving the name -> id mapping to config during initial setup — IDs are stable and do not change.
Kit v3 vs v4 API?
Kit v4 (current): https://api.kit.com/v4/, Bearer token. Kit v3 (legacy): https://api.convertkit.com/v3/, api_key as a query param. New integrations should only use v4 — v3 is supported but not being developed further.
How do I remove tags when a stage changes in Kommo?
DELETE /v4/tags/{tag_id}/subscribers/{subscriber_id} — removes a specific tag from a subscriber. For a plan change: delete plan_growth, add plan_scale. Implemented via a PATCH /api/v4/leads webhook triggered when the “Plan” custom field changes.
Summary
- Kit API v4: Bearer token,
https://api.kit.com/v4/ - Upsert subscriber:
POST /subscribers(by email) - Add tag:
POST /tags/{tag_id}/subscribers - Add to sequence:
POST /sequences/{sequence_id}/subscribers - Webhook:
subscriber.unsubscribed,subscriber.bounced— no HMAC, protection via secret URL - Tag strategy: map plan/source/status -> Kit tags for correct segmentation
If you use Kit and Kommo and want to automate onboarding by pipeline stage — describe your plan structure and sequences. Exceltic.dev will configure the mapping and webhook handler.