formbasedocs
Go to appApp

Integrations

Custom webhooks

Send each completed submission as a signed POST request to any HTTPS endpoint — your backend, automation platform, or serverless function.


How it works

On every submission, formbase POSTs a JSON body to your webhook URL. The request is signed with HMAC-SHA256, retried on failure, and logged in the integration’s event log. This page covers setup. The exact payload, headers, and signature algorithm live in the webhook reference.

Add a webhook

  1. 1

    Open form Integrations

    Form → Settings → Integrations → Webhook.

  2. 2

    URL

    Type the host and path — the https:// prefix is fixed in the input. Plain http:// is accepted only for localhost during development.

  3. 3

    Mapping

    Leave it empty to send every field. Add rows to send only those fields, under the JSON key you choose. The mapping shapes the answers and display objects together, so a renamed key is renamed in both. The full request under the mapping redraws as you edit it.

  4. 4

    Headers

    A signing secret starting with whsec_ is generated for you. It cannot be changed after creation. On the same step, add up to 5 custom headers your endpoint needs, such as an authorization token, and turn on Send the field list with every event if your receiver cannot call fields.list. Content-Type is set automatically and cannot be overridden.

  5. 5

    Finalize

    Press Send a test event to POST a synthesized example submission, then press Create integration.

Multiple webhooks

You can attach multiple webhooks to a single form. Each fires independently for every event.

Which URLs formbase accepts

  • https:// everywhere, or http:// for localhost and *.localhost during development.

  • No credentials in the URL, and at most 2,048 characters.
  • No private or internal addresses. The hostname is resolved and re-checked immediately before every delivery, so a DNS record repointed at an internal address after setup is still refused.

A refused URL is a configuration problem, not a transient one: the delivery fails permanently instead of retrying.

What you receive

Every request is the same event envelope — id, type, createdAt, apiVersion, test and data. Inside data sit the form, the submission (id, respondent email, submitted time, PDF link, language), an answers object keyed by field key, and a display object with the same keys as readable text. Each answer appears once, in each map.

See the reference for the full payload shape, answers and display, and how a repeating group is represented.

To preview the exact body for your form, open the integration and expand Example payload under the signing secret. It renders your current mapping with sample answers.

Verifying signatures

Each request includes an X-formbase-Signature header: t=TIMESTAMP,sha256=HEX, an HMAC-SHA256 of TIMESTAMP.BODY computed with your signing secret. The secret itself is never sent. The reference has a copy-pasteable verification snippet.

Abandoned response events

Custom webhooks fire only for completed submissions and edits — never for abandoned drafts. A custom webhook is the one receiver that gets both: a Zapier, Make or n8n subscription picks first submissions or edits, never both. For abandoned drafts, use a provider that has an Abandoned submissions step: Google Sheets, Airtable, Notion, Slack, Discord, Linear, or GitHub Issues. Each takes its own idle window and, where it applies, its own message template. That step requires Pro or Business.

Retries and failures

  • A delivery succeeds on any 2xx.

  • Up to 5 attempts: the first fires immediately, retries wait at least 1, 2, 4, and 8 minutes. formbase looks for due retries every 30 minutes, so the last attempt comes about two hours after the first. A Retry-After header on a 429 or 5xx is honored when it asks for a longer wait.

  • 429, 5xx, timeouts, and connection failures are retried. Every other 4xx fails immediately.

  • After 5 consecutive failures the integration auto-pauses and the person who set it up gets an email. Fix the endpoint, then press Resume.

  • 401, 403, and 404 stop the integration right away with an error status and the same email — there is no waiting for five failures.

  • Deliveries that used up all 5 attempts collect in a banner on the integration. Retry all re-queues them and reactivates a paused integration.

Testing

Send a test event appears on the Finalize step and again on the saved integration. It POSTs a synthesized example submission — “John Doe” for text, 42 for numbers, john@example.com for email — signed and with your custom headers, exactly like a real delivery. From the saved integration it also writes a connection-test entry to the event log.

For local development, expose your dev server with a tunnel:

bash
# ngrok
ngrok http 3000

# cloudflare tunnel

cloudflared tunnel --url http://localhost:3000

FAQ

Yes. Each has its own URL, signing secret, and custom headers. All active webhooks fire independently for every submission.

Yes — up to 5, added during setup or later from the integration. Content-Type is set automatically and any attempt to override it is ignored.

No. The signing secret is generated once when the webhook is created and cannot be changed. If you need a new secret, delete the webhook and create a new one.

Custom webhooks (configured in Form settings) fire only for completed submissions and updates. For abandoned-draft events, use Slack, Discord, or a project-management integration — each has a dedicated abandoned-event tab. If you need abandoned events via HTTP, create a submission_abandoned subscription through the REST API webhook subscriptions, from Zapier, Make, or any other caller.

Only for localhost and *.localhost during development. All other URLs must use HTTPS.

Delete it from Form settings → Integrations. formbase stops sending requests immediately, and the integration’s event history is deleted with it.

Next steps