Webhooks

A webhook sends every new answer of a form to an address of your choice, such as business software or an automation tool.

Setting up the webhook

  1. Open the form's Studio, Automations tab.
  2. In the Webhook block, enter the URL that will receive the calls (a public https:// address).
  3. Enter an HMAC secret, a long random string that you also keep on your side.
  4. Save and check that the automation is enabled.

When the call is made

The call is made for every new answer, wherever it comes from: public link, embedded page, mobile app, API or a shared session. It is sent in the background: submitting the form does not wait for your server.

What your server receives

A POST request with content type application/json:

{
  "submission_id": 1234,
  "form_slug": "site-inspection",
  "data": { "...": "the answers, question by question" },
  "date_submitted": "2026-10-16T08:42:11+00:00"
}

The X-Formsbuilder-Signature header holds sha256= followed by the HMAC-SHA256 signature of the raw body, computed with your secret.

Verifying the signature

import hashlib, hmac

def is_valid_signature(body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)

Compute the signature on the exact body received, before any JSON parsing.

Errors and retries

Your server must answer within 10 seconds. On a network error or a 5xx response, the call is retried up to three times, one minute apart; a 4xx response is not retried. Internal addresses (private network, localhost) are refused.