With webhooks, you can instantly send information to another app or URL after a trigger, like a Tally form submission. This instant notification lets you build automated workflows to take action on form entries.
Webhooks are available for free to all Tally users.

How it worksAdd a webhookEndpoint URLAdd a signing secretAdd HTTP headersRequest failure and retriesManage webhooksExample webhook eventWhy people use the Webhook integration
If you're instead looking for a non-technical way to sync Tally form submissions with other apps, check out our Zapier, Make, Pipedream or Integrately integrations.
How it works
Webhooks send notifications to a specified URL when triggered by an event. The event trigger is a new form submission. When someone submits a Tally form, a notification containing the response data gets sent to your URL in JSON format via a POST request.
Add a webhook
Publish your form and go to the
Integrations tab. Click Connect to Webhooks.
You’ll be prompted to configure your webhook endpoint.

Endpoint URL
For the endpoint URL, set up an HTTP or HTTPS endpoint that can accept webhook requests with a POST method:
- Handles POST requests with a JSON payload
- Returns a successful status code (2XX) within 10 seconds
A webhook endpoint has a 10-second timeout to process and respond to a new submission. If the processing takes longer, it's advisable to call another service internally.
This enables the endpoint to swiftly send a successful status code to Tally. The separate service can then handle the processing of the submission without delaying the webhook response.
Add a signing secret
You can secure your webhook by using a signing secret to verify that Tally generated a webhook request and that it didn’t come from a server acting like Tally.
When this option is enabled, the webhook requests will contain a
Tally-Signature header. The value of this header is a SHA256 cryptographic hash of the webhook payload. Express.js example
const app = express(); app.use(express.json()); app.post('/webhook', (req, res) => { const webhookPayload = req.body; const receivedSignature = req.headers['tally-signature']; // Replace 'YOUR_SIGNING_SECRET' with your signing secret const yourSigningSecret = 'YOUR_SIGNING_SECRET'; // Calculate the signature using the signing secret and the payload const calculatedSignature = createHmac('sha256', yourSigningSecret) .update(JSON.stringify(webhookPayload)) .digest('base64'); // Compare the received signature with the calculated signature if (receivedSignature === calculatedSignature) { // Signature is valid, process the webhook payload res.status(200).send('Webhook received and processed successfully.'); } else { // Signature is invalid, reject the webhook request res.status(401).send('Invalid signature.'); } }); app.listen(3000, () => console.log('Server is running on port 3000'));
Add HTTP headers
You can optionally configure custom HTTP headers that will be sent with each webhook request. Click
Add HTTP headers and enter the header name and value. 
Request failure and retries
If a webhook endpoint fails to return a successful status code (2XX) within a 10-second window, we employ a retry mechanism to attempt delivery of the submission. Here is the sequence of retries:
- The first retry occurs after 5 minutes
- If the first retry fails, the second retry is scheduled after 30 minutes
- If the second retry fails, the third retry is scheduled after 1 hour
- If the third retry fails, the fourth retry is scheduled after 6 hours
- If the fourth retry fails, the fifth retry is scheduled after 1 day
Manage webhooks
You will see the active webhook URLs in your published form dashboard. You can connect unlimited webhook URLs and pause them by clicking the toggle.

Click
🕔 next to your active webhook to see the events log. This log contains all requests made to your webhook endpoint. 
Click
🖊 to edit or 🗑 to remove the webhook.If the webhook is created from an integration, then you can only remove the webhook in the integration where you originally created it.

Example webhook event
This example event contains every type of field that Tally supports. You can also use this free tool to test the requests to your webhook endpoint.
POST /[webhook_url] HTTP/1.1 User-Agent: Tally Webhooks Content-Type: application/json
{ "eventId": "a4cb511e-d513-4fa5-baee-b815d718dfd1", "eventType": "FORM_RESPONSE", "createdAt": "2023-06-28T15:00:21.889Z", "data": { "responseId": "2wgx4n", "submissionId": "2wgx4n", "respondentId": "dwQKYm", "formId": "VwbNEw", "formName": "Webhook payload", "createdAt": "2023-06-28T15:00:21.000Z", "fields": [ { "key": "question_mVGEg3_8b5711e3-f6a2-4e25-9e68-5d730598c681", "label": "utm_campaign", "type": "HIDDEN_FIELDS", "value": "newsletter" }, { "key": "question_nPpjVn_84b69d73-0a85-4577-89f4-8632632cc222", "label": "Score", "type": "CALCULATED_FIELDS", "value": 20 }, { "key": "question_nPpjVn_d8ad6961-4931-4737-b814-dda344f64391", "label": "Type", "type": "CALCULATED_FIELDS", "value": "Hard" }, { "key": "question_3EKz4n", "label": "Text", "type": "INPUT_TEXT", "value": "Hello" }, { "key": "question_nr5yNw", "label": "Number", "type": "INPUT_NUMBER", "value": 10 }, { "key": "question_w4Q4Xn", "label": "Email", "type": "INPUT_EMAIL", "value": "[email protected]" }, { "key": "question_3jZaa3", "label": "Phone number", "type": "INPUT_PHONE_NUMBER", "value": "+32491223344" }, { "key": "question_w2XEjm", "label": "Website", "type": "INPUT_LINK", "value": "example.com" }, { "key": "question_3xrXrn", "label": "Date", "type": "INPUT_DATE", "value": "2023-06-28" }, { "key": "question_mZ8jow", "label": "Time", "type": "INPUT_TIME", "value": "12:00" }, { "key": "question_3Nrpl3", "label": "Long text", "type": "TEXTAREA", "value": "Hello world" }, { "key": "question_3qL4Gm", "label": "Multiple choice", "type": "MULTIPLE_CHOICE", "value": [ "e7bfbbc6-c2e6-4821-8670-72ed1cb31cd5" ], "options": [ { "id": "ec321dc4-b50d-4270-8df0-0e38c898762a", "text": "Not started" }, { "id": "e7bfbbc6-c2e6-4821-8670-72ed1cb31cd5", "text": "In progress" }, { "id": "2ff233ad-ad78-42ee-b51f-57b54a55bd3e", "text": "Done" }, { "id": "3f378bb3-30e2-4e55-a30c-c2b28fe0d9db", "text": "Blocked" } ] }, { "key": "question_wQ1K7w", "label": "Checkboxes", "type": "CHECKBOXES", "value": [ "cb33303b-4e9d-4bb3-8b51-f16acbf573fe", "b42d4e8c-bdb6-4c82-b749-906706c251ff" ], "options": [ { "id": "9bbb6bd7-1e3b-4e48-b4b9-a221d5aad87e", "text": "Soccer" }, { "id": "cb33303b-4e9d-4bb3-8b51-f16acbf573fe", "text": "Swimming" }, { "id": "b42d4e8c-bdb6-4c82-b749-906706c251ff", "text": "Skiing" } ] }, { "key": "question_wQ1K7w_9bbb6bd7-1e3b-4e48-b4b9-a221d5aad87e", "label": "Checkboxes (Soccer)", "type": "CHECKBOXES", "value": false }, { "key": "question_wQ1K7w_cb33303b-4e9d-4bb3-8b51-f16acbf573fe", "label": "Checkboxes (Swimming)", "type": "CHECKBOXES", "value": true }, { "key": "question_wQ1K7w_b42d4e8c-bdb6-4c82-b749-906706c251ff", "label": "Checkboxes (Skiing)", "type": "CHECKBOXES", "value": true }, { "key": "question_n9BqQm", "label": "Dropdown", "type": "DROPDOWN", "value": [ "6010d529-62a5-484d-bb03-dcbcbfc76f0b" ], "options": [ { "id": "260c201f-1c52-4f2d-af88-78f21576bc46", "text": "Easy" }, { "id": "6010d529-62a5-484d-bb03-dcbcbfc76f0b", "text": "Hard" } ] }, { "key": "question_meMqem", "label": "Multi-select", "type": "MULTI_SELECT", "value": [ "00a9c1c2-ff96-43d1-8d68-2e109f689680", "f75280b0-4311-42dd-8542-e76b54b2ad15" ], "options": [ { "id": "f75280b0-4311-42dd-8542-e76b54b2ad15", "text": "Golf" }, { "id": "00a9c1c2-ff96-43d1-8d68-2e109f689680", "text": "Surf" }, { "id": "08cf2b34-5cd3-483a-9ec7-af08f8fe11da", "text": "Climbing" } ] }, { "key": "question_nW2ONw", "label": "File upload", "type": "FILE_UPLOAD", "value": [ { "id": "5mDNqw", "name": "Tally_Icon.png", "url": "https://storage.googleapis.com/tally-response-assets-dev/vBXMXN/34fd1ee5-4ead-4929-9a4a-918ac9f0b416/Tally_Icon.png", "mimeType": "image/png", "size": 16233 } ] }, { "key": "question_wa9QBw_price", "label": "Payment (price)", "type": "PAYMENT", "value": 9 }, { "key": "question_wa9QBw_currency", "label": "Payment (currency)", "type": "PAYMENT", "value": "USD" }, { "key": "question_wa9QBw_name", "label": "Payment (name)", "type": "PAYMENT", "value": "Alice Smith" }, { "key": "question_wa9QBw_email", "label": "Payment (email)", "type": "PAYMENT", "value": "[email protected]" }, { "key": "question_wa9QBw_link", "label": "Payment (link)", "type": "PAYMENT", "value": "https://dashboard.stripe.com/payments/[PAYMENT_ID]" }, { "key": "question_m6L8kw", "label": "Rating", "type": "RATING", "value": 4 }, { "key": "question_w7qRZm", "label": "Ranking", "type": "RANKING", "value": [ "79dbe95e-a895-4f0a-9e07-9865ddf4e4c5", "79597316-9ac4-4267-bb6f-1950fb5d1b7e", "58745e02-3e10-4b0e-bf6b-f6901caf7068" ], "options": [ { "id": "79597316-9ac4-4267-bb6f-1950fb5d1b7e", "text": "Apple" }, { "id": "79dbe95e-a895-4f0a-9e07-9865ddf4e4c5", "text": "Pear" }, { "id": "58745e02-3e10-4b0e-bf6b-f6901caf7068", "text": "Banana" } ] }, { "key": "question_wbq5L3", "label": "Linear scale", "type": "LINEAR_SCALE", "value": 7 }, { "key": "question_wAz7Dn", "label": "Signature", "type": "SIGNATURE", "value": [ { "id": "63lyBw", "name": "ca8f2e11-f99a-4042-b872-0888811b8118.png", "url": "https://storage.googleapis.com/tally-response-assets-dev/vBXMXN/signatures/ca8f2e11-f99a-4042-b872-0888811b8118.png", "mimeType": "image/png", "size": 7646 } ] }, { "key": "question_mBazQn", "label": "Matrix", "type": "MATRIX", "value": { "98618291-f36d-4743-9393-b67bca0d1ef2": [ "77be6b60-3b56-4db0-b39b-deb2d8243ea1" ], "53c86017-bdd4-4a41-b501-4f389dfec300": [ "dcdfcafd-d544-4d5b-b50b-8d3b41a240ea" ] }, "rows": [ { "id": "98618291-f36d-4743-9393-b67bca0d1ef2", "text": "Quality" }, { "id": "53c86017-bdd4-4a41-b501-4f389dfec300", "text": "Speed" } ], "columns": [ { "id": "cf0a72b5-5b7b-4068-9eff-3e03eed58100", "text": "Unsatisfied" }, { "id": "dcdfcafd-d544-4d5b-b50b-8d3b41a240ea", "text": "Neutral" }, { "id": "77be6b60-3b56-4db0-b39b-deb2d8243ea1", "text": "Satisfied" } ] } ] } }
Why people use the Webhook integration
People use the Webhook integration when they want Tally to talk to anything, not just the tools that have a native integration. A webhook lets you send every form submission as structured JSON to any HTTP endpoint in real time. That could be your own backend, a custom internal tool, a low code automation platform or a niche SaaS that is critical to your stack.
Instead of polling the Tally API or exporting CSVs, webhooks push data the moment a form is submitted. This is more efficient, avoids running into API rate limits and gives you near instant reactions to what people submit.
Teams also use webhooks when they outgrow one click integrations and need very specific workflows. A Tally form can trigger automation platforms like Make, Zapier or n8n, which then route the data to CRMs, billing tools, internal databases or messaging apps. In most of these setups, the first step is simply a webhook that catches new Tally responses and kicks off the rest of the scenario.
On the more technical side, the Webhook integration is popular with developers who care about reliability and security. Tally can sign each webhook request with a SHA256 signature so you can verify that the payload really came from Tally before you process it. You can list delivery events, inspect responses and retry failed webhook attempts, which makes production workflows much easier to monitor and debug.
In practice, people reach for the Webhook integration when they want to:
- Push submissions into their own database or data warehouse
- Sync leads to a custom CRM or internal admin panel
- Trigger complex multi step automations that go beyond native integrations
- Generate PDFs, contracts or reports from form responses
- Power real time notifications or decision flows in their own applications
So the Webhook integration is the choice for anyone who wants Tally to plug into a custom stack. It turns every form submission into a real time event your systems can react to, without waiting for new native integrations or changing the tools you already use.