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

  1. Open the grantor in the CreditRisk portal and go to the Adaptors tab.
  2. In the Webhooks section click Add webhook.
  3. Enter a name, the callback URL and select the Triggers / Events you want to receive.
  4. 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, .internal and private IP ranges are rejected)

Events

EventSent when
account.approvedAn account application is approved
credit_insurance.requestedCredit insurance is requested for an account

Request Format

POST https://your-server.example.com/your-webhook-endpoint
HeaderDescription
Content-Typeapplication/json
X-Webhook-EventThe event key, e.g. account.approved
X-Webhook-IdUnique id of the delivery — use it to ignore duplicates
X-Signaturesha256= 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 2xx status 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.