---
title: "n8n"
description: "Trigger n8n workflows from Prosyo events, verify webhook signatures, and add leads and enroll them in LinkedIn campaigns from n8n."
url: https://prosyo.com/docs/integrations/n8n/
section: "Integrations"
updated: 2026-11-06
---

# n8n

Connect Prosyo to [n8n](https://n8n.io) in two directions:

- **Prosyo → n8n:** start a workflow when a prospect replies, changes stage, is enriched, and so on.
- **n8n → Prosyo:** add leads to a Prosyo list from any source n8n can read.

Works with n8n Cloud and self-hosted n8n. Self-hosted n8n must be reachable over **public HTTPS** on the standard port (443). Addresses with another port, such as `:5678`, are rejected.

---

## Prosyo → n8n: trigger a workflow

### 1. Add a Webhook trigger in n8n

1. Create a new workflow.
2. Add a **Webhook** node.
3. Set **HTTP Method** to `POST`.
4. Set **Path**, for example `prosyo`.
5. Set **Respond** to **Immediately**.
6. Under **Options**, turn on **Raw Body**. You need it to verify the signature.
7. Copy the **Production URL**, for example `https://yourname.app.n8n.cloud/webhook/prosyo`.

> **Important:** Use the **Production URL**, not the Test URL, and **activate** the workflow. The Test URL only works while you're listening in the editor.

### 2. Connect the webhook in Prosyo

You need to be a workspace **owner or admin**.

1. Go to **Integrations** and click the **Custom webhook** card, then **Connect Custom webhook**.
2. Paste the n8n Production URL into **HTTPS endpoint** and click **Connect**.
3. Copy the **Signing secret**. It's shown once.
4. Choose your **Events** and click **Save mapping**.
5. Click **Test connection**. The execution appears in n8n, with the type `integration.test`.

### 3. Verify the signature (recommended)

Add a **Crypto** node after the Webhook node:

- **Action:** Hmac
- **Type:** SHA256
- **Value:** the raw body
- **Secret:** your Prosyo signing secret. Store it in an n8n credential or variable, not in plain text.
- **Encoding:** hex
- **Property name:** `expectedSignature`

Then add an **If** node that checks `{{ $json.expectedSignature }}` equals `{{ $('Webhook').item.json.headers['x-prosyo-signature'] }}`. Only continue on **true**.

Or use one **Code** node:

```js
const crypto = require('crypto');
const secret = $env.PROSYO_WEBHOOK_SECRET; // or paste from a credential
const item = $input.first();
const raw = Buffer.from(item.binary.data.data, 'base64'); // raw body from the Webhook node
const expected = crypto.createHmac('sha256', secret).update(raw).digest('hex');
if (expected !== item.json.headers['x-prosyo-signature']) {
  throw new Error('Invalid Prosyo signature');
}
return [{ json: JSON.parse(raw.toString('utf8')) }];
```

On self-hosted n8n, allow the `crypto` module in Code nodes with `NODE_FUNCTION_ALLOW_BUILTIN=crypto`.

### 4. Route by event

Add a **Switch** node on `{{ $json.type }}` (or the `x-prosyo-event` header):

| Route | Example next step |
|---|---|
| `conversation.reply_received` | Send an SMS, create a CRM task, post to Teams |
| `prospect.stage_changed` where `data.stage` = `meeting` | Add a row to Google Sheets, create a deal in Pipedrive |
| `account.needs_reconnect` | Email the account owner |
| `intent.high_intent` | Create a task for the account owner |
| `prospect.created` | Look up the company in Apollo or another data tool |
| `integration.test` | Ignore it. It's the sample sent by **Test connection**. |

### Recipe: replies → Google Sheets

1. **Webhook** (Prosyo, `conversation.reply_received`)
2. **Google Sheets → Append row** with `data.full_name`, `data.company`, `data.email`, `data.stage` and `created_at`

### Recipe: meetings → Pipedrive deal

1. **Webhook** (Prosyo, `prospect.stage_changed`)
2. **If** `data.stage` equals `meeting`
3. **Pipedrive → Create person** and **Create deal**

If you also use Prosyo's own [Pipedrive integration](https://prosyo.com/docs/integrations/pipedrive.md), it already creates the person and their organization. In that case, find the person by email instead of creating them again, then create the deal.

---

## Add leads to Prosyo from n8n

Use the same API token as the [Chrome extension](https://prosyo.com/docs/integrations/chrome-extension.md).

1. In Prosyo, go to **Integrations**, click the **Chrome extension & API** card and click **Generate API token**. Copy it. Only owners and admins can generate one. If your workspace already has a token and you saved it, use it. Otherwise click **Rotate token**: it replaces every token, so paste the new one into your Chrome extension and every other tool that used the old one.
2. In n8n, create a **Header Auth** credential:
   - **Name:** `Authorization`
   - **Value:** `Bearer YOUR_TOKEN`
3. Add an **HTTP Request** node:
   - **Method:** `POST`
   - **URL:** `https://app.prosyo.com/api/v1/ext/leads`
   - **Authentication:** Generic → Header Auth → your credential
   - **Send Body:** JSON

```json
{
  "listName": "Inbound – website form",
  "leads": [
    {
      "firstName": "{{ $json.first_name }}",
      "lastName": "{{ $json.last_name }}",
      "email": "{{ $json.email }}",
      "title": "{{ $json.job_title }}",
      "companyName": "{{ $json.company }}",
      "website": "{{ $json.website }}",
      "linkedinUrl": "{{ $json.linkedin }}"
    }
  ]
}
```

**Lead fields:** `fullName`, `firstName`, `lastName`, `title`, `companyName`, `linkedinUrl`, `website`, `email`, `phone`, `locationName`. Each lead needs at least a name, a LinkedIn URL or an email. If a value is empty, leave the field out or send `null`. An empty string in `email` is rejected as an invalid email.

**Rules:**

- Up to **100 leads per request**. Use n8n's **Loop Over Items** node to batch.
- `listName` adds the leads to that list, creating it if needed. Or pass an existing `listId`. Leave both out to save the leads without a list.
- New leads count toward your monthly import limit. People already in Prosyo are matched by their LinkedIn profile and updated instead, so send `linkedinUrl` whenever you have it.
- Up to **60 requests per minute** per user.

Other useful calls with the same token:

| Call | Use |
|---|---|
| `GET /api/v1/ext/session` | Check the token and remaining import quota |
| `GET /api/v1/ext/boards` | Get your lists, tags and stages |
| `GET /api/v1/ext/inbox` | Read the latest replies |

## Start campaigns automatically

Go one step further: add the lead **and enroll them in a campaign** in the same workflow. See [Custom triggers](https://prosyo.com/docs/integrations/custom-triggers.md) for step-by-step recipes, and the [API reference](https://prosyo.com/docs/integrations/api-reference.md) for every endpoint.
