Guides
Webhooks
Integrate with CreditRisk endpoints using clear request and response examples.
Webhooks
Webhooks let CreditRisk notify your system with a signed HTTPS request as soon as an event happens, so you don't need to poll the API.
Overview
When a subscribed event occurs for a grantor, CreditRisk sends an HTTP POST with a JSON body to the URL you registered. Your endpoint should verify the signature, respond quickly with a 2xx status, and process the event asynchronously.
Setting Up a Webhook
- Open the grantor in the CreditRisk portal and go to the Adaptors tab.
- In the Webhooks section click Add webhook.
- Enter a name, the callback URL and select the Triggers / Events you want to receive.
- Save. A signing secret (starting with
whsec_) is generated for the webhook — use it to verify signatures.
URL requirements:
- Must use
https:// - Must be publicly reachable (localhost,
.local,.internaland private IP ranges are rejected)
Events
| Event | Sent when |
|---|---|
account.approved | An account application is approved |
credit_insurance.requested | Credit insurance is requested for an account |
Request Format
POST
https://your-server.example.com/your-webhook-endpoint
| Header | Description |
|---|---|
Content-Type | application/json |
X-Webhook-Event | The event key, e.g. account.approved |
X-Webhook-Id | Unique id of the delivery — use it to ignore duplicates |
X-Signature | sha256= followed by the HMAC-SHA256 of the raw request body |
Payloads
Every payload has the same envelope. The data object depends on the event.
account.approved
{
"id": "evt_123456",
"event": "account.approved",
"created_at": "2026-11-07 11:30:00",
"grantor_id": 7,
"data": {
"account_id": 12345,
"sync_id": "ACC-001",
"account_name": "Example Trading (Pty) Ltd"
}
}
credit_insurance.requested
{
"id": "evt_123457",
"event": "credit_insurance.requested",
"created_at": "2026-11-07 11:35:00",
"grantor_id": 7,
"data": {
"account_id": 12345,
"sync_id": "ACC-001",
"account_name": "Example Trading (Pty) Ltd"
}
}
Use account_id or sync_id with the Accounts API to fetch the full account.
Verifying Signatures
Compute an HMAC-SHA256 of the raw request body using your webhook's signing secret and compare it with the X-Signature header using a constant-time comparison. Reject the request if they don't match.
PHP
$payload = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
$received = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
if (!hash_equals($expected, $received)) {
http_response_code(401);
exit;
}
http_response_code(200);
Node.js
const crypto = require('crypto');
function isValid(rawBody, signatureHeader, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(signatureHeader || '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Responses & Retries
- Respond with any
2xxstatus within a few seconds to acknowledge the delivery. - Any other status, or a timeout, is treated as a failure and the delivery is retried with increasing delays.
- Deliveries may be repeated, so make your handler idempotent using
X-Webhook-Id. - Keep your signing secret private. If it is exposed, edit the webhook in the portal to generate a new one.