> ## Documentation Index
> Fetch the complete documentation index at: /help/llms.txt
> Use this file to discover all available pages before exploring further.

# n8n

> Send contacts from n8n to a Kerux campaign, receive Kerux events in n8n, and let n8n answer a contact that's waiting.

> [!NOTE]
>
> **Pro plan.** n8n works through trigger URLs, webhooks, HTTP steps and listeners (and API keys to read a contact), which are part of Pro and Agency (and the free trial). Anything you already have keeps working on every plan. See [Plans and billing](/help/account/billing.md).

n8n connects to Kerux with its own built-in nodes, no community node needed:

* **HTTP Request** node sends people to a campaign's trigger URL.
* **Webhook** node receives Kerux events (replies, accepted invitations, meetings).
* A **Call & wait** step in Kerux calls your n8n workflow and waits for its answer, so n8n can score, enrich or route a contact mid-campaign.

> [!NOTE]
>
> **How it connects:** Kerux's trigger URLs, webhooks and callback URLs, with n8n's [HTTP Request node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/) and Webhook node.

## 1. Send people from n8n to a campaign

**1. Copy the trigger URL**

In Kerux, open the campaign, click **+ Add** on the **Trigger** half of the start box and choose **Incoming webhook (API)**. Click **Add**, then **Copy link**.

**2. Add an HTTP Request node**

Method **POST**, the URL you copied, **Send Body** on, body content type **JSON**.

**3. Map the fields**

`linkedin_url` is required: Kerux knows people by their LinkedIn profile and never adds the same one twice.

```json theme={null}
POST https://www.usekerux.com/t/YOUR_TRIGGER_TOKEN
{
  "linkedin_url": "https://www.linkedin.com/in/sofia-rossi",
  "first_name": "Sofia",
  "last_name": "Rossi",
  "email": "sofia@brightline.io",
  "company": "Brightline",
  "title": "Head of Growth",
  "custom": { "source": "n8n", "score": "87" }
}
```

Up to 100 people at once: `{ "leads": [ ... ] }`. Kerux answers `202`:

```json theme={null}
{ "data": { "enrolled": 1, "already_in": 0, "lead_ids": ["9b2e..."] } }
```

`custom` values become contact fields you can use in messages, for example `{{contact.custom.score}}`. Turn on **Require a signature** in **Integrations > Developers > Trigger URLs** if you sign requests (Standard Webhooks).

## 2. Receive Kerux events in n8n

**1. Add a Webhook node**

Method **POST**. Copy its **Production URL** (activate the workflow).

**2. Add the endpoint in Kerux**

In **Integrations > Developers**, under **Webhooks**, add that URL and pick the events, for example `reply.positive`, `linkedin.invitation_accepted` and `meeting.booked`. Click **Send test event**.

What arrives (a positive reply, from Kerux's code):

```json theme={null}
{
  "id": "evt_3f1c...",
  "type": "reply.positive",
  "created_at": "2026-11-05T14:02:11.000Z",
  "workspace_id": "...",
  "data": {
    "reply_id": "...",
    "lead_id": "9b2e...",
    "conversation_id": "...",
    "workflow_id": "...",
    "type": "positive",
    "confidence": 0.93,
    "classified_by": "ai",
    "text": "Sounds good, let's talk Thursday.",
    "received_at": "2026-11-05T14:01:58.000Z"
  }
}
```

Events carry the contact's id, not its email. To get the contact's details, add an HTTP Request node: `GET https://www.usekerux.com/api/v1/leads/{{ $json.data.lead_id }}` with the header `Authorization: Bearer YOUR_KERUX_API_KEY` (create the key in **Integrations > Developers**, scope `leads:read`).

Every delivery is signed with Standard Webhooks (`webhook-id`, `webhook-timestamp`, `webhook-signature` headers); check it in a Code node with the endpoint's `whsec_` secret if the workflow does anything important.

## 3. Let n8n answer a waiting contact (Call & wait)

**1. Add a Call & wait step in Kerux**

It POSTs the contact to your n8n Webhook node and waits. Put the contact's callback URL in the body: `"callback_url": "{{wait.callback_url}}"`, with the fields n8n needs.

**2. Answer from n8n**

At the end of the workflow, an HTTP Request node POSTs JSON to the `callback_url` it received, for example `{ "score": 87, "segment": "agency" }`.

**3. Use the answer**

Later steps read `{{steps.<step>.payload.score}}` and `{{steps.<step>.payload.segment}}`. If n8n never answers, the step goes out through **timed out** at the limit you set.

A callback URL resumes exactly one contact at one step and is signed, so it can't be guessed or reused for another contact.

## Test with one contact

In the campaign's **Builder**, click **Test** to open **Test on one contact**. The journey shows the call to n8n and n8n's answer. For the trigger URL, run the n8n workflow once and check that the person appears in the campaign.

## Common errors

> [accordion] 422 VALIDATION\_FAILED from the trigger URL
>
> A field is missing or too long; `linkedin_url` is required. The answer lists the field.

> [accordion] 401 INVALID\_SIGNATURE
>
> The trigger requires a signature and the request wasn't signed with its secret. Sign it, or turn **Require a signature** off.

> [accordion] n8n gets nothing
>
> The workflow must be active for the **Production URL** to answer. Use **Send test event** in Kerux and look at the endpoint's delivery log in **Integrations > Developers**.

Related: [Trigger URLs and forms](/help/developers/trigger-urls-and-forms.md), [Webhooks](/help/developers/webhooks.md), [Webhook steps](/help/integrations/webhook-steps.md), [API](/help/developers/api.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.