Skip to main content
When a lead reaches a stage you care about, have n8n do something: post to Slack, write a row in Sheets, open a task in Jira, message the customer back through us. We push to n8n. You don’t poll, and n8n doesn’t need credentials for our API unless the workflow writes back.

What you need first

1

An n8n workflow with a Webhook node

Add a Webhook node, method POST. n8n gives you two URLs — a test URL that only listens while you have the editor open, and a production URL that works once the workflow is active. Start with the test URL.
2

A webhook endpoint in Linkiasoft

Integrations → Webhooks → New endpoint. Paste the n8n URL, and subscribe to lead.stage.changed.
3

The signing secret

Shown once when you create the endpoint. Copy it — n8n needs it to verify that a request really came from us.
n8n’s test URL only accepts one request per “Listen for test event” click. If your second test seems to vanish, that’s why — click listen again.

Pick your fields

A stage-change payload can carry the lead’s name, email, phone, value, owner and more. n8n workflows tend to end up in Slack channels and spreadsheets, so send only what the workflow uses. For a Slack notification, this is usually enough: Untick email and phone unless the workflow needs to contact someone. See choosing which fields to send.

Verify the signature in n8n

Anyone who learns your n8n URL can POST to it. The signature is what makes the difference between “a lead moved” and “someone told me a lead moved”. Add a Code node immediately after the Webhook node:
JSON.stringify(rawBody) only works because n8n has already parsed the JSON and you are re-serialising it. That is fragile — it depends on key order surviving the round trip.For anything you rely on, set the Webhook node’s Raw Body option and hash the raw string instead. See verifying the signature for why this matters.
Put the secret in an n8n environment variable rather than the node body — workflow JSON gets exported, shared and committed.

Act on it

After the Code node, a Switch or IF node on {{ $json.body.data.status }} routes by stage. A Slack node then sends something like:
To message the customer back through WhatsApp, add an HTTP Request node calling POST /v1/conversations/send with an API key scoped to conversations:send. Read the 24-hour rule first — a notification your workflow initiates almost always needs an approved template.

Go to production

Two things change when you switch from the test URL:
  1. Update the endpoint URL in Linkiasoft to n8n’s production URL. They are different paths — reusing the test URL means deliveries stop the moment you close the editor.
  2. Activate the workflow. An inactive workflow returns 404, which we treat as terminal and never retry.

When nothing arrives

Check in this order — the answer is almost always in step 1.
  1. The delivery log, on the endpoint’s page in Linkiasoft. It shows every attempt, the status code, and the exact body we sent. If there’s no row at all, the event never fired — check you subscribed to the right event, and that the stage actually changed.
  2. The status code in that log.
  3. n8n’s own executions list. If we logged a 2xx but nothing happened, the request arrived and the workflow is at fault.
Twenty consecutive failures disables the endpoint and events stop being queued. If you left a broken workflow failing overnight, check whether the endpoint is still enabled before debugging anything else.

Two things that bite

Both lead.updated and lead.stage.changed fire on a stage move. Subscribe to one. If you take both, every move runs your workflow twice. Deliveries are at least once. A timeout after your workflow already ran means we retry and it runs again. If it posts to Slack, you get two messages; if it charges something, you have a real problem. Deduplicate on {{ $json.body.id }}, which is stable across every attempt at the same delivery.