Overview
eFICA delivers real-time event notifications to external systems via outgoing webhooks.
How it works
When a key event occurs in eFICA, an HTTP POST request is sent to your configured endpoint with a signed JSON payload. This eliminates the need to poll the API for changes.
Supported application types
- Individual — Webhook events for individual FICA applications
- Entity — Webhook events for entity applications
- Trust — Webhook events for trust applications (Under Development)
- Customer Portal — Webhook events for customer portal onboarding flows (Individual Only)
Delivery behaviour
Timeouts and retries
eFICA expects a 2xx response within 10 seconds. If the endpoint does not respond
in time, or returns a retryable status code, the delivery is retried on an exponential
back-off schedule:
| Attempt | Delay after previous |
|---|---|
| 1 | Immediate (async) |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 15 minutes |
| 5 | 60 minutes |
| 6 | 6 hours |
| 7 | 24 hours |
Total window: approximately 31 hours. After attempt 7, the delivery is marked
failed-final and retries stop.
| Response | Behaviour |
|---|---|
2xx | Delivery marked successful |
408, 429, 500–599 | Retryable — follows schedule above |
400–499 (excl. 408, 429) | Non-retryable — marked failed-final immediately |
Idempotency
Deliveries are at-least-once — retries and replays can result in your endpoint
receiving the same event more than once. Use the X-Efica-Event-Id header to
deduplicate.
Audit trail
All delivery attempts are logged in eFICA, including timestamp, HTTP status, and response time.
Signature verification
Every delivery is signed using HMAC-SHA256. You should verify the signature before processing any payload.
Headers
| Header | Description |
|---|---|
X-Efica-Signature | t=<unixSeconds>,v1=<hexHmac> |
X-Efica-Event-Id | Unique event identifier |
X-Efica-Event-Type | The event type string |
User-Agent | efica-webhooks/2.0 |
Verifying the signature
- Extract
tandv1from theX-Efica-Signatureheader. - Reject the request if
tdiffers from the current Unix time by more than 300 seconds (5 minutes). This prevents replay attacks. - Construct the signed string:
"<t>.<rawBody>"— use the exact raw request body, before any parsing. - Compute
HMAC-SHA256(webhookSecret, signedString)and hex-encode it. - Compare your result to
v1using a constant-time comparison to prevent timing attacks.
The raw body must be used as-is — do not parse and re-serialise the JSON before verifying, as whitespace differences will cause the signature check to fail.
Example (Node.js)
const crypto = require('crypto');
function verifyWebhook(secret, rawBody, signatureHeader) {
const [tPart, v1Part] = signatureHeader.split(',');
const t = tPart.replace('t=', '');
const v1 = v1Part.replace('v1=', '');
const age = Math.abs(Date.now() / 1000 - Number(t));
if (age > 300) throw new Error('Timestamp too old — possible replay attack');
const signed = `${t}.${rawBody}`;
const expected = crypto
.createHmac('sha256', secret)
.update(signed)
.digest('hex');
const valid = crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(v1)
);
if (!valid) throw new Error('Invalid signature');
}
Document history
| Version | Date | Notes |
|---|---|---|
| 1.0 | 2026-05-26 | Initial release |
Support
For technical support and questions:
- Email: melissa@efica.co.za
- Melissa will co-ordinate with the development team.
This documentation is maintained by the eFICA development team. For updates and corrections, please contact your account manager.
Last Updated: 26 May 2026