Individual Webhooks — Integration Guide
This document describes all webhook event types related to natural-person (individual) FICA in eFICA: the main individual record and individual documents. It is written for business analysts (what happens, when, and why) and mid-level developers (payloads, routing, and implementation notes).
1. Overview (business)
What these webhooks do
External systems (for example a partner CRM or case-management platform) can subscribe to individual-related events so they stay aligned with eFICA when:
- A new individual FICA application is opened
- An existing individual is updated through the FICA workflow (risk, verification, onboarding decision, and so on)
- Documents are uploaded or removed on an individual application
How delivery works
- An action in eFICA (UI or public API) verifies if your subscription has the
eventTypeand is enabled. - If enabled, a delivery is queued to your URL.
- A background job POSTs the JSON payload to your endpoint (typically within seconds).
- Delivery is at-least-once: retries may cause duplicates; use
eventIdto deduplicate.
Events are only stored when at least one enabled subscription includes that event type. If nothing is subscribed, no row appears in Webhook Events.
Where to configure subscriptions
- eFICA UI: eFIca Settings → Integrations → Webhooks (create or edit a subscription, select event types under Individual).
Event catalogue (individual FICA domain)
| Event type | Business meaning | Typical trigger |
|---|---|---|
individual.created | New individual FICA record created | Create individual (dashboard or public API) |
individual.updated | Individual record or workflow step changed | Step 2 verification, profile saves, AML refresh, onboarding decision, API updates |
individual.document.created | Individual document uploaded | Document upload (dashboard or public API) |
individual.document.deleted | Individual document soft-deleted | Document delete (dashboard or public API) |
2. Shared concepts (business + technical)
Identifiers you must understand
| Field | Meaning | Who sets it |
|---|---|---|
eFICA Individual UUID (sourceId on record events, individualId on document events) | Stable primary key for the individual in eFICA | eFICA on individual create |
Client reference (data.clientRef) | Partner’s own reference for this application (CRM case ID, policy number, and so on) | Partner user or integration |
External user ID (data.externalUserID) | Optional third-party user identifier stored on the individual | Partner integration |
Onboarding ID (onboardingId on envelope, when present) | Links the individual to a customer portal onboarding row | eFICA when created from portal |
External ID (externalID on envelope, when present) | Portal routing identifier from the onboarding record (not the same as clientRef) | Set on customer portal onboarding or by API |
Individual document ID (individualDocID) | Stable key for a uploaded document row (individualDocID) | eFICA on upload |
| eventId | Unique ID for this webhook occurrence | eFICA (UUID) — use for idempotency |
Routing rules (important for integrations)
| Event | sourceId | externalID on envelope | When event is skipped |
|---|---|---|---|
individual.created | Individual UUID | Always null | Missing partner or individual UUID |
individual.updated | Individual UUID | Portal externalID when individual has onboardingID; otherwise null | Missing partner or individual UUID |
individual.document.* | Individual UUID | clientRef (clientReference on record) if set; otherwise null | Missing partner or individual UUID |
Business implication:
- Use
individual.createdwithsourceIdto create the external record when a desk user or API opens a new FICA file. - Use
individual.updatedto keep that record in sync; you do not need a portal onboarding link for updates to fire. - When the individual came from the customer portal,
externalIDandonboardingIdonindividual.updatedhelp you match the portal application. - For documents, prefer
individualId+individualDocID; useexternalIDonly when you already map documents by client reference.
Admin user fields
Fields such as adminAdded, adminUpdated, uploadAdminId, and deleteAdminId are eFICA user UUIDs (not numeric user IDs), resolved from internal user records.
Screening and validation JSON
| Payload field | Description |
|---|---|
amlScreeningResults | AML / sanctions screening summary. Treat as structured JSON; only depend on keys your integration documents. |
consumerDetail, kycResult | Identity / bureau validation payloads when stored on the individual (may be null until verification runs). |
faceMatchResult, faceMatchImageDocURL | Biometric face-match summary and optional stored image reference when applicable. |
customQuestions | Partner custom form answers (JSON), when configured. |
Do not assume fixed schemas inside these objects unless your integration explicitly documents them.
Payload envelope (all events)
Every delivery body is JSON with:
{
"schemaVersion": 1,
"eventId": "<uuid>",
"eventType": "<event.type>",
"occurredAt": "<ISO-8601 UTC>",
"sourceEntity": "<source code>",
"sourceId": "<primary routing id>",
"externalID": "<optional>",
"data": { }
}
Document events also include top-level individualId and individualDocID. individual.updated may include onboardingId when linked to a portal onboarding.
3. Individual record events
3.1 individual.created
When it fires
- A new individual FICA record is created in the dashboard (new application wizard).
- A new individual is created via the public API create-individual endpoint.
When it does not fire
- Updates to an existing individual (use
individual.updated). - Document-only changes (use
individual.document.*).
Routing
sourceId= individual UUID (ficaIndividualUUID).externalID=null— route onsourceIdand storedata.clientRefwhen the partner sets it.
Example payload
{
"schemaVersion": 1,
"eventId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"eventType": "individual.created",
"occurredAt": "2026-05-26T09:10:39.410Z",
"sourceEntity": "FICA_INDIVIDUAL",
"sourceId": "11111111-2222-3333-4444-555555555555",
"externalID": null,
"data": {
"firstName": "Jane",
"lastName": "Smith",
"ficaStatus": "In Progress",
"riskDescription": null,
"identificationNumber": "0000000000000",
"passportNumber": "",
"clientRef": "",
"externalUserID": null,
"clientEmail": "jane.smith@example.com",
"telNumber": "0000000000",
"taxNumber": "",
"clientFaceToFace": true,
"clientSACitizen": true,
"citizenshipCountry": null,
"residenceCountry": null,
"addressLineOne": "123 Example Street",
"addressLineTwo": "Suburb",
"townCity": "City",
"zipCode": "0000",
"addressCountry": 189,
"employmentStatus": 2,
"occupation": "Accountant",
"employmentIndustry": 2,
"employerName": "Example Company",
"employerIndustry": "Financial Services",
"transactionFrequency": 1,
"transactionType": 49,
"transactionFundingSource": 23,
"sourceFundingDescription": "source funding description",
"transactionSourceWealth": 24,
"sourceWealthDescription": "source wealth description",
"customerPermission": true,
"consumerDetail": {
"ConsumerID": 00000000,
"FirstName": "JANE",
"SecondName": "",
"Surname": "SMITH",
"IDNo": 0000000000000,
"BirthDate": "YYYY-MM-DDT00:00:00+02:00",
"Gender": "Female",
"TitleDesc": "MS",
"MaritalStatusDesc": "Single",
"Age": 35,
"PrivacyStatus": "DO NOT ACCEPT CONTACTS",
"ResidentialAddress": "123 Example Street, Suburb, City, 0000",
"PostalAddress": "123 Example Street, Suburb, City, 0000",
"HomeTelephoneNo": "0000000000",
"WorkTelephoneNo": "0000000000",
"CellularNo": "0000000000",
"EmailAddress": "jane.smith@example.com",
"EmployerDetail": "Example Company South Africa",
"ReferenceNo": "C0000000000-00000000",
"ExternalReference": "mock",
"Nationality": "South African",
"_mock": true
},
"kycResult": {
"EnquiryDate": "2026-05-26T00:00:00+02:00",
"ID": "Valid | 0000000000000",
"ResidentialAddress": "Not Confirmed | 123 Example Street, Suburb, City, 0000",
"Sources": "",
"TotalSourcesUsed": 0,
"IDStatusInd": 1,
"KYCStatusInd": 0,
"IDStatusDesc": "ID Validated On Home Affairs",
"KYCStatusDesc": "No Match Established Within Provided Parameters",
"_mock": true
},
"faceMatchResult": {
"ConnectGetIdentityVerificationResult": {
"IdentityVerificationResult": {
"IdentityInformation": {
"Title": "Miss",
"IDNo": 0000000000000,
"Names": "JANE",
"Surname": "SMITH",
"IdentityCountry": "South African ID",
"IdentityType": "ID Card",
"IDIssueDate": "YYYY-MM-DD",
"DeceasedStatus": "Alive",
"DeceasedDate": "",
"AlivenessScore": 92,
"AlivenessExceptionReason": "",
"ErrorMessage": "",
"LastUpdated": 4
},
"PersonalInformation": {
"DateOfBirth": "YYYY-MM-DD",
"PlaceOfBirth": "ZAF",
"Citizenship": "South African",
"Gender": "Female",
"MaritalStatus": "SINGLE",
"MaritalDate": ""
},
"AddressInformation": {
"PostalAddress1": "123 Example Street",
"PostalAddress2": "Suburb",
"PostalAddress3": "City",
"PostalAddress4": "",
"PostalCode": "",
"ResidentialAddress1": "123 Example Street",
"ResidentialAddress2": "Suburb",
"ResidentialAddress3": "City",
"ResidentialAddress4": "",
"ResidentialCode": ""
}
}
},
"_mock": true
},
"faceMatchImageDocURL": "__mock__/face-match-placeholder.jpg",
"additionalVerification": true,
"additionalVerificationReason": "Additional review required",
"transactionConsistent": "false",
"transactionInconsistantReason": "Transaction pattern inconsistent with profile",
"customQuestions": {
"444": {
"type": "DROPDOWN",
"questionLabel": "Transaction Value",
"selectedOptionId": 942,
"label": "R1 - R500",
"riskScore": 1
},
"445": {
"type": "TEXT",
"questionLabel": "Gender",
"value": "Female",
"riskScore": 0
}
},
"amlScreeningResults": {
"_mock": true,
"metadata": {
"message": "1 match found for PEP and Sanctions.",
"clientId": "11111111-2222-3333-4444-555555555555",
"scriptNameFullName": "Jane Smith",
"scanId": "mock-scan-individual"
},
"matchedNumber": 1,
"matchedEntities": [
{
"resultId": 10000001,
"uniqueId": 20000001,
"resultEntity": {
"uniqueId": 20000001,
"oldProfile": false,
"category": "SIP",
"categories": "Special Interest Person (SIP)",
"suggestedRisk": "Unallocated",
"gender": "Female",
"deceased": "NO",
"primaryFirstName": "Jane",
"primaryLastName": "Smith",
"title": null,
"position": null,
"dateOfBirth": "01 Jan 1970",
"deceasedDate": null,
"placeOfBirth": "",
"primaryLocation": "1 Example Road, EX1 1AA, Example City, United Kingdom",
"generalInfo": {
"nationality": "British"
},
"enterDate": null,
"lastReviewed": "2023-10-24",
"descriptions": [
{
"description1": "Special Interest Person (SIP)",
"description2": "Insolvency",
"description3": ""
}
],
"nameDetails": [
{
"nameType": "Name Spelling Variation",
"firstName": "Jane",
"middleName": "",
"lastName": "Smith"
}
],
"originalScriptNames": [],
"importantDates": [
{
"dateType": "Date of Birth",
"dateValue": "01 Jan 1970"
}
],
"nationalities": [
"British"
],
"nationalitiesCodes": [
"GB"
],
"locations": [
{
"country": "United Kingdom",
"countryCode": "GB",
"city": "Example City",
"address": "1 Example Road, EX1 1AA",
"type": "Residential"
}
],
"countries": [],
"officialLists": [],
"identifiers": [
{
"type": "Occupation",
"country": null,
"value": "Retired"
}
],
"profileOfInterests": [],
"sources": [
{
"url": "https://example.mock/insolvency",
"categories": "Insolvency",
"details": [
{
"categories": "Insolvency",
"originalUrl": "https://example.mock/insolvency",
"credibility": "High",
"language": "eng",
"captureDate": "2023-06-15",
"isCopyrighted": false
}
]
}
],
"linkedIndividuals": [
{
"id": 0,
"firstName": "John",
"middleName": "",
"lastName": "Doe",
"category": "",
"subcategories": "",
"description": "",
"suggestedRisk": "Unallocated"
}
],
"linkedCompanies": [
{
"id": 30000001,
"name": "Example Holdings Ltd",
"category": "SIE",
"description": "Director"
}
],
"Gender": "Female"
},
"matchedFields": "AKA",
"category": "SIP",
"firstName": "Jane",
"lastName": "Smith",
"matchRate": 85,
"dob": "01 Jan 1970",
"primaryLocation": "1 Example Road, EX1 1AA, Example City, United Kingdom",
"decisionDetail": {
"text": "Not Reviewed",
"matchDecision": "NotReviewed",
"assessedRisk": "Unallocated",
"comment": null
}
}
],
"webSearchResults": [
{
"title": "Mock web search result",
"snippet": "Placeholder adverse media snippet for sandbox testing.",
"link": "https://example.mock/search",
"displayLink": "example.mock"
}
],
"fatfJurisdictionRiskResults": [
{
"jurisdiction": "United Kingdom",
"fatfCompliance": "Compliant",
"fatfEffectiveness": "Substantial",
"countryCode": "gb"
}
],
"dataBreachCheckParam": {
"emailAddress": "jane.smith@example.com"
}
},
"adminAdded": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"dateAdded": "2026-05-26T09:11:00.000Z"
}
}
data fields (core groups)
| Group | Fields | Purpose |
|---|---|---|
| Identity | firstName, lastName, identificationNumber, passportNumber, clientSACitizen, citizenshipCountry, residenceCountry | Who the client is |
| Status | ficaStatus, riskDescription | Application state and risk label |
| Partner refs | clientRef, externalUserID | Your routing references |
| Contact | clientEmail, telNumber, taxNumber | Contact and tax |
| Address | addressLineOne, addressLineTwo, townCity, zipCode, addressCountry | Residential address |
| Employment / transaction | employmentStatus, occupation, employmentIndustry, employerName, employerIndustry, transactionFrequency, transactionType, transactionFundingSource, sourceFundingDescription, transactionSourceWealth, sourceWealthDescription | FICA questionnaire |
| Compliance | clientFaceToFace, customerPermission, additionalVerification, additionalVerificationReason, transactionConsistent, transactionInconsistantReason | Flags and reasons |
| Verification | consumerDetail, kycResult, faceMatchResult, faceMatchImageDocURL, amlScreeningResults, customQuestions | Populated when verification has run (often null on immediate create) |
| Audit | adminAdded, dateAdded | Who created and when |
3.2 individual.updated
When it fires
Whenever the individual record is saved after material workflow changes, including (non-exhaustive):
- Dashboard: Step 2 identity verification (risk recalculation), profile update with bureau refresh, document-review confirmation, onboarding approve / decline / refer
- Public API: Update individual, run AML screening, run client validation, PEP/sanctions decision, confirm documents uploaded, onboarding decision
When it does not fire
- Document-only upload or delete without going through the individual-update paths (use
individual.document.*). - If the partner or individual UUID cannot be resolved (event skipped).
Routing
sourceId= individual UUID.externalID= portal onboarding external ID whenonboardingIDis set on the individual; otherwisenull.onboardingId(string) appears on the payload when linked to portal onboarding.
Payload shape
data contains the same curated snapshot as individual.created, plus update-specific and workflow fields below. This is a full snapshot, not a minimal delta.
Example payload (abbreviated)
{
"schemaVersion": 1,
"eventId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"eventType": "individual.updated",
"occurredAt": "2026-05-26T09:29:46.369Z",
"sourceEntity": "FICA_INDIVIDUAL",
"sourceId": "11111111-2222-3333-4444-555555555555",
"externalID": null,
"data": {
"firstName": "Jane",
"lastName": "Smith",
"ficaStatus": "In Progress",
"riskDescription": "High Risk",
"identificationNumber": "0000000000000",
"passportNumber": "",
"clientRef": "",
"externalUserID": null,
"clientEmail": "jane.smith@example.com",
"telNumber": "0000000000",
"taxNumber": "000000000",
"clientFaceToFace": true,
"clientSACitizen": true,
"citizenshipCountry": null,
"residenceCountry": null,
"addressLineOne": "123 Example Street",
"addressLineTwo": "Suburb",
"townCity": "City",
"zipCode": "0000",
"addressCountry": 189,
"employmentStatus": 4,
"occupation": "",
"employmentIndustry": null,
"employerName": "",
"employerIndustry": "",
"transactionFrequency": 1,
"transactionType": 37,
"transactionFundingSource": 55,
"sourceFundingDescription": "",
"transactionSourceWealth": 5,
"sourceWealthDescription": "",
"customerPermission": true,
"consumerDetail": {
"ConsumerID": 00000000,
"FirstName": "JANE",
"SecondName": "",
"Surname": "SMITH",
"IDNo": 0000000000000,
"BirthDate": "YYYY-MM-DDT00:00:00+02:00",
"Gender": "Female",
"TitleDesc": "MS",
"MaritalStatusDesc": "Single",
"Age": 35,
"PrivacyStatus": "DO NOT ACCEPT CONTACTS",
"ResidentialAddress": "123 Example Street, Suburb, City, 0000",
"PostalAddress": "123 Example Street, Suburb, City, 0000",
"HomeTelephoneNo": "0000000000",
"WorkTelephoneNo": "0000000000",
"CellularNo": "0000000000",
"EmailAddress": "jane.smith@example.com",
"EmployerDetail": "Example Company South Africa",
"ReferenceNo": "C0000000000-00000000",
"ExternalReference": "mock",
"Nationality": "South African",
"_mock": true
},
"kycResult": {
"EnquiryDate": "2026-05-26T00:00:00+02:00",
"ID": "Valid | 0000000000000",
"ResidentialAddress": "Not Confirmed | 123 Example Street, Suburb, City, 0000",
"Sources": "",
"TotalSourcesUsed": 0,
"IDStatusInd": 1,
"KYCStatusInd": 0,
"IDStatusDesc": "ID Validated On Home Affairs",
"KYCStatusDesc": "No Match Established Within Provided Parameters",
"_mock": true
},
"faceMatchResult": {
"ConnectGetIdentityVerificationResult": {
"IdentityVerificationResult": {
"IdentityInformation": {
"Title": "Miss",
"IDNo": 0000000000000,
"Names": "JANE",
"Surname": "SMITH",
"IdentityCountry": "South African ID",
"IdentityType": "ID Card",
"IDIssueDate": "YYYY-MM-DD",
"DeceasedStatus": "Alive",
"DeceasedDate": "",
"AlivenessScore": 92,
"AlivenessExceptionReason": "",
"ErrorMessage": "",
"LastUpdated": 4
},
"PersonalInformation": {
"DateOfBirth": "YYYY-MM-DD",
"PlaceOfBirth": "ZAF",
"Citizenship": "South African",
"Gender": "Female",
"MaritalStatus": "SINGLE",
"MaritalDate": ""
},
"AddressInformation": {
"PostalAddress1": "123 Example Street",
"PostalAddress2": "Suburb",
"PostalAddress3": "City",
"PostalAddress4": "",
"PostalCode": 0000,
"ResidentialAddress1": "123 Example Street",
"ResidentialAddress2": "Suburb",
"ResidentialAddress3": "City",
"ResidentialAddress4": "",
"ResidentialCode": 0000
}
}
},
"_mock": true
},
"faceMatchImageDocURL": "__mock__/face-match-placeholder.jpg",
"additionalVerification": false,
"additionalVerificationReason": null,
"transactionConsistent": "true",
"transactionInconsistantReason": "",
"customQuestions": {
"444": {
"type": "DROPDOWN",
"questionLabel": "Transaction Value",
"selectedOptionId": 942,
"label": "R1 - R500",
"riskScore": 1
}
},
"amlScreeningResults": {
"_mock": true,
"metadata": {
"message": "1 match found for PEP and Sanctions.",
"clientId": "11111111-2222-3333-4444-555555555555",
"scriptNameFullName": "Jane Smith",
"scanId": "mock-scan-individual"
},
"matchedNumber": 1,
"matchedEntities": [
{
"resultId": 10000001,
"uniqueId": 20000001,
"resultEntity": {
"uniqueId": 20000001,
"oldProfile": false,
"category": "SIP",
"categories": "Special Interest Person (SIP)",
"suggestedRisk": "Unallocated",
"gender": "Female",
"deceased": "NO",
"primaryFirstName": "Jane",
"primaryLastName": "Smith",
"title": null,
"position": null,
"dateOfBirth": "01 Jan 1970",
"deceasedDate": null,
"placeOfBirth": "",
"primaryLocation": "1 Example Road, EX1 1AA, Example City, United Kingdom",
"generalInfo": {
"nationality": "British"
},
"enterDate": null,
"lastReviewed": "2023-10-24",
"descriptions": [
{
"description1": "Special Interest Person (SIP)",
"description2": "Insolvency",
"description3": ""
}
],
"nameDetails": [
{
"nameType": "Name Spelling Variation",
"firstName": "Jane",
"middleName": "",
"lastName": "Smith"
}
],
"originalScriptNames": [],
"importantDates": [
{
"dateType": "Date of Birth",
"dateValue": "01 Jan 1970"
}
],
"nationalities": [
"British"
],
"nationalitiesCodes": [
"GB"
],
"locations": [
{
"country": "United Kingdom",
"countryCode": "GB",
"city": "Example City",
"address": "1 Example Road, EX1 1AA",
"type": "Residential"
}
],
"countries": [],
"officialLists": [],
"identifiers": [
{
"type": "Occupation",
"country": null,
"value": "Retired"
}
],
"profileOfInterests": [],
"sources": [
{
"url": "https://example.mock/insolvency",
"categories": "Insolvency",
"details": [
{
"categories": "Insolvency",
"originalUrl": "https://example.mock/insolvency",
"credibility": "High",
"language": "eng",
"captureDate": "2023-06-15",
"isCopyrighted": false
}
]
}
],
"linkedIndividuals": [
{
"id": 0,
"firstName": "John",
"middleName": "",
"lastName": "Doe",
"category": "",
"subcategories": "",
"description": "",
"suggestedRisk": "Unallocated"
}
],
"linkedCompanies": [
{
"id": 30000001,
"name": "Example Holdings Ltd",
"category": "SIE",
"description": "Director"
}
],
"Gender": "Female"
},
"matchedFields": "AKA",
"category": "SIP",
"firstName": "Jane",
"lastName": "Smith",
"matchRate": 85,
"dob": "01 Jan 1970",
"primaryLocation": "1 Example Road, EX1 1AA, Example City, United Kingdom",
"decisionDetail": {
"text": "Not Reviewed",
"matchDecision": "NotReviewed",
"assessedRisk": "Unallocated",
"comment": null
},
"confirmedMatch": true,
"confirmedByAdminId": 1,
"confirmedByAdminName": "Admin User",
"confirmedAt": "2026-05-26T09:29:13.834Z"
}
],
"webSearchResults": [
{
"title": "Mock web search result",
"snippet": "Placeholder adverse media snippet for sandbox testing.",
"link": "https://example.mock/search",
"displayLink": "example.mock"
}
],
"fatfJurisdictionRiskResults": [
{
"jurisdiction": "United Kingdom",
"fatfCompliance": "Compliant",
"fatfEffectiveness": "Substantial",
"countryCode": "gb"
}
],
"dataBreachCheckParam": {
"emailAddress": "jane.smith@example.com"
}
},
"adminAdded": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"dateAdded": "2026-05-26T08:33:00.000Z",
"adminUpdated": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"dateUpdated": "2026-05-26T09:30:00.000Z"
}
}
Additional data fields (update / workflow only)
| Field | Description |
|---|---|
adminUpdated, dateUpdated | Last change user UUID and timestamp |
riskReason | Human-readable reason for current risk label |
adverseSearchKYC | Adverse media / KYC search flag when set |
pepConfirmReviewed | PEP confirmation reviewed flag |
foreignOfficial, foreignOfficialType | Foreign public official indicators |
docsUploadedReviewed, docsReviewedAdminID, docsReviewedDate | Document review step |
sanctionsPepReviewed | Sanctions / PEP review completed |
ongoingMonitoring | Ongoing monitoring enabled on screening |
nextFicaReviewDate | Next scheduled FICA review (ISO) |
ficaApprovedAdminID, ficaApprovedDate, ficaApprovedComment | Approval path |
ficaDeclineAdminID, ficaDeclineDate, ficaDeclineComment | Decline path |
ficaReferedByAdminID, ficaReferedToAdminID, ficaReferredDate, referredToAdminReason, referredAdminDecision, referredAdminDecisionComment | Referral path |
4. Individual document events
4.1 individual.document.created
When it fires: After a successful upload and a ficaIndividualDocs row is created (dashboard document upload or public API add-document).
Note: Public API add-document can create multiple document rows from one file (multiple document groups/types). You receive one webhook per row.
4.2 individual.document.deleted
When it fires: After a document is soft-deleted (isActive = false).
Routing (both)
| Field | Value |
|---|---|
sourceId / individualId | Parent individual UUID |
externalID | Individual clientRef when set; otherwise null |
individualDocID | ficaIndividualDocsID |
Example (individual.document.created)
{
"schemaVersion": 1,
"eventId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"eventType": "individual.document.created",
"occurredAt": "2026-05-21T12:00:00.000Z",
"sourceEntity": "FICA_INDIVIDUAL_DOC",
"sourceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"individualId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"externalID": "PARTNER-APP-10042",
"individualDocID": 1042,
"data": {
"docGroupID": 3,
"docTypeID": 12,
"docName": "a1b2c3d4-e5f6-7890-abcd-ef1234567890.pdf",
"active": true,
"uploadDate": "2026-05-21T12:00:00.000Z",
"uploadAdminId": "9b8c7d6e-5f4a-3210-9876-543210fedcba",
"deleteAdminDate": null,
"deleteAdminId": null
}
}
| Field | Description |
|---|---|
docGroupID | Document group (individualDocsID) |
docTypeID | Document type (IndividualDocTypesID) |
docName | Stored blob name / key (not a public download URL by itself) |
active | Whether the document row is active |
uploadAdminId / deleteAdminId | User GUIDs (delete admin may be null on public API delete) |
Business note: Downloading file content usually requires a separate eFICA document API using individualDocID, not the webhook alone.
5. Implementation checklist (developers)
- Verify signature on every request.
- Dedupe on
eventId(return2xxquickly; process async if needed). - Create external record on
individual.createdusingsourceId(individual UUID); persistdata.clientRefwhen provided. - Sync on
individual.updatedusingsourceId; useexternalID+onboardingIdwhen present to tie back to portal applications. - Documents: resolve parent via
individualId+individualDocID; do not rely ondocNamealone. - Inspect deliveries in eFICA: Settings → Integrations → Webhook Events (filter by event type, view attempts).
- No HTTP delivery: Confirm the event type is enabled on an enabled subscription for the same partner that owns the individual record.
6. Troubleshooting
| Symptom | Likely cause |
|---|---|
| No webhook at all | Subscription disabled; event type not selected; enqueue skipped (missing individual UUID or partner) |
| Event in UI but no HTTP call | No matching subscription (eventTypes must include exact string, e.g. "individual.document.created") |
| Duplicate POSTs | Normal at-least-once behaviour; dedupe with eventId |
individual.updated without externalID | Individual not linked to customer portal onboarding (onboardingID empty) — still valid; use sourceId |
| Document webhook missing after UI upload | Subscription missing individual.document.created; or backend not redeployed after enablement |
uploadAdminId null on public API | Public API may use a generic partner user for addedByID; field optional |
Document history
| Version | Date | Notes |
|---|---|---|
| 1.0 | 2026-05-26 | Initial individual webhook reference (record + documents) |
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