Trello is the simplest kanban for operational teams. Without a Kommo integration, sales closes a deal and writes in the general chat “new client, handle onboarding” — the Trello card is created manually, data is copied, nothing is connected. With the integration, Won in Kommo instantly creates a Trello card with full client data in the right list, and when the team completes onboarding — this is reflected in the deal card.
Why the Native Integration via Zapier Is Not Enough
The Zapier Kommo -> Trello connection works, but has limitations:
— 5–15 minute delay (polling interval of the free plan)
— Cannot pass data from custom Kommo fields without a paid Zapier plan ($49+/month)
— Cannot create checklists and labels programmatically
— Reverse sync (Trello -> Kommo) requires a separate Zap
A custom integration eliminates these limitations: the card is created in seconds, includes all required fields and a checklist, and Trello events instantly appear in the deal history.
Similar to Kommo + Jira integration for dev teams — Trello handles the same task for operational teams without Jira.
What Gets Synchronized
Kommo -> Trello:
— Won -> create a card in the “New Clients” list with name, email, plan, amount
— Won -> add an onboarding checklist to the card
— Won -> assign the card to the responsible person (via Kommo manager -> Trello member mapping)
Trello -> Kommo:
— Card moved to “Done” -> Note: “Trello: onboarding completed”
— Comment added to the card -> Note in the deal
— Card archived -> Note: “Trello: card closed”
Architecture
Kommo Webhook: deal moved to Won
↓ Backend
1. GET /api/v4/leads/{id} + contacts
-> email, name, plan, amount, responsible manager
2. Trello API: POST /cards
-> idList = "New Clients" list on the onboarding board
-> name = "{client_name} - {plan}"
-> desc = "Email: {email}\nAmount: {amount}\nKommo: {deal_link}"
3. Trello API: POST /cards/{card_id}/checklists
-> onboarding checklist template
4. Trello API: POST /cards/{card_id}/members
-> idMember = Trello member by manager mapping
5. Kommo: PATCH /leads/{id}
-> custom field trello_card_id = card_id
6. Kommo: POST /leads/{id}/notes
-> "Trello: card created - onboarding started"
Trello Webhook: updateCard (listAfter = Done)
↓ Backend
1. Find deal by trello_card_id
2. Kommo: POST /leads/{deal_id}/notes
-> "Trello: onboarding completed (card moved to Done)"
Trello API: Key Requests
Base URL: https://api.trello.com/1/.
Authentication: query params key and token.
Get key: Trello -> Developer Settings -> Power-Ups.
Get token: https://trello.com/1/authorize?expiration=never&scope=read,write&response_type=token&key={api_key}.
Create a card:
import requests
TRELLO_API_KEY = "your_api_key"
TRELLO_TOKEN = "your_token"
TRELLO_LIST_ID = "id_of_new_clients_list"
BASE_URL = "https://api.trello.com/1"
def trello_params(**kwargs) -> dict:
return {"key": TRELLO_API_KEY, "token": TRELLO_TOKEN, **kwargs}
def create_trello_card(name: str, description: str, list_id: str, label_ids: list = None) -> dict:
params = trello_params(
name=name,
desc=description,
idList=list_id,
)
if label_ids:
params["idLabels"] = ",".join(label_ids)
resp = requests.post(f"{BASE_URL}/cards", params=params)
resp.raise_for_status()
return resp.json()
def add_checklist(card_id: str, checklist_name: str, items: list) -> dict:
resp = requests.post(
f"{BASE_URL}/cards/{card_id}/checklists",
params=trello_params(name=checklist_name)
)
resp.raise_for_status()
checklist_id = resp.json()["id"]
for item in items:
requests.post(
f"{BASE_URL}/checklists/{checklist_id}/checkItems",
params=trello_params(name=item)
)
return resp.json()
def assign_member(card_id: str, member_id: str) -> None:
requests.post(
f"{BASE_URL}/cards/{card_id}/idMembers",
params=trello_params(value=member_id)
)
ONBOARDING_CHECKLIST = [
"Send welcome email",
"Conduct introductory call",
"Set up access",
"Run team training",
"Receive launch confirmation",
]
MANAGER_TO_TRELLO = {
"alice@company.com": "trello_member_id_alice",
"bob@company.com": "trello_member_id_bob",
}
def on_deal_won(lead: dict, contact: dict):
name = contact["name"]
email = get_contact_email(contact)
plan = get_custom_field(lead, PLAN_FIELD_ID) or "Starter"
amount = lead.get("price", 0)
manager_email = get_manager_email(lead)
deal_link = f"https://your-domain.kommo.com/leads/detail/{lead['id']}"
desc = (
f"**Email:** {email}\n"
f"**Plan:** {plan}\n"
f"**Amount:** ${amount}\n"
f"**Kommo:** {deal_link}"
)
card = create_trello_card(
name=f"{name} - {plan}",
description=desc,
list_id=TRELLO_LIST_ID
)
card_id = card["id"]
add_checklist(card_id, "Onboarding", ONBOARDING_CHECKLIST)
trello_member = MANAGER_TO_TRELLO.get(manager_email)
if trello_member:
assign_member(card_id, trello_member)
update_kommo_deal(lead["id"], {"trello_card_id": card_id})
create_kommo_note(lead["id"],
f"Trello: card created for {name}, list 'New Clients'")
Registering the Trello Webhook:
def register_trello_webhook(callback_url: str, model_id: str) -> dict:
# model_id = board id or specific card id
resp = requests.post(
f"{BASE_URL}/webhooks",
params=trello_params(
callbackURL=callback_url,
idModel=model_id,
description="Kommo integration"
)
)
resp.raise_for_status()
return resp.json()
Handling the Trello Webhook:
from flask import Flask, request
app = Flask(__name__)
@app.route("/webhooks/trello", methods=["HEAD", "POST"])
def trello_webhook():
if request.method == "HEAD":
return "", 200 # Trello verifies the endpoint via HEAD
payload = request.json
action_type = payload.get("action", {}).get("type")
action_data = payload.get("action", {}).get("data", {})
if action_type == "updateCard":
card_id = action_data.get("card", {}).get("id")
list_after = action_data.get("listAfter", {}).get("name", "")
deal_id = find_deal_by_field("trello_card_id", card_id)
if not deal_id:
return "", 200
if list_after.lower() in ["done", "completed"]:
create_kommo_note(deal_id,
"Trello: onboarding completed - card moved to Done")
elif action_type == "commentCard":
card_id = action_data.get("card", {}).get("id")
comment_text = action_data.get("text", "")
author = payload.get("action", {}).get("memberCreator", {}).get("fullName", "")
deal_id = find_deal_by_field("trello_card_id", card_id)
if deal_id:
create_kommo_note(deal_id,
f"Trello (comment by {author}): {comment_text}")
return "", 200
Trello Webhook has no verification — protection is via a secret URL. Trello validates the endpoint via a HEAD request upon registration — it is important to handle both methods.
Real-World Case
SaaS (EU, 40–50 new clients per month, sales in Kommo, onboarding via Trello):
- Before: the sales manager wrote in Slack “new Won, handle onboarding.” Customer Success searched for data in Kommo, created a Trello card manually. Sometimes lost it. Onboarding delay — 4–24 hours.
- After: Won -> Trello card with checklist in 3 seconds. CS sees the new client without waiting. First contact — within the hour.
- Additionally: when moved to Done — Note in Kommo, the sales manager sees that CS completed onboarding without a call.
Who This Is Relevant For
- Teams where sales are in Kommo and operational work is in Trello
- Onboarding, delivery, support — all in Trello, a CRM connection is needed
- 20–100 new clients per month — at higher volumes, Jira or ClickUp is preferable
- Small and medium teams without Jira — Trello is simpler and cheaper for operations
Frequently Asked Questions
Trello vs ClickUp for Kommo integration?
Kommo + ClickUp integration offers a more flexible structure (subtasks, dependencies, time tracking). Trello is simpler to set up and maintain. If the team is already in Trello and processes are working — there is no reason to migrate just for the integration.
How to get the ID of a specific list in Trello?
GET /boards/{board_id}/lists?key={key}&token={token} — returns all lists with IDs and names. Board ID is visible in the board URL: trello.com/b/{board_id}/board-name. Save the required list ID in your config.
Trello Webhook: how to confirm it is working?
Upon registration, Trello sends a HEAD request to your URL. If the URL does not respond with 200 — the webhook is not created. To check active webhooks: GET /webhooks?key={key}&token={token}. A webhook is automatically deleted if the endpoint responds with 410 three times in a row.
How to add labels to a card?
First get the label IDs for the board: GET /boards/{board_id}/labels. Then pass them in idLabels when creating the card. A useful mapping: Kommo plan -> Trello label color (green = Starter, yellow = Growth, red = Scale).
Summary
- Trello API: key + token as query params,
https://api.trello.com/1/ - Create card:
POST /cards, checklist:POST /cards/{id}/checklists - Webhook registration:
POST /webhookswith idModel = board_id - HEAD method on webhook endpoint — mandatory, Trello verifies upon registration
- Store
trello_card_idin a custom Kommo field for reverse lookup - Key events:
updateCard(listAfter) andcommentCard
If you want to connect Kommo deals with Trello onboarding — describe your board structure and pipeline stages. Exceltic.dev will configure the mapping and webhook handler.