Webhooks
Receive automatic callbacks when requests are decided.
How webhooks work
When someone approves or rejects a request in your dashboard, we automatically POST the decision to your webhook URL. This lets your system know what happened and take action accordingly.
Setup
- Go to your project settings
- Add your webhook URL (must be HTTPS in production)
- Save
That’s it. We’ll start sending webhooks immediately.
Webhook payload
When a request is decided, we POST this JSON to your webhook URL:
{
"event": "request.decided",
"request_id": "req_abc123",
"external_id": "your-reference-id",
"title": "Brief description",
"status": "approved",
"decided_by_id": "user_xyz789",
"decision_note": "Looks good",
"decided_at": "2026-01-18T12:05:00Z",
"payload": {
"your": "original data"
}
}
Fields:
-
event- Always"request.decided"(more events may be added in future) -
request_id- The request ID -
external_id- Your reference ID (if you provided one) -
title- Request title -
status-"approved"or"rejected" -
decided_by_id- ID of user who made the decision -
decision_note- Optional note from the user -
decided_at- When the decision was made (ISO 8601) -
payload- Your original payload data
Responding to webhooks
Your endpoint should:
-
Return
200 OKstatus code - Respond within 10 seconds
- Process the webhook asynchronously if needed
Example response:
{
"received": true
}
The response body doesn’t matter - we only care about the status code.
Retries
If your webhook fails (non-200 status or timeout), we’ll retry:
- 1st retry: 30 seconds later
- 2nd retry: 5 minutes later
- 3rd retry: 30 minutes later
After 3 failed attempts, we give up. You can manually retry from the request detail page.
Security
Verify the source
Only accept webhooks from our IP addresses (coming soon).
Use HTTPS
Always use HTTPS for your webhook URL in production. We reject HTTP URLs outside of localhost.
Validate the payload
Check that the request_id exists in your system before processing.
Testing
Use our test server for local development, or tools like:
- webhook.site - Inspect webhook payloads
- ngrok - Expose localhost to the internet
Example implementations
Node.js / Express
app.post('/webhook', express.json(), async (req, res) => {
const { event, request_id, status, payload } = req.body;
if (event === 'request.decided') {
// Handle the decision
if (status === 'approved') {
await processRefund(payload);
}
}
res.json({ received: true });
});
Python / Flask
@app.route('/webhook', methods=['POST'])
def webhook():
data = request.json
if data['event'] == 'request.decided':
if data['status'] == 'approved':
process_refund(data['payload'])
return {'received': True}
Webhook logs
View webhook delivery status and retry history in the request detail page. You can see:
- Delivery status (pending, delivered, failed)
- Response status code
- Number of attempts
- Last error message
- Retry webhook manually