Kommo + Trello: Automatic Task Creation from Won Deals Without Zapier

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 /webhooks with idModel = board_id
  • HEAD method on webhook endpoint — mandatory, Trello verifies upon registration
  • Store trello_card_id in a custom Kommo field for reverse lookup
  • Key events: updateCard (listAfter) and commentCard

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.

More articles

All →