# n8n Integration

> Connect WPsigner with n8n for self-hosted workflow automation with full control over your document signing workflows.

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/integrations/n8n/
Markdown: https://docs.wpsigner.com/md/integrations/n8n.md
Source file: integrations/n8n.md

---

Integrate WPsigner with [n8n](https://n8n.io) for powerful, self-hosted workflow automation. Build complex document signing workflows with n8n's visual editor while keeping all your data on your own infrastructure.

> **tip**
n8n is ideal for technical teams who want full control over their automation. It can be self-hosted for free or used via n8n Cloud. If you prefer a fully hosted solution, check out [Make](/integrations/make/) or [Zapier](/integrations/zapier/).

---

## How It Works

WPsigner connects to n8n in two directions:

```
Incoming: WPsigner → Webhook → n8n Workflow → External App
Outgoing: External App → n8n Workflow → WPsigner REST API
```

| Direction | n8n Node | Use Case |
|---|---|---|
| **WPsigner → n8n** | Webhook node | Trigger workflows when documents are signed, created, etc. |
| **n8n → WPsigner** | HTTP Request node | Create documents, send for signing, look up status |

---

## Requirements

- WPsigner **1.3.0+** (webhooks) / **1.8.0+** (REST API)
- n8n instance — either [self-hosted](https://docs.n8n.io/hosting/) or [n8n Cloud](https://n8n.io/cloud/)
- A WPsigner API key with **Full** permissions (for outgoing calls)

> **note**
Your n8n instance must be publicly accessible for WPsigner webhooks to reach it. If running locally, use a tunnel service like [ngrok](https://ngrok.com) or [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).

---

## Part 1: Receiving WPsigner Events (Triggers)

This enables n8n to react when something happens in WPsigner.

### Step 1: Add a Webhook Node

1. Open your n8n editor
2. Click **+** to add a new node
3. Search for **Webhook** and select it
4. Configure:
   - **HTTP Method**: `POST`
   - **Path**: Choose a custom path (e.g. `wpsigner-events`)
5. Click **Listen for test event** (or **Execute workflow** in production mode)
6. Copy the **webhook URL** shown (e.g. `https://your-n8n.com/webhook/wpsigner-events`)

> **note**
n8n has two URLs: **Test URL** (for testing) and **Production URL** (for live workflows). Use the production URL when registering in WPsigner.

### Step 2: Register the Webhook in WPsigner

1. Go to **WPsigner → More → Webhooks** in your WordPress admin
2. Click **Add Webhook**
3. Fill in:
   - **Name**: `n8n - Document Events`
   - **URL**: Paste the n8n webhook URL from Step 1 (use the **Production URL**)
   - **Events**: Select which events should trigger the workflow
   - **Secret** (optional): Add an HMAC secret for signature verification
4. Click **Save**

### Step 3: Test the Connection

1. In n8n, click **Listen for test event** on the Webhook node
2. In WPsigner, create or sign a test document
3. n8n should receive the webhook payload and display the data structure
4. You can now add more nodes to process the data

### Step 4: Add Processing Nodes

After the Webhook node, add any n8n node to process the data:

**Common nodes:**
- **IF** — Filter by event type
- **Set** — Transform/rename fields
- **Slack** — Send notifications
- **Google Sheets** — Log to spreadsheet
- **HTTP Request** — Call external APIs
- **Email (SMTP)** — Send custom emails
- **Postgres / MySQL** — Write to database

---

## Part 2: Calling WPsigner API (Actions)

This enables n8n to create documents, send for signing, and query status.

### Step 1: Generate API Credentials

1. Go to **WPsigner → Settings → API Keys**
2. Click **Generate New Key**
3. Set **Permissions** to `Full`
4. Copy the **API Key** and **API Secret**

> **caution**
Save the API Secret immediately — it is shown only once. If you lose it, generate a new key.

### Step 2: Store Credentials in n8n

For reusability, store your WPsigner credentials in n8n:

1. Go to **Settings → Credentials** in n8n
2. Click **Add Credential** → **Header Auth**
3. Add two header parameters:
   - **Name**: `X-WPS-API-KEY` → **Value**: your API key
   - **Name**: `X-WPS-API-SECRET` → **Value**: your API secret
4. Save as `WPsigner API`

Now you can reuse this credential in all HTTP Request nodes.

### Step 3: Create a Document

Add an **HTTP Request** node:

| Setting | Value |
|---|---|
| **Method** | `POST` |
| **URL** | `https://yoursite.com/wp-json/insigner/v1/documents` |
| **Authentication** | Header Auth → `WPsigner API` |
| **Body Content Type** | JSON |
| **Body** | See below |

```json
{
  "title": "{{ $json.deal_name }} Agreement"
}
```

### Step 4: Add a Signer

Add another **HTTP Request** node:

| Setting | Value |
|---|---|
| **Method** | `POST` |
| **URL** | `https://yoursite.com/wp-json/insigner/v1/documents/{{ $json.id }}/signers` |
| **Body** | See below |

```json
{
  "name": "{{ $json.contact_name }}",
  "email": "{{ $json.contact_email }}",
  "role": "signer"
}
```

### Step 5: Send for Signing

Add a third **HTTP Request** node:

| Setting | Value |
|---|---|
| **Method** | `POST` |
| **URL** | `https://yoursite.com/wp-json/insigner/v1/documents/{{ $node['Create Document'].json.id }}/send` |

---

## Example Workflows

### Workflow 1: Document Signed → Slack + Google Sheets

Log signed documents and notify your team simultaneously.

```
┌──────────┐    ┌────────┐    ┌──────────┐
│ Webhook  │───▶│   IF   │───▶│  Slack   │
│ WPsigner │    │ event= │    │  Notify  │
│          │    │ signed │    └──────────┘
│          │    │        │    ┌──────────┐
│          │    │        │───▶│  Sheets  │
└──────────┘    └────────┘    │  Log Row │
                              └──────────┘
```

**IF node condition:** `{{ $json.event }}` equals `document.signed`

**Slack message:**
```
📝 Document "{{ $json.data.document.title }}" signed by {{ $json.data.signer.name }} ({{ $json.data.signer.email }})
```

---

### Workflow 2: CRM Deal → Auto-Create Contract

When a deal closes in your CRM, automatically generate and send a contract.

```
┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ CRM      │───▶│ Create   │───▶│  Add     │───▶│  Send    │
│ Trigger  │    │ Document │    │ Signer   │    │ Document │
└──────────┘    └──────────┘    └──────────┘    └──────────┘
```

---

### Workflow 3: Document Completed → Database + Cloud Storage

When all signers finish, archive the record.

```
┌──────────┐    ┌────────┐    ┌──────────┐
│ Webhook  │───▶│  IF    │───▶│ Postgres │
│ WPsigner │    │ event= │    │  INSERT  │
│          │    │ compl. │    └──────────┘
│          │    │        │    ┌──────────┐
│          │    │        │───▶│   S3     │
└──────────┘    └────────┘    │  Upload  │
                              └──────────┘
```

---

### Workflow 4: Scheduled Document Status Check

Run daily to find unsigned documents and send reminders.

```
┌──────────┐    ┌──────────┐    ┌────────┐    ┌──────────┐
│  Cron    │───▶│  HTTP   │───▶│   IF   │───▶│  Email   │
│  Daily   │    │  GET    │    │ status │    │ Reminder │
│  9:00AM  │    │  /docs  │    │ =sent  │    │          │
└──────────┘    └──────────┘    └────────┘    └──────────┘
```

**HTTP Request:**
- `GET https://yoursite.com/wp-json/insigner/v1/documents?status=sent`

**IF condition:** Filter documents older than 3 days

---

## Available Events

Register these events when creating your webhook in WPsigner:

| Event | Triggered When |
|---|---|
| `document.created` | New document is created |
| `document.sent` | Document emails sent to signers |
| `document.viewed` | Signer opens the signing page |
| `document.signed` | Individual signer applies their signature |
| `document.completed` | All signatures complete |
| `document.declined` | Signer declines to sign |
| `document.expired` | Document expires unsigned |
| `signer.reminded` | Reminder sent to a signer |

---

## Webhook Payload Structure

All events send data in this format:

```json
{
  "event": "document.signed",
  "timestamp": "2026-01-15T11:00:00-05:00",
  "data": {
    "document": {
      "id": 123,
      "title": "Service Agreement",
      "status": "sent",
      "created_at": "2026-01-15T10:30:00-05:00"
    },
    "signer": {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "status": "signed",
      "signed_at": "2026-01-15T11:00:00-05:00"
    }
  },
  "meta": {
    "site_url": "https://yourdomain.com",
    "site_name": "Your Site",
    "plugin_version": "1.8.0"
  }
}
```

---

## API Endpoints Reference

These are the WPsigner REST API endpoints you can call from n8n's HTTP Request node:

| Endpoint | Method | Description |
|---|---|---|
| `/wp-json/insigner/v1/documents` | `GET` | List all documents |
| `/wp-json/insigner/v1/documents` | `POST` | Create a new document |
| `/wp-json/insigner/v1/documents/{id}` | `GET` | Get document details |
| `/wp-json/insigner/v1/documents/{id}/signers` | `POST` | Add a signer |
| `/wp-json/insigner/v1/documents/{id}/send` | `POST` | Send for signing |

For the full API reference, see [REST API Documentation](/api/).

---

## Tips & Best Practices

### Credential Management

- Store WPsigner API credentials as **Header Auth** credentials in n8n for reuse
- Never hardcode secrets in workflow expressions
- Use separate API keys for production vs. testing workflows

### Error Handling

- Add **Error Trigger** nodes to catch and log failures
- Use n8n's built-in **retry on fail** option on HTTP Request nodes
- Set up a Slack/email notification for failed workflow executions

### Performance

- WPsigner API keys have configurable rate limits (default: 1000 req/hour)
- Use n8n's **Wait** node between bulk operations
- If you see `429 Too Many Requests`, increase the rate limit on your API key
- For high-volume workflows, consider using n8n's queue mode

### Testing

1. Use n8n's **test URL** during development
2. Switch to the **production URL** when activating the workflow
3. Test with a sample document before going live
4. Monitor the first few executions for data mapping issues

---

## Troubleshooting

| Issue | Cause | Solution |
|---|---|---|
| Webhook not received | URL incorrect or workflow inactive | Verify the URL and ensure workflow is **active** (not just saved) |
| n8n shows "Waiting for webhook" | WPsigner hasn't sent an event yet | Trigger an event (create/sign a document) or check webhook URL |
| `401 Unauthorized` from API | Invalid API key or secret | Double-check `X-WPS-API-KEY` and `X-WPS-API-SECRET` headers |
| `403 Forbidden` | Read-only API key | Generate a new key with **Full** permissions |
| `404 Not Found` | Wrong endpoint URL | Verify the URL includes `/wp-json/insigner/v1/` |
| Expressions not resolving | Wrong n8n expression syntax | Use `{{ $json.field }}` for current node data |
| Webhook data incomplete | Not all events selected | Check WPsigner → Webhooks and enable the needed events |

---

## Self-Hosting Tips

If you're self-hosting n8n:

- Ensure your n8n instance has a **public URL** or use a tunnel (ngrok, Cloudflare Tunnel)
- Set `WEBHOOK_URL` environment variable to your public URL
- Use `N8N_PROTOCOL=https` for secure webhook delivery
- Consider using Docker with a reverse proxy (nginx/Caddy) for production

---

## Next Steps

- [Make Integration](/integrations/make/) — Hosted visual automation alternative
- [Zapier Integration](/integrations/zapier/) — Connect with 6,000+ apps
- [API Overview](/api/) — Full REST API documentation
- [Google Drive Integration](/integrations/google-drive/) — Auto-backup signed documents
