Skip to main content

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:

AttemptDelay after previous
1Immediate (async)
21 minute
35 minutes
415 minutes
560 minutes
66 hours
724 hours

Total window: approximately 31 hours. After attempt 7, the delivery is marked failed-final and retries stop.

ResponseBehaviour
2xxDelivery marked successful
408, 429, 500–599Retryable — 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

HeaderDescription
X-Efica-Signaturet=<unixSeconds>,v1=<hexHmac>
X-Efica-Event-IdUnique event identifier
X-Efica-Event-TypeThe event type string
User-Agentefica-webhooks/2.0

Verifying the signature

  1. Extract t and v1 from the X-Efica-Signature header.
  2. Reject the request if t differs from the current Unix time by more than 300 seconds (5 minutes). This prevents replay attacks.
  3. Construct the signed string: "<t>.<rawBody>" — use the exact raw request body, before any parsing.
  4. Compute HMAC-SHA256(webhookSecret, signedString) and hex-encode it.
  5. Compare your result to v1 using 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

VersionDateNotes
1.02026-05-26Initial release

Support

For technical support and questions:


This documentation is maintained by the eFICA development team. For updates and corrections, please contact your account manager.

Last Updated: 26 May 2026