Skip to Content

Webhooks

A webhook posts to a URL you provide whenever something happens. Use one when you want to react immediately — insert into a database, kick off a job, notify a channel — rather than pull on a schedule.

The Webhooks page under Settings, listing configured webhooks with their URL, the events they fire on, and their recent delivery health.
Settings → Webhooks. View deliveries shows every attempt with the response your endpoint gave.

Setting one up

Settings → Webhooks → Add webhook.

  • URL — must be reachable from the internet over HTTPS. Private and local addresses are refused.
  • Events — tick which of these to send.
  • Secret — optional but recommended. Used to sign every delivery so your endpoint can prove it came from us.
  • Headers — anything extra your endpoint needs, such as an API key of its own.

Use Send test event from the row menu to fire a sample at your endpoint and see the real response.

Events

EventWhen
submission.createda record is submitted for the first time
submission.updateda record’s answers change
submission.status_changedapproved, returned, or otherwise moved
submission.deleteda record is deleted
form.publisheda form is published
form.archiveda form is archived

A webhook fires for every form in the organisation. Filter on data.form_id at your end if you only want some.

What you receive

POST, JSON body, Content-Type: application/json:

{ "event": "submission.created", "timestamp": "2026-09-03T14:22:07.512Z", "organization_id": "…", "data": { "id": "…", "form_id": "…", "form_name": "Equipment Inspection", "data": { "asset": { "asset_id": "AST-1043", "…": "…" }, "inspected_on": "2026-09-03", "…": "…" }, "submitted_by": "…", "submitted_at": "2026-09-03T14:22:05.000Z", "location": { "latitude": -31.95, "longitude": 115.86 } } }

data.data is the record’s answers keyed by field key — the same shape as the API returns. submission.updated also carries previous_data; submission.status_changed carries previous_status and new_status.

Verifying a delivery

When a secret is set, every delivery carries X-Webhook-Signature: sha256=<hex> — an HMAC-SHA256 of the raw request body using your secret. Compute it over the exact bytes received, before any JSON parsing, and compare with a timing-safe function. Reject anything that does not match.

Retries

Your endpoint should answer 2xx quickly and do its work afterwards. Anything else, or no answer within the timeout, is retried: after 1 minute, then 5, 15, 1 hour and 4 hours. After the fifth failure the delivery is marked failed and shown as such under View deliveries, where it can be resent by hand.

Deliveries may occasionally arrive more than once. Use data.id to make your handling idempotent.

Reaching something that cannot receive a webhook? Ask us at customer.service@firedragontech.com. We will help you get the data where it needs to go.