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

# n8n Integration

> Self-hosted workflow automation with full control

n8n is an open-source workflow automation tool that you can self-host for complete data privacy and control. It offers powerful nodes for HTTP requests and webhooks to integrate with SendPilot.

## Why n8n?

* **Self-hosted**: Keep your data on your own servers
* **Open source**: Full transparency and customization
* **No vendor lock-in**: Export and own your workflows
* **Powerful**: Complex branching, loops, and error handling

## Setting Up SendPilot in n8n

### Step 1: Create a Webhook Node (Trigger)

1. Create a new workflow in n8n
2. Add a **Webhook** node as the trigger
3. Set method to `POST`
4. Copy the webhook URL (e.g., `https://your-n8n.com/webhook/abc123`)

### Step 2: Register Webhook in SendPilot

1. Go to SendPilot **Integrations** → **Webhooks**
2. Click **Add Webhook**
3. Paste your n8n webhook URL
4. Select events: `message.received`, `connection.accepted`, etc.
5. Save

### Step 3: Configure HTTP Request Node (Actions)

For calling SendPilot API, use the **HTTP Request** node:

```
Node: HTTP Request
  Method: POST
  URL: https://api.sendpilot.ai/v1/leads
  Authentication: None (use headers)
  Headers:
    X-API-Key: YOUR_API_KEY
    Content-Type: application/json
  Body:
    {
      "campaignId": "{{$json.campaignId}}",
      "leads": [...]
    }
```

## Example Workflows

### 1. Lead Reply → Slack + HubSpot

```
[Webhook Trigger] 
    → [IF: eventType == "message.received"]
    → [Slack: Send Message to #sales]
    → [HubSpot: Create Task]
```

**Webhook Node Configuration:**

* Path: `/sendpilot-events`
* Method: POST

**IF Node Configuration:**

* Value 1: `{{$json["eventType"]}}`
* Operation: Equal
* Value 2: `message.received`

**Slack Node Configuration:**

* Channel: `#sales-leads`
* Message: `🎉 Reply from {{$json["data"]["linkedinUrl"]}}: {{$json["data"]["replyPreview"]}}`

### 2. Google Sheet → Add Leads to Campaign

```
[Schedule Trigger (every hour)]
    → [Google Sheets: Read Rows]
    → [HTTP Request: POST /v1/leads]
    → [Google Sheets: Update Row (mark as processed)]
```

**HTTP Request Node:**

```json theme={null}
{
  "method": "POST",
  "url": "https://api.sendpilot.ai/v1/leads",
  "headers": {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  "body": {
    "campaignId": "your_campaign_id",
    "leads": [
      {
        "linkedinUrl": "={{$json[\"LinkedIn URL\"]}}",
        "firstName": "={{$json[\"First Name\"]}}",
        "lastName": "={{$json[\"Last Name\"]}}",
        "company": "={{$json[\"Company\"]}}"
      }
    ]
  }
}
```

### 3. Connection Accepted → Enrich + CRM Sync

```
[Webhook: connection.accepted]
    → [HTTP Request: Clearbit Enrichment]
    → [Merge: Combine data]
    → [Salesforce: Update Lead]
    → [Slack: Notify team]
```

### 4. Daily Campaign Report

```
[Schedule: Daily at 9am]
    → [HTTP Request: GET /v1/campaigns]
    → [Code: Calculate metrics]
    → [Slack: Send report]
```

**HTTP Request Node (Get Campaigns):**

```json theme={null}
{
  "method": "GET",
  "url": "https://api.sendpilot.ai/v1/campaigns",
  "headers": {
    "X-API-Key": "YOUR_API_KEY"
  }
}
```

## Reusable Credential Setup

Create a custom credential for SendPilot API:

1. Go to **Credentials** in n8n
2. Click **Add Credential**
3. Select **Header Auth**
4. Configure:
   * Name: `SendPilot API`
   * Header Name: `X-API-Key`
   * Header Value: `YOUR_API_KEY`

Now you can select this credential in HTTP Request nodes.

## Error Handling

n8n provides excellent error handling:

```
[HTTP Request]
    → Success: [Continue workflow]
    → Error: [Slack: Send error alert]
           → [Log error to database]
```

Add an **Error Trigger** workflow to catch failures:

```
[Error Trigger]
    → [Slack: Alert #ops channel]
    → [Save to error log]
```

## Complete Workflow JSON

Here's a complete workflow you can import into n8n:

```json theme={null}
{
  "name": "SendPilot Reply Handler",
  "nodes": [
    {
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 300],
      "parameters": {
        "path": "sendpilot-events",
        "httpMethod": "POST"
      }
    },
    {
      "name": "Filter Replies",
      "type": "n8n-nodes-base.if",
      "position": [450, 300],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"eventType\"]}}",
              "value2": "message.received"
            }
          ]
        }
      }
    },
    {
      "name": "Slack",
      "type": "n8n-nodes-base.slack",
      "position": [650, 250],
      "parameters": {
        "channel": "#sales-leads",
        "text": "🎉 New reply from {{$json[\"data\"][\"linkedinUrl\"]}}!"
      }
    }
  ]
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use Environment Variables">
    Store your API key in n8n environment variables, not hardcoded in workflows.
  </Accordion>

  <Accordion title="Add Retry Logic">
    Use the HTTP Request node's built-in retry options for resilience.
  </Accordion>

  <Accordion title="Log Everything">
    Add logging nodes to track workflow execution for debugging.
  </Accordion>

  <Accordion title="Test with Real Data">
    Use n8n's "Execute Workflow" feature to test with real webhook payloads.
  </Accordion>
</AccordionGroup>

## Deployment

### Self-Hosted

```bash theme={null}
docker run -it --rm \
  -p 5678:5678 \
  -e N8N_BASIC_AUTH_ACTIVE=true \
  -e N8N_BASIC_AUTH_USER=admin \
  -e N8N_BASIC_AUTH_PASSWORD=secure_password \
  -v ~/.n8n:/home/node/.n8n \
  n8nio/n8n
```

### n8n Cloud

Use [n8n.cloud](https://n8n.cloud) for a managed solution with the same features.
