Webhook Events¶
The system publishes events to webhook subscribers when business actions occur. Subscribers register endpoints and select which events to receive.
Event Types¶
| Event | Trigger | Key Payload Fields |
|---|---|---|
loan.created |
New loan created | loan_id, borrower_id |
loan.status_changed |
Loan status transition | loan_id, old_status, new_status |
loan.disbursed |
Loan funded | loan_id, amount |
payment.received |
Payment completed | payment_id, loan_id, amount |
payment.reversed |
Payment reversed | payment_id, loan_id |
payment.failed |
Payment processing failed | payment_id, loan_id, reason |
delinquency.changed |
DPD bucket transition | loan_id, old_bucket, new_bucket |
fee.assessed |
Fee assessed on loan | fee_id, loan_id, amount |
modification.completed |
Modification applied | modification_id, loan_id |
compliance.failed |
Compliance check failed | check_id, loan_id, rule |
document.generated |
Document generated | document_id, loan_id |
Payload Format¶
All webhook payloads follow a standard envelope:
{
"event_type": "payment.received",
"timestamp": "2026-01-15T14:30:00Z",
"tenant_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"payment_id": "123e4567-e89b-12d3-a456-426614174000",
"loan_id": "789e0123-e89b-12d3-a456-426614174000",
"amount": "500.00"
}
}
Subscription Management¶
WebhookSubscription Model¶
| Field | Description |
|---|---|
url |
HTTPS endpoint to deliver events to |
events |
Array of event types to subscribe to |
is_active |
Whether the subscription is active |
secret |
Shared secret for HMAC signature verification |
failed_attempts |
Consecutive failure count |
last_error |
Most recent error message |
last_delivered_at |
Timestamp of last successful delivery |
Security¶
HMAC Signature Verification¶
Every webhook delivery includes an HMAC-SHA256 signature in the request headers:
The signature is computed using the subscription's secret and the request body. Subscribers should verify the signature before processing the payload.
HTTPS Only¶
Webhook URLs must use HTTPS. HTTP URLs are rejected at subscription creation time.
Delivery¶
Retry Policy¶
Failed deliveries are retried with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 10 seconds |
| 2nd retry | 60 seconds |
| 3rd retry | 300 seconds (5 minutes) |
Maximum 3 retry attempts per delivery.
Dead-Letter Handling¶
Subscriptions are auto-disabled after 5 consecutive failures:
is_activeset toFalselast_errorrecords the final failure reason- Can be re-enabled via the API after the subscriber fixes their endpoint
Delivery Log¶
Every delivery attempt is recorded in WebhookDelivery:
| Field | Description |
|---|---|
subscription |
FK to subscription |
event_type |
Event type delivered |
payload |
Full payload sent |
response_status |
HTTP status code received |
response_body |
Response body (truncated) |
delivered_at |
Delivery timestamp |
See Also¶
- Cross-Module Communication --- How events are emitted