Skip to content

Webhooks

Webhooks let you send form submission data to your own server or application in real time. This makes it easy to automate workflows, trigger custom logic, or integrate Formware with your internal systems.

When someone submits your form, Formware sends a POST request to your webhook URL with the submission data in JSON format.

Each request includes:

  • Form responses (answers)
  • Field metadata (fields)
  • Event details (ID, type, timestamp)

You can use this data to trigger actions like:

  • Storing responses in your database
  • Sending data to a CRM
  • Running custom business logic

To receive webhook events, you’ll need an endpoint that:

  • Accepts HTTP POST requests
  • Parses a JSON payload
  • Returns a 2XX status code within 10 seconds

Webhook setup via the UI will be available soon.

If you need access right away, please please Contact Support.

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 enabled, each request includes a Formware-Signature header:

Formware-Signature: sha256=...

This is a SHA256 hash of the request payload. You can validate it on your server before processing the data.

Example: Verify signature (Python / FastAPI)

Section titled “Example: Verify signature (Python / FastAPI)”
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

Automatic retries are not yet available. If this is critical for your use case, please Contact Support.

Each webhook event includes the following fields:

  • event_id — Unique ID for the submission
  • event_type — Event type (e.g. form_response)
  • sent_at — Timestamp of the request
  • answers — Map of field IDs to submitted values
  • 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.
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?"
},
...
]
}