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

# n8n integration

> Build workspace event and REST workflows with scoped credentials and safe retries.

Use a **Webhook** node for incoming workspace events and **HTTP Request** nodes for public REST calls. Store the SendPilot key in an n8n Header Auth credential with header name `X-API-Key`, rather than in an exported workflow.

## Receive workspace events

1. Add a POST Webhook node and obtain its public HTTPS URL.
2. Register it in **SendPilot → Integrations → Webhooks**.
3. Subscribe to exact event names such as `reply.received` and `connection_request.accepted`.
4. Preserve the raw body and signature headers for [Svix verification](https://docs.sendler.ai/webhooks/setup.md), or use a verifying receiver before n8n.
5. Extract the verified event body from the trigger output and deduplicate by `eventId`.

The Webhook node commonly places parsed JSON under `$json.body`; inspect your node's actual output before mapping expressions. This guide describes the workflow, not an importable version-specific node export.

## Reply → Slack and CRM

```text theme={null}
Verified event
  → deduplicate eventId
  → eventType equals reply.received
  → send notification using data.reply and data.linkedinUrl
  → create a CRM follow-up task
```

`leadId` and `campaignId` can be null for non-campaign replies. Guard those fields before calling lead-specific REST actions.

## Spreadsheet → campaign leads

1. Schedule a sheet read and select unprocessed rows.
2. POST to `https://api.sendpilot.ai/v1/leads` using the stored Header Auth credential.
3. Add `Content-Type: application/json` and a stable `Idempotency-Key` derived from the source row/batch identity.
4. Supply the body below, mapping your row fields rather than sending the placeholders.
5. Inspect added/duplicate/invalid counts before marking rows processed.

```json theme={null}
{
  "campaignId": "CAMPAIGN_ID",
  "leads": [{
    "linkedinUrl": "https://www.linkedin.com/in/PROFILE_ID",
    "firstName": "Alex",
    "company": "Example company",
    "source": "CRM import"
  }]
}
```

REST imports support up to 1,000 leads and flat custom fields. Campaign state determines when imported leads participate in outreach.

## Daily campaign report

Use a scheduled GET to `/v1/campaigns`, iterate `page` and `limit` within the documented bounds, then summarize the returned counts. First check `/v1/me` to confirm the workspace and scopes.

## Error handling

Use an error branch for 401/403 permission failures, 402 entitlement failures, 429 limits, and 409/422 idempotency outcomes. Built-in retries must retain the same idempotency key and body. Inspect uncertain sends before another attempt. See [REST behavior](https://docs.sendler.ai/api-reference/behavior.md).

MCP OAuth URLs are for compatible AI clients; they do not replace the API-key header on HTTP Request nodes.


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