Woodpecker is a specialized B2B cold email outreach platform with automated follow-up sequences. When a prospect replies to an email, that is a signal of interest that should immediately become a deal in Kommo. The Woodpecker REST API and webhook system make it possible to build a two-way integration: replies flow into CRM, and status from CRM goes back to Woodpecker to stop the campaign.
This is an important scenario for outbound teams: without integration the manager manually checks Woodpecker, copies data into Kommo, and forgets to stop the campaign - so the prospect receives three more follow-ups after they have already replied and booked a demo.
Why the native Woodpecker + Kommo integration does not solve the problem
Woodpecker offers native integrations with Pipedrive, HubSpot, and several other CRMs. Kommo is not on that list. Technically Woodpecker can be connected to Kommo through Zapier - “when a prospect replies, create a contact in Kommo.” But this approach breaks down in practice:
One-directional flow. Zapier creates a contact on a reply but cannot stop the Woodpecker campaign when the Kommo deal moves to “Meeting Scheduled” or “Qualified.” The result: the prospect keeps receiving emails after they have already become an active lead.
No deduplication. If the prospect already exists in Kommo (for example, added manually earlier), Zapier creates a duplicate instead of updating the existing contact.
Loss of campaign context. Kommo does not receive information about which campaign the prospect was reading, which email resonated, or how many follow-ups preceded the reply. The manager starts the conversation blind.
A custom integration via Woodpecker API v1 solves all three problems.
Integration architecture
Woodpecker API works via REST; authentication uses an API key in the x-api-key header. Webhooks support the events: REPLIED, BOUNCED, OPTED_OUT, INTERESTED, CALL_SCHEDULED.
Flow: Woodpecker -> Kommo:
- Prospect replies to an email - Woodpecker sends a
REPLIEDwebhook. - The service searches for the contact in Kommo by email. If not found - creates one.
- Creates or updates a deal with the “Woodpecker” tag and campaign data.
- Adds a note: reply text, campaign name, sequence step.
Flow: Kommo -> Woodpecker:
- Manager moves the deal to “Qualified” or “Meeting Scheduled.”
- The Kommo webhook notifies the service of the stage change.
- The service finds the prospect in Woodpecker by email and marks them as
REPLIEDor stops the campaign.
import requests
import hashlib
import json
from typing import Optional
WOODPECKER_BASE = "https://api.woodpecker.co/rest/v1"
def get_woodpecker_prospect(api_key: str, email: str) -> Optional[dict]:
"""Search for a prospect in Woodpecker by email."""
headers = {"x-api-key": api_key}
resp = requests.get(
f"{WOODPECKER_BASE}/prospect_list",
headers=headers,
params={"email": email}
)
if resp.status_code == 404:
return None
resp.raise_for_status()
data = resp.json()
return data[0] if data else None
def update_prospect_status(api_key: str, prospect_id: int, status: str):
"""
Update a prospect's status in Woodpecker.
status: ACTIVE | PAUSED | REPLIED | BOUNCED | OPTED_OUT | NOT_CONTACTED
"""
headers = {"x-api-key": api_key, "Content-Type": "application/json"}
resp = requests.put(
f"{WOODPECKER_BASE}/prospect/{prospect_id}",
headers=headers,
json={"status": status}
)
resp.raise_for_status()
def handle_woodpecker_webhook(payload: dict, kommo_client, api_key: str):
"""
Handle the REPLIED event from Woodpecker.
"""
event = payload.get("event")
if event != "REPLIED":
return # Only process replies
prospect = payload["prospect"]
campaign = payload["campaign"]
email_addr = prospect["email"]
first_name = prospect.get("first_name", "")
last_name = prospect.get("last_name", "")
company = prospect.get("company", "")
reply_text = payload.get("reply_message", "")
# Find or create contact in Kommo
contact = kommo_client.search_contact_by_email(email_addr)
if not contact:
contact = kommo_client.create_contact(
name=f"{first_name} {last_name}".strip(),
email=email_addr,
company=company,
)
# Find active deal or create a new one
lead = kommo_client.get_active_lead_for_contact(contact["id"])
if not lead:
lead = kommo_client.create_lead(
contact_id=contact["id"],
name=f"{company} - Woodpecker",
tags=["woodpecker", "cold-outreach"],
custom_fields={
"campaign_name": campaign["name"],
"reply_step": str(payload.get("step", 1)),
}
)
# Add a note with the reply text
note = (
f"Cold email reply (Woodpecker)\n"
f"Campaign: {campaign['name']}\n"
f"Sequence step: {payload.get('step', '?')}\n\n"
f"Reply text:\n{reply_text}"
)
kommo_client.add_note(lead["id"], note)
return lead
Step-by-step implementation
Step 1 - Woodpecker API Key. In Woodpecker settings: Settings -> Integrations -> API. Generate the key. It is passed in the x-api-key header of every request.
Step 2 - configure Woodpecker webhooks. Settings -> Webhooks. Add your microservice URL. Select events: REPLIED, INTERESTED, OPTED_OUT. Woodpecker supports HMAC-SHA256 signing for verification.
Step 3 - Kommo webhook on stage change. Create a webhook for deal status change events. When a deal transitions to “Qualified” or “Won” - the service updates the prospect’s status in Woodpecker.
Step 4 - custom fields in Kommo. Create custom deal fields: “Woodpecker Campaign,” “Reply Step,” “Woodpecker Prospect ID.” These are needed for reverse synchronization.
Step 5 - deduplication logic. Before creating a contact, always check by email. Before creating a deal, check whether there is already an active deal for that contact. This prevents duplicates when a prospect replies to a different campaign.
Step 6 - stop the campaign. When a deal moves to “Won” or “Lost” - change the prospect’s status in Woodpecker to REPLIED (this stops sending). Do not delete the prospect from Woodpecker - the data is needed for campaign analytics.
Real case: B2B SaaS, US market outreach
SaaS company from Eastern Europe selling into the US. Outbound team of 3 SDRs, about 200 prospects in active Woodpecker campaigns. CRM is Kommo.
Problem: SDRs manually checked Woodpecker every day, copied data from replies into Kommo. Campaigns were regularly forgotten to stop. One prospect received 4 follow-up emails after already scheduling a demo - they left.
After integration: a Woodpecker reply appears in Kommo within 15 seconds. The SDR sees a notification in Kommo and can respond immediately. When the deal moves to “Demo Scheduled” the campaign stops automatically.
Result over 3 months: time to process outreach leads dropped from 2 hours/day to 15 minutes. No qualified lead received unwanted follow-ups. Reply-to-meeting conversion improved 18% - managers started responding faster.
Who this is for
The Kommo + Woodpecker integration is needed by teams where:
- Outbound is an active channel with 500+ emails per week
- SDR team works in Woodpecker while account executives work in Kommo
- Full contact-history tracking in CRM is required
- “Zombie prospects” are a problem - leads already in the pipeline who keep receiving cold emails
For inbound leads from forms and ads the task is different - those need integrations with forms or ad platforms. Woodpecker’s outbound specifics require their own logic.
Frequently asked questions
Woodpecker supports more than email - it has LinkedIn steps too. Do those sync as well?
Woodpecker supports LinkedIn steps in sequences, but they are executed manually (by the operator). The webhook MANUAL_TASK_COMPLETED fires when a manual step is completed. The integration can receive this event and add a note in Kommo: “LinkedIn step completed for campaign X.”
How do you pass UTM parameters or personalization data from Woodpecker to Kommo?
Woodpecker stores custom fields for each prospect. In the webhook they are passed in the prospect.custom_fields object. You can map these to custom deal fields in Kommo. For example, company_size from Woodpecker -> “Company size” field in Kommo.
What happens if the prospect replies negatively (“not interested”)?
Woodpecker does not automatically determine reply sentiment (without AI analysis). The REPLIED webhook fires on any reply. The integration creates a deal tagged “Needs qualification” - the manager reads the reply and decides: close or develop. If Woodpecker is configured with the OPTED_OUT category, such a prospect triggers a separate webhook, and the deal can be immediately marked as closed.
Can a Woodpecker campaign be launched from Kommo?
Yes. The Woodpecker API allows adding a prospect to a campaign via POST /prospect. You can configure: when the tag “For outreach” is added in Kommo - the service adds the contact to the appropriate Woodpecker campaign. Full two-way connectivity.
Does the integration affect Woodpecker email deliverability?
No. The integration works via API and does not touch the email sending mechanism. Woodpecker uses its own SMTP or a connected Gmail/Outlook account - this is entirely independent of the API integration with Kommo.
Next step
If you use Woodpecker for outbound and Kommo for deal management - describe your requirements to the Exceltic.dev team. We will review your lead handoff process and propose an integration architecture. A standard project takes 1-2 weeks.