---
title: "Zapier and n8n"
description: "Start Zaps and n8n workflows from new submissions with REST hooks, and call the API from them."
---

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

# Zapier and n8n

Automation tools get new submissions through REST hooks: a subscription adds an [HTTP destination](https://docs.getquickforms.com/destinations/#http-request) to the form that posts the `submission.created` event to the tool's URL. Unsubscribing deletes it. Hook deliveries are retried and logged like any other [destination](https://docs.getquickforms.com/destinations/#how-destinations-are-delivered).

| Endpoint | Description |
| --- | --- |
| `POST /api/v1/hooks` | Subscribe a URL to a form's new submissions. |
| `DELETE /api/v1/hooks/{hook}` | Unsubscribe. |
| `GET /api/v1/forms/{form}/sample` | A sample event, for mapping fields while you build. |

All three take a team API key as `Authorization: Bearer <api_key>`. See [API](https://docs.getquickforms.com/api/).

## Subscribe

### Request

```bash
curl -X POST https://YOUR-QUICKFORMS-HOST/api/v1/hooks \
  -H "Authorization: Bearer $QUICKFORMS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"form_id": "FORM_ID", "target_url": "https://hooks.zapier.com/hooks/standard/1/abc", "name": "Zapier"}'
```

### 201 response

```json
{
  "data": {
    "id": "01jcd3n5p7q9r1s3t5v7w9x1y3",
    "form_id": "01jc8xk2m5t9qw3e7r4y6u8v0p",
    "type": "http",
    "service": "HTTP request",
    "name": "Zapier",
    "enabled": true,
    "config": { "url": "https://hooks.zapier.com/hooks/standard/1/abc", "method": "POST", "body": "event" },
    "mapping": { "name": "{{name}}", "email": "{{email}}", "message": "{{message}}" },
    "conditions": [],
    "created_at": "2026-11-06T10:24:00.000000Z",
    "updated_at": "2026-11-06T10:24:00.000000Z"
  }
}
```

| Field | Required | Description |
| --- | --- | --- |
| `form_id` | Yes | The form to subscribe to. |
| `target_url` | Yes | Where to send each event. An `https` URL, up to 2048 characters. |
| `name` | No | The destination's name, shown in the delivery log. Defaults to `Automation hook`. |

The response is the new destination. Keep its `id`: it is the hook ID you unsubscribe with. The IDs are illustrative.

The hook counts towards the form's 20 destinations. A form outside the API key's team returns a `404`, and an invalid `target_url` a `422`.

## Unsubscribe

```bash
curl -X DELETE https://YOUR-QUICKFORMS-HOST/api/v1/hooks/HOOK_ID \
  -H "Authorization: Bearer $QUICKFORMS_TOKEN" \
  -H "Accept: application/json"
```

Returns `204`. The hook ID must be an HTTP destination on one of your team's forms, otherwise the response is a `404`.

## What the hook receives

Each submission is a `POST` with `Content-Type: application/json` and `User-Agent: quickforms-destinations/1.0`. The body is the same `submission.created` event as the [form webhook](https://docs.getquickforms.com/webhooks/#request):

```json title="POST body"
{
  "id": "evt_01jca9qf3tz5b8m2k7w4r6x0hn",
  "type": "submission.created",
  "created_at": "2026-11-06T10:24:00+00:00",
  "sandbox": false,
  "form": { "id": "01jc8xk2m5t9qw3e7r4y6u8v0p", "name": "Contact" },
  "submission": {
    "id": "01jca9qf3tz5b8m2k7w4r6x0hn",
    "data": { "name": "Ada Lovelace", "email": "ada@example.com", "message": "Hello" },
    "confirmed_at": null,
    "link": null,
    "created_at": "2026-11-06T10:24:00+00:00"
  }
}
```

- Hooks are not signed. To sign them, set the destination's `sign` setting to `yes` with `PATCH /api/v1/destinations/{destination}`. See [HTTP request](https://docs.getquickforms.com/destinations/#http-request).
- Like every destination, hooks are held for spam review and [double opt-in](https://docs.getquickforms.com/double-opt-in/), and are never sent for [sandbox](https://docs.getquickforms.com/sandbox/) submissions.
- File fields include a [signed download link](https://docs.getquickforms.com/file-uploads/#download-links).

## Sample event

`GET /api/v1/forms/{form}/sample` returns a list with one event. It is built from the form's latest submission, so the tool can show your real fields while you map them.

```bash
curl https://YOUR-QUICKFORMS-HOST/api/v1/forms/FORM_ID/sample \
  -H "Authorization: Bearer $QUICKFORMS_TOKEN" \
  -H "Accept: application/json"
```

If the form has no submissions yet, the event is made up from the form's fields, with `Example` for every answer:

```json title="200 response"
{
  "data": [
    {
      "id": "evt_sample",
      "type": "submission.created",
      "sandbox": true,
      "form": { "id": "01jc8xk2m5t9qw3e7r4y6u8v0p", "name": "Contact" },
      "submission": {
        "id": "sample",
        "data": { "name": "Example", "email": "Example", "message": "Example" }
      }
    }
  ]
}
```

## Zapier

The repository includes a Zapier Platform CLI app in `integrations/zapier`. It hasn't been published to Zapier, so push it to your own Zapier account to use it.

### Push the app

```bash
npm i -g zapier-platform-cli
cd integrations/zapier
npm install
zapier register "quickforms"
zapier push
```

### Connect an account

When you connect quickforms in Zapier, it asks for:

| Field | Description |
| --- | --- |
| quickforms URL | Where your quickforms app runs, without a trailing slash. |
| API key | A team API key. |

Zapier checks the connection with `GET /api/v1/me` and labels it with your team's name. Every request sends the API key as `Authorization: Bearer <api_key>`.

### New submission trigger

Triggers when a form receives a submission, after spam checks and double opt-in.

- Pick the form from a dropdown of your forms.
- Turning the Zap on subscribes with `POST /api/v1/hooks` (named `Zapier`), and turning it off unsubscribes.
- Each submission gives the Zap the submission's `id`, `data`, `confirmed_at`, `link` and `created_at`, plus `form` and `sandbox`.
- When you test the trigger, Zapier loads the form's 10 latest live submissions from `GET /api/v1/forms/{form}/submissions`.

### Send test submission action

Sends a [sandbox](https://docs.getquickforms.com/sandbox/) test submission with `POST /api/v1/forms/{form}/test-submissions` and returns the stored submission. Nothing is emailed or posted.

| Field | Description |
| --- | --- |
| Form | The form to test. |
| Answers | Field name and value pairs. |

## n8n

No custom n8n node is needed.

### Trigger a workflow

Add an n8n **Webhook** node and copy its URL, then either:

- Add an [HTTP request destination](https://docs.getquickforms.com/destinations/#http-request) to the form, pointing at that URL with `body` set to `event`. Do this from the form's **Destinations** tab in the dashboard, or with the API.
- Or subscribe from a workflow with an **HTTP Request** node calling `POST /api/v1/hooks`, and unsubscribe with `DELETE /api/v1/hooks/{hook}`.

Use `GET /api/v1/forms/{form}/sample` to get an event to map fields from.

> **Note**
>
> `POST /api/v1/hooks` only takes `https` URLs. On the hosted platform, URLs that resolve to a private or reserved address are refused, so a self-hosted n8n needs a public address. See [private addresses](https://docs.getquickforms.com/destinations/#private-addresses).

### Call quickforms from a workflow

Use the **HTTP Request** node against the [API](https://docs.getquickforms.com/api/), with header auth: `Authorization` set to `Bearer <api_key>`. For example, `POST /api/v1/forms/{form}/test-submissions` sends a sandbox test submission.

## Make

The same works for Make: point an [HTTP request destination](https://docs.getquickforms.com/destinations/#http-request) with `body` set to `event` at a Make custom webhook, or subscribe with `POST /api/v1/hooks`.

Source: https://docs.getquickforms.com/zapier-and-n8n/index.mdx
