A webhook sends every new entry automatically as JSON to a web address, for example to Zapier, Make, n8n or your own system. Funnelforms signs every call, so the receiver can check that it comes from your website.
Requirements
- Funnelforms Pro. This feature is not included in Funnelforms Free. Free does not offer Webhook under Add an action and names webhooks in the note with the Pro badge; the Interfaces tab of the settings is Pro only too.
- You have the right to see entries. Without this right you can prepare the action; someone with the right publishes it.
- The receiver has a web address that accepts POST calls.
- For the webhook secret you need the right to change the settings.
Where to find it
- Action: open the form in the editor, click the contact step in the Structure workspace, open the After sending tab on the right and choose Webhook under Actions in Add an action.
- Secret for the signature: Funnelforms → Settings → Interfaces, card Webhooks.
Features at a glance
- Web address: receiver of the entries. The note below it: "Receives each entry as JSON, signed with the site's webhook secret."
- Format: Funnelforms 3 (Pro) or Funnelforms 4 (Zaps and scenarios built on the online version).
- Signature with three headers: timestamp, signature and delivery ID.
- Up to three attempts per delivery.
- When (right away or after the payment) and For entries from (a certain contact step or Every contact step).
Step by step
- Open the form in the editor, click the contact step and then the After sending tab on the right.
- Under Add an action, choose Webhook.
- Enter the address of the receiver under Web address, starting with
https://. - Under Format, choose the format your receiver expects.
- Publish the form with Publish.
- Send a test entry and check at the receiver that the call arrives.
- To check the signature, open Funnelforms → Settings → Interfaces, card Webhooks, and copy the secret from the Webhook secret field.
- Store the secret at the receiver and check the signature as described below.
How it works
What is sent?
Funnelforms sends a POST call with JSON in the body and the headers Content-Type: application/json and Accept: application/json. The receiver has to answer within 15 seconds.
Format "Funnelforms 3 (Pro)" matches the webhook of Funnelforms 3. The JSON body contains, among others, these keys:
form_id,lead_id(the number of the entry) andlead_timestampanalytics_datawithquery_stringandurlquestions(question and answer),all_questions_by_id,all_question_datacontact_form(contact fields by variable name),all_contact_form_datahidden_fieldsandcalculationData
Format "Funnelforms 4" sends the payload of the online version of Funnelforms 4 with the same keys and types, so existing Zaps and scenarios keep working. The body contains timestamp, id, form, formFields, analytics, formResponseId, formResponsesByFieldId, formResponsesByWebhookFieldId and allQuestionData.
- Fields are named by their variable name, contact fields "field-" plus the name.
- Give fields the IDs they had in Funnelforms 4 as variable names, and existing Zaps keep working.
- Details that Funnelforms 5.0 does not store (IP address, screen size, browser settings) are
null.
How do I check the signature?
Every call carries these headers:
X-Funnelforms-Timestamp: Unix time of sending.X-Funnelforms-Signature:v1=plus the HMAC-SHA256 (hexadecimal) oftimestamp.bodywith the webhook secret of the website.X-Funnelforms-Delivery: number of the delivery. It stays the same for retries.
Example in PHP:
$body = file_get_contents( 'php://input' );
$timestamp = $_SERVER['HTTP_X_FUNNELFORMS_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_FUNNELFORMS_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac( 'sha256', $timestamp . '.' . $body, $secret );
if ( ! hash_equals( $expected, $signature ) ) {
http_response_code( 401 );
exit;
}
Use the unchanged body as it arrives. Also check that the timestamp is not too old, and remember the delivery number to detect duplicates. The secret is created on first use and starts with whsec_.
What happens on errors and retries?
Funnelforms only counts an answer with status 200 to 299 as success. For any other answer and for connection errors, it tries the call three times in total: again after one and after four minutes. After that the delivery is Failed with an error code such as http_500. The entry itself stays stored.
You see the deliveries in the entry under Sent to and in the list under Funnelforms → Settings → E-mail in the section Mails and deliveries. With Send again … in the entry you send the webhook once more; that is a new delivery with a new delivery number.
What happens when I renew the secret?
With Create a new secret, Funnelforms replaces the secret immediately and reports "Webhook secret renewed". Receivers that check the signature need the new secret afterwards.
What happens with double opt-in?
If the form uses double opt-in, the webhook waits until the visitor has confirmed the address.
Best Practices
- Check the signature and the timestamp on the receiver side.
- Answer quickly with status 200 and do longer steps in the background.
- Use the delivery number to detect duplicate calls.
- Give fields descriptive, fixed variable names, so mappings in the receiver do not change.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Action shows "Enter the web address that receives the entries." | The address is missing or not a complete web address. | Enter an address such as https://example.org/hook. |
Delivery is "Failed" with http_404, http_500 and similar codes | The receiver does not answer with 2xx. | Check the address and the receiver. Then send again from the entry. |
Error code starts with http_error: | Funnelforms could not reach the receiver, or it does not answer within 15 seconds. | Check that the address is reachable. |
| The signature does not match | Wrong secret, changed body, or a new secret was created. | Copy the current secret and check the unchanged body. |
| Zap or scenario finds no fields | Wrong format or different variable names. | Choose Funnelforms 4 (Zaps and scenarios built on the online version) and assign the former IDs as variable names. |
| The webhook does not arrive immediately | Deliveries run in the background. | See Mails do not arrive, section on WP-Cron. |
Tips
- You can test without a receiver of your own with a service that displays calls. Do not enter real customer data there.
- If you need polling with an access token instead of push calls, see Automation with access tokens.
FAQ
Can I set up several webhooks per form? Yes. Add the Webhook action several times, each with its own web address.
Is every call signed? Yes, always. Receivers that do not check keep working too, because the body stays unchanged.
How often does Funnelforms try? Three times per delivery, with pauses of one and four minutes.
Can I keep using a webhook from Funnelforms 3? Yes. The format "Funnelforms 3 (Pro)" matches the body of Funnelforms 3.
Are there webhooks in Funnelforms Free? No. If a form has a webhook and the website runs Free, Free does not run it; the entry shows it as "Skipped".