n8n trigger
The Cosend Trigger node — ten events, server-side filtering, signature verification, and the two events no cloud-API-only provider can emit.
The Cosend Trigger starts a workflow when something happens on your number. It registers its own webhook endpoint when you activate the workflow and removes it when you deactivate — there is nothing to configure in the dashboard.
Events
Ten, and the trigger filters server-side: it subscribes only to what you select, so an unselected event never reaches your instance at all.
| Event | Fires when |
|---|---|
message.received | An inbound message — text, media, a reaction or a reply |
message.status | sent · delivered · read · failed |
message.echo | The owner answered from the WhatsApp Business app |
conversation.created | A new thread opened |
conversation.updated | State, assignee, control or labels changed |
conversation.window_expiring | The 24-hour service window closes in one hour |
contact.consent_changed | An opt-in or an opt-out was recorded |
automation.run_finished | A run reached a terminal state. automation.run_failed alongside it |
connection.disconnected | The connection broke. connection.needs_reauth alongside it |
usage.threshold_reached | 80% or 100% of a meter |
The two in bold
message.echo only exists on a coexistence number, because it is the event that says a human
picked up the phone and answered. No cloud-API-only provider can emit it — there is no phone in
their architecture to emit it about. In a workflow it is what lets a follow-up cancel itself when
a person has already replied.
conversation.window_expiring turns the single most common WhatsApp integration bug — sending
into a window that closed — into an event you can branch on an hour before it matters.
Filters and options
Filters narrow the subscription further, and they also run server-side:
- Message types — text, image, video, audio, document, location, contacts, sticker, reaction, interactive reply.
- Statuses, for
message.status. - Labels and assigned agent.
- Automation, for
automation.run_finished. - Ignore messages sent by me, on by default — otherwise your own sends re-trigger the workflow that made them.
Two options change the shape of what arrives:
- Simplify, on by default: the flattened event object rather than the raw envelope.
- Include contact, on by default: the contact expanded server-side, so you do not need a second node to look up who sent it.
Signatures
Every delivery carries a Cosend-Signature header:
Cosend-Signature: t=1756108800,v1=5257a869e7ecebeda32affa62cdca3fa…
The node verifies it before doing anything else: HMAC-SHA256 over the raw body with the secret
stored when the endpoint was registered, compared in constant time, with deliveries older than
five minutes rejected so a captured request cannot be replayed. A failed verification returns
401 and produces no workflow data — a workflow never runs on an unverified payload.
The scheme is deliberately the one Stripe uses, so the verification snippet already exists in every language.
Testing it
POST to the webhook endpoint’s test route sends a ping event. The node answers 200 and
produces no workflow data, so you can confirm the endpoint is reachable and signing correctly
without firing the workflow.
If the endpoint has gone missing on our side — deleted in the dashboard, say — the node notices at activation and recreates it. If it exists but its URL or its event set no longer matches the workflow, it is replaced rather than left pointing somewhere stale.
Errors
A failed registration surfaces as a node error carrying the API’s code and request_id rather
than a generic message. The error reference has every code, and
the credential page covers the two that are almost always the cause:
a key that is not for this organization, or a key with too narrow a scope.