This article walks you through enabling webhooks, creating a configuration, and the options available to you.
Note: Webhooks are a self-service feature. You'll need an API key to use them — if you haven't generated one yet, see Generating an API key in the Settings area.
Before you start
You'll need:
Admin access to the Legl platform.
A receiving endpoint — a publicly accessible HTTPS URL on your side that can accept JSON
POSTrequests and respond with a2xxstatus.A Legl API key for your firm. The same token is used to sign each webhook payload, so your endpoint can verify the request really came from us.
Where to find webhook settings
Go to Settings → Integrations.
Scroll to the Webhooks section.
Click Add to create your first webhook configuration. You can have as many configurations as you need (for example, one for staging and one for production, or different endpoints per event family).
Creating a webhook
When you click Add, you'll see the following options:
Name (required)
A short label so you can recognise the configuration later — e.g. Production Engage events or Disbursements – staging. It's only used inside Legl and isn't sent in the payload. There must be no spaces in the name.
Webhook URL (required)
The HTTPS endpoint we'll send events to. It must:
Be reachable from the public internet.
Use HTTPS.
Respond with a
2xxstatus code within the delivery timeout (see below).
Event types
Tick each event you want this URL to receive. The full list is below — you can mix and match across products in a single configuration, or split them across multiple webhooks.
Active
A toggle that lets you pause delivery without deleting the configuration. When Active is off, no events will be sent to this URL, but the configuration and history are preserved. Useful while you're rolling out changes on your side.
Allowlist header value (optional)
If your firewall, WAF, or middleware needs an additional shared secret to allow the request through, paste a token here. Legl will include it on every request as the header:
X-Legl-Webhook-Token: <your token>
This is a simple shared-secret check; it does not replace verifying the Legl-Signature header (see Verifying webhook authenticity below).
Available events
You can subscribe to any combination of the events below. Each event has a stable identifier (used in the payload as event_type) and a human-readable name (shown in the settings UI).
Engage
Event | Fires when |
| The client has completed and submitted all steps of an Engage request. |
| All processes are complete and the request is ready for a fee earner to review. |
| A user has reviewed the Engage request. |
| A signer has signed a document via the e-signature step (fires once per signer). |
Businesses & company reports
Event | Fires when |
| A new business is created. |
| An entity is created. |
| An entity is updated. |
| A company report PDF has been generated. |
Risk assessments
Event | Fires when |
| A new risk assessment is created. |
| A risk assessment has been completed. |
| The PDF for a completed risk assessment is ready to download. |
| An assessment is manually closed (e.g. the client stopped instructing). |
| A previously closed assessment is reopened. |
Sanctions & monitoring
Event | Fires when |
| A business sanctions report is ready for review. |
| A business sanctions report has been reviewed and is ready as a PDF. |
| Business sanctions monitoring is disabled. |
| A business sanctions monitoring alert moves between action required and no action. |
| Business report monitoring is disabled. |
| A business report monitoring alert moves between action required and no action. |
| Individual watchlist monitoring is disabled. |
| An individual watchlist monitoring alert moves between action required and no action. |
For the exact payload structure of each event, see our API reference — every event has a dedicated schema documenting each field.
See our implementation materials on our Postman page for more details if needed.
What a webhook delivery looks like
Every event is wrapped in the same envelope so your endpoint can route on event_type and use uuid for idempotency:
{
"uuid": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
"event_type": "engage_request_reviewed",
"version": 1,
"created_at": "2026-05-05T14:32:11Z",
"data": {
"...": "event-specific payload"
}
}
Headers we send:
Header | Purpose |
| Body format. |
| HMAC-SHA256 signature of the JSON body — see below. |
| Only sent if you configured an Allowlist header value. |
Verifying webhook authenticity
We sign every payload so you can confirm it really came from Legl. The Legl-Signature header is the HMAC-SHA256 of the raw JSON body, using your Legl API key as the secret.
Pseudocode:
expected = hmac_sha256(api_key, raw_request_body).hex()
if not constant_time_compare(expected, request.headers["Legl-Signature"]):
reject(401)
Important:
Compute the HMAC against the raw request body before any JSON re-serialisation — re-encoding can change whitespace and break the signature.
Always use a constant-time comparison (e.g.
hmac.compare_digestin Python,crypto.timingSafeEqualin Node).If you rotate your API key, the signing key rotates with it — update both ends together.
Responding to a webhook
Reply with any
2xxstatus code as soon as you've received the event. We treat that as success.Do your heavy work asynchronously — long-running processing should happen after you've responded, otherwise you risk the timeout.
Use the
uuidfield to deduplicate. The sameuuidis reused across retries, so you can safely ignore one you've already processed.
Retries
If your endpoint returns a 4xx or 5xx, times out, or is unreachable, Legl will retry the delivery up to 5 times with exponential back-off. After that the message is marked failed and won't be re-sent automatically.
Testing your webhook
Once you've saved a configuration, click Test webhook address next to it. Legl will send a small signed test payload ({"test": "data"}) to your URL and report back whether the request succeeded.
A successful test confirms:
Your URL is reachable from Legl.
TLS is set up correctly.
Your firewall / allowlist accepts our request.
(If configured) the
X-Legl-Webhook-Tokenheader is being sent as expected.
It does not verify your Legl-Signature validation logic — for that, we recommend triggering a real low-stakes event (e.g. submit a sandbox Engage request) and checking your server logs.
Editing or removing a webhook
Edit any field at any time — changes take effect on the next event.
Pause by toggling Active off. Events fired while paused are not queued for later delivery.
Remove to delete the configuration entirely.
Troubleshooting
Symptom | Common cause |
Test request succeeds but real events never arrive | The configuration is inactive, or no event types are ticked. |
All deliveries fail with timeouts | Endpoint is too slow — move processing to a background job and respond |
| You're hashing the parsed/re-serialised JSON instead of the raw request body. |
Requests blocked by your firewall | Add the Allowlist header value, or get in touch with our support team about other allowlisting options. |
Duplicate events | Expected on retries — dedupe on |
Delivery timeouts | Legl will wait for your endpoint to respond before treating the delivery as failed and queuing a retry. This wait defaults to 5 seconds. |
Need help?
Drop us a message via Live Chat (bottom right of your screen) or email [email protected] and we'll be happy to help you wire things up.


