> For the complete documentation index, see [llms.txt](https://docs.dapta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dapta.ai/dapta-forms/connect/webhooks.md).

# Webhooks

Send every Dapta Forms submission as a JSON POST to a URL you control. Set the endpoint, an optional signing secret, choose whether partial and complete submissions trigger it, send a test, and switch

A webhook POSTs each submission as JSON to an endpoint you own: your CRM, an automation tool, a spreadsheet connector, or your own backend. You set it up per form from the **Connect** tab. Delivery is durable: a submission is stored first and the webhook is queued, retried on failure, and logged so you can see what was sent and what your endpoint answered.

This page covers the webhook card. The request format is on [Payload & headers reference](/dapta-forms/connect/webhooks/payload-reference.md), authentication on [Verify the signature](/dapta-forms/connect/webhooks/verify-signature.md), and testing on [Test & delivery history](/dapta-forms/connect/webhooks/test-and-history.md).

***

**Step 1:** Open your form in the editor and click **Connect** in the top bar. In the **Integrations** section, find the **Webhook** card ("POST each submission as JSON to a URL you control.") and turn the switch on. The label changes from **Disabled** to **Enabled** and the card expands.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-0f86abfc7f6b9224d8d35217a6c86db7123d1ea8%2Fforms-webhooks-01-enable-switch.png?alt=media" alt="The Webhook card with the Enabled switch turned on, showing the Endpoint URL, Signing secret and Trigger on fields"><figcaption><p>Turn the switch on to reveal the webhook settings.</p></figcaption></figure>

***

**Step 2:** Paste your URL in **Endpoint URL**. It must start with `https://` (plain `http://` is accepted only for `localhost`, for local development). Anything else shows "Enter a valid https\:// URL (plain http is allowed only for localhost)." As soon as the URL is valid it is saved: the footer reads **Changes saved automatically**, and the webhook is live on the published form from that moment.

**Step 3 (recommended):** Type a **Signing secret (optional)**. When set, each request is signed with HMAC-SHA256 in the `X-Forms-Signature` header so your endpoint can verify the request really came from Dapta Forms. After you leave the field it is masked and reads **A secret is set. Leave blank to keep it, or type a new one.** The secret is never shown again.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-c050d6b43435067c711bb57d338af909b75f74bb%2Fforms-webhooks-02-url-and-secret.png?alt=media" alt="The Webhook card with an Endpoint URL filled in and a Signing secret typed"><figcaption><p>Endpoint URL and signing secret. Both save automatically.</p></figcaption></figure>

***

**Step 4:** Under **Trigger on**, choose which submissions are sent: **Partial submissions**, **Complete submissions**, or both. Both are ticked by default and at least one must stay ticked.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-639685ae6b7353374f8417f041de152a97cf8350%2Fforms-webhooks-03-trigger-on.png?alt=media" alt="The Trigger on checkboxes for Partial submissions and Complete submissions"><figcaption><p>Choose which submissions are sent to this webhook.</p></figcaption></figure>

* A **partial** submission is sent when the respondent passes the form's **Partial submit point** (for example right after the email question) and has not finished yet.
* A **complete** submission is sent when the respondent reaches the end. The same session produces one partial and then one complete delivery; both carry the same `submission.id`, and `phase` tells them apart.

***

**Step 5:** Click **Send test**. Dapta Forms posts one sample body in the real shape, signed with your secret, with made-up answers and `"test": true` in the data. A green toast **Test delivered. Your endpoint accepted it.** means your endpoint answered with a 2xx status. If it did not, the toast explains what came back (see [Test & delivery history](/dapta-forms/connect/webhooks/test-and-history.md)).

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-f1ea43cee96626f4e8cdd10fc731b1f526034736%2Fforms-webhooks-04-send-test.png?alt=media" alt="The Send test button with a toast that reads Test delivered. Your endpoint accepted it."><figcaption><p>A successful test. The sample request reaches your endpoint for real.</p></figcaption></figure>

> **⚠️ Note:** **Send test** is available to Owners and Admins. Any member can edit the webhook fields.

***

## Settings reference

| Setting                           | What it does                                                                                                                                                              |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Enabled** / **Disabled** switch | Turns the webhook on or off without losing its settings. Off means nothing is queued for this webhook.                                                                    |
| **Endpoint URL**                  | The `https://` URL that receives the POST. Clearing the field removes the webhook. Private, loopback, link-local and cloud metadata addresses are blocked before sending. |
| **Send test**                     | Posts one signed sample request. Disabled until a URL is saved (otherwise: "Save a webhook URL first.").                                                                  |
| **Signing secret (optional)**     | Key for the HMAC-SHA256 signature in `X-Forms-Signature`. Leave blank to keep the current one; type a new value to rotate it.                                             |
| **Trigger on**                    | **Partial submissions** and/or **Complete submissions**. At least one.                                                                                                    |
| **Webhook history**               | A **{n} deliveries** chip (or a red **{n} failed**) and the **View history** button that opens the delivery log.                                                          |

## How a delivery behaves

* Method **POST**, header `content-type: application/json`, body = the JSON envelope described in [Payload & headers reference](/dapta-forms/connect/webhooks/payload-reference.md).
* Your endpoint has 10 seconds to answer. Any **2xx** counts as delivered. A 3xx is never followed and counts as a failure, as do 4xx, 5xx, timeouts and network errors.
* Failures are retried automatically with increasing delays (1 s, 2 s, 4 s, 8 s…), up to 5 attempts. After that the delivery is marked **Failed** and kept in the history. See [Delivery, retries & history](/dapta-forms/connect/delivery-and-retries.md).
* Nothing is sent to a webhook that is **Disabled**, and a submission is always stored even if the webhook is down.

## Several webhooks on one form

Each form can hold more than one webhook, but the card edits only the first. When others exist you see **This form has {count} more webhook(s)** with the note that they keep running exactly as they are and are saved untouched, just not editable from here. All of them are listed in the **Webhooks** inventory on the [Connections](/dapta-forms/connect/connections.md) page.

> **💡 Tip:** UTM parameters on the public link (`utm_source`, `utm_medium`, …) ride along in every webhook body, nested under `data.utm` and again at the top level under `utm`, so your endpoint can attribute the lead.

## What's next

* [Payload & headers reference](/dapta-forms/connect/webhooks/payload-reference.md): every field and header.
* [Verify the signature](/dapta-forms/connect/webhooks/verify-signature.md): Node.js and Python snippets.
* [Test & delivery history](/dapta-forms/connect/webhooks/test-and-history.md): read the Webhook history dialog.
* [Partial submissions](/dapta-forms/builder/partial-submissions.md): where the partial submit point goes.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.dapta.ai/dapta-forms/connect/webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
