Webhooks
With webhooks, you can instantly send information to another app or URL after a trigger, like a Formware form submission. This instant notification lets you design automated workflows to apply custom logic on form responses within your own private cloud computing environment.
Webhooks are available for free to all Formware users.
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 form, a notification containing the form responses gets sent to your URL in JSON format via a POST request.
Add a webhook
Adding a webhook via the UI will be enabled soon. If this is an urgent requirement, please Contact Support.
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
Request Timeout
A webhook endpoint URL has a 10-second request timeout to process and respond to a new submission. If synchronous processing takes longer, it's advisable to log the request data and process it asynchronously in a separate thread.
This enables the endpoint URL to promptly respond with a successful status code to Formware. The async service can then handle the processing of the submission without delaying the webhook response.
Add a signing secret (Optional)
You can secure your webhook by using a signing secret to verify that Fromware generated a webhook request and that it didn’t come from a server acting like Formware.
When this option is enabled, the webhook requests will contain a Formware-Signature header. The value of this header is a SHA256 cryptographic hash of the webhook payload.
Python FastAPI Example
from fastapi import FastAPI,Request,HTTPException
import hashlib
import hmac
import base64
import os
app = FastAPI()
@app.post("/webhook")
async def recWebHook(req: Request):
raw = await req.body()
receivedSignature = req.headers.get("formware-signature")
if receivedSignature is None:
return HTTPException(403, detail="Permission denied.")
sha_name, signature = receivedSignature.split('=', 1)
if sha_name != 'sha256':
return HTTPException(501, detail="Operation not supported.")
is_valid = verifySignature(signature, raw)
if(is_valid != True):
return HTTPException(403, detail="Invalid signature. Permission Denied.")
# Do something with the payload received
return {"Message": "Webhook well received"}
def verifySignature(receivedSignature: str, payload):
WEBHOOK_SECRET = os.environ.get('FORMWARE_SECRET_KEY')
digest = hmac.new(WEBHOOK_SECRET.encode('utf-8'), payload, hashlib.sha256).digest()
e = base64.b64encode(digest).decode()
if(e == receivedSignature):
return True
return False
Request failure and retries
Webhook retries will be enabled soon. If this is an urgent requirement, please Contact Support.
Example webhook event
The webhook event has the following keys:
event_id: Unique id for the form responseevent_type: Type of event (eg.form_response)sent_at: timestamp of the webhook requestanswers: A map of field ids as key and the answer as value.fields: an ordered list of fields containing the field id, field type and title. This is the order in which the questions had been asked in the form filled by respondents.
Sample request payload
POST /[endpoint_url] HTTP/1.1
User-Agent: Formware Webhooks
Content-Type: application/json
Formware-Signature: sha256=...
{
"event_id": "68ecc910636199413b7f8bd6",
"event_type": "form_response",
"sent_at": "2025-08-25T15:10:32.552718587+05:30",
"answers": {
"3b8c1343-e457-4945-bd09-8e529e4fb012": {
"value": "https://dummy.com"
},
"476604aa-ef34-4891-b88a-4f9b5e1baa2f": {
"value": "+449998887777",
"metadata": {
"country_code": "GB"
}
},
...
},
"fields": [
{
"block_id": "476604aa-ef34-4891-b88a-4f9b5e1baa2f",
"block_type": "Phone Number",
"title": "Phone number?"
},
{
"block_id": "3b8c1343-e457-4945-bd09-8e529e4fb012",
"block_type": "Website",
"title": "What is your website?"
},
...
]
}