Skip to main content

Webhooks

Overview

Webhooks let you receive event data from Financely at an HTTPS endpoint you control. Configure them in Integrations → Automations → Webhooks.

Available events

Configuring a webhook

  1. Go to Integrations → Automations tab
  2. Click Add webhook
  3. Enter your endpoint URL (must be HTTPS)
  4. Select the events you want to receive
  5. Set the number of retries (0–5) for failed deliveries
  6. Click Save
Use Send test event to immediately fire a sample payload to your endpoint and verify delivery.

Request format

All webhook requests are:
  • Method: POST
  • Content-Type: application/json
  • Body: JSON payload (see schemas below)
  • Headers: include X-Financely-Signature for verification

Payload schemas

widget.submitted

widget.started

Signature verification

Every request includes an X-Financely-Signature header with the format sha256=<hex_digest>. The digest is an HMAC-SHA256 of the raw request body, keyed with your webhook secret.

Node.js

Python

Always verify the signature against the raw request body before parsing as JSON. Parsing and re-serializing will change byte order or whitespace and break the signature check.

Retry behaviour

If your endpoint does not respond with a 2xx HTTP status code within the timeout, Financely retries the delivery. Retries use a short delay between attempts.
Your endpoint must return a 2xx response as quickly as possible. For long-running processing, return 200 immediately and process the payload asynchronously.

Endpoint requirements

  • Must be HTTPS (HTTP endpoints are rejected)
  • Must return a 2xx status code
  • Must respond within the timeout window
  • Should be idempotent — retries may deliver the same event more than once

Troubleshooting

  1. Confirm your endpoint is publicly accessible over HTTPS
  2. Use Send test event in the Automations tab to test delivery manually
  3. Check that the widget generating submissions is Published
  4. Verify your endpoint returns a 2xx status code
Make sure you are hashing the raw bytes of the request body, not the parsed JSON. In Express, use express.raw() middleware. In Flask, use request.get_data().
Retries can deliver the same event more than once. Make your handler idempotent by checking the leadId or submittedAt field before processing.