# n8n

> Connect n8n workflows to a pod with an API key, a webhook subscription and the Hub REST API.

URL: https://docs.synap.live/docs/build/n8n · Last reviewed against the code: 2026-10-20

There is no Synap node for n8n. You connect a workflow to a pod with n8n's built-in **Webhook** trigger and **HTTP
Request** nodes, the pod's [Hub REST API](/docs/reference/hub-api) and an [API key](/docs/build/api-keys). Use the Hub
REST API (`/api/hub/*`) from n8n, not the pod's `/trpc` endpoint.

In the examples, `https://pod.example.com` is your pod and `$SYNAP_API_KEY` is the key.

## 1. Create a key for n8n

In the pod's admin console, open **Keys**, create a key named after the workflow (for example "n8n"), and give it the
scopes `hub-protocol.read` and `hub-protocol.write`. Narrow its grant to what the workflow touches; see
[Grants](/docs/build/api-keys#grants-what-a-key-may-touch). Copy the key: it is shown once.

In n8n, store it as a header credential, so every HTTP Request node sends:

```http
Authorization: Bearer <your key>
```

## 2. Receive the pod's events in n8n

Add a **Webhook** trigger node to the workflow with the `POST` method, and copy its production URL. Then subscribe that
URL to the events you want, with the key:

```bash
curl -X POST https://pod.example.com/api/hub/webhooks \
  -H "Authorization: Bearer $SYNAP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://n8n.example.com/webhook/synap", "eventTypes": ["entity.create.completed"]}'
```

The answer (`201`) holds the subscription's `id` and its `secret`. The secret is returned only here: keep it if you
want to verify signatures. Pick event types from the [event catalog](/docs/reference/events#catalog).

Each event arrives as a `POST` with a JSON body (`type`, `subjectId`, `userId`, `data`, `timestamp`) and the headers
described in [Webhooks](/docs/build/webhooks#what-your-endpoint-receives). To check `X-Synap-Signature` in the
workflow, compute the HMAC over the raw request body, as shown in
[Verify the signature](/docs/build/webhooks#verify-the-signature). A failed delivery is retried with the same
`X-Synap-Delivery-Id`; use it to skip duplicates.

A subscription created with a key belongs to that key:

- it delivers only the events the key's grant can read, and only while the key is valid; revoking or expiring the key
  stops it;
- the key lists (`GET /api/hub/webhooks`) and deletes (`DELETE /api/hub/webhooks/<id>`) only its own subscriptions.

## 3. Write to the pod from n8n

Add an **HTTP Request** node that sends `POST https://pod.example.com/api/hub/entities` with a JSON body:

```json
{
  "profileSlug": "note",
  "title": "Weekly report",
  "content": "Generated by n8n.",
  "source": "n8n"
}
```

`title` is required. `profileSlug` is the kind (`note`, `task`, …). `content` is a long Markdown body, stored as a
linked document.

Writes go through the pod's governance, so handle both answers:

| Status | Meaning |
|---|---|
| `200` | The entity was created. |
| `202` | It became a proposal for a person to approve: `{ status: "proposed", proposalId, reviewUrl }`. |
| `409` | An entity of the same kind with this title already exists. |

Send an `Idempotency-Key` header (for example the n8n execution ID) so that a retried node does not create a second
entity.

## 4. Read from the pod

```http
GET https://pod.example.com/api/hub/entities?profileSlug=task&limit=20
```

`q` searches instead of listing. Every endpoint, with its parameters and answers, is in the
[Hub REST API reference](/docs/reference/hub-api). A key whose grant is narrower than `*` cannot use every read
endpoint; see [Doors a scoped key can read through](/docs/build/api-keys#doors-a-scoped-key-can-read-through).
