Webhook Payload Reference
Before your ERP system sends back the vendor number, B1Link first sends a webhook payload to your configured webhook receiver endpoint. This section documents the complete structure of the incoming payload that B1Link will POST to your endpoint.
This page documents the onboarding payload, whose categoryTitle values are unchanged. The separate supplier-update webhook is moving its categories keys to PascalCase, a breaking change for receivers of that webhook. If you consume it, see the breaking-change callout on that page.
Structure
The payload sent from B1Link to your ERP system follows this structure:
{
"onboardingRequestErpEventId": "550e8400-e29b-41d4-a716-446655440000",
"clientCompanyId": 123,
"supplierCompanyId": 456,
"workflowInstanceId": "660e8400-e29b-41d4-a716-446655440001",
"data": [
{
"category": 0,
"categoryTitle": "OnboardingRequestDetails",
"dataJson": { /* Onboarding request details */ },
"success": true,
"errorMessage": null
},
{
"category": 1,
"categoryTitle": "CompanyDetails",
"dataJson": { /* Company information */ },
"success": true,
"errorMessage": null
},
{
"category": 2,
"categoryTitle": "Documents",
"dataJson": { "documents": [ /* Document status array */ ] },
"success": true,
"errorMessage": null
},
{
"category": 3,
"categoryTitle": "BbbeeInfo",
"dataJson": { /* B-BBEE information */ },
"success": true,
"errorMessage": null
}
]
}
data items are ordered by category ascending.
Payload Field Descriptions
| Field | Type | Description |
|---|---|---|
onboardingRequestErpEventId | GUID (string) | Unique identifier for the onboarding request ERP event |
clientCompanyId | integer | The ID of the client company requesting the onboarding |
supplierCompanyId | integer | The ID of the supplier company being onboarded |
workflowInstanceId | GUID (string) | The workflow instance ID tracking this onboarding process |
data | array | Array of collected data items, each with a category and dataJson, ordered by category ascending |
Data Category Types
Each item in the data array contains:
| Field | Type | Description |
|---|---|---|
category | integer | The category, as a number. See Category Values below. Route on this field, not categoryTitle. |
categoryTitle | string | The category's enum name as a string (e.g. CompanyDetails). Provided for logging and support purposes only. Do not use it to drive logic, it is not guaranteed to be stable to parse against. |
dataJson | object or array | The actual data for this category (structure varies by category) |
success | boolean | Whether the data was successfully retrieved |
errorMessage | string or null | The failure reason when success is false, or a partial-retrieval notice when success is true. A non-null errorMessage does not imply the delivery failed (see note 4). |
Category Values
category value | categoryTitle |
|---|---|
0 | OnboardingRequestDetails |
1 | CompanyDetails |
2 | Documents |
3 | BbbeeInfo |
The webhook serializes enums as their numeric wire value. There is no string-enum conversion. Your receiver's routing logic (e.g. a switch/case on category) must match on these integers. categoryTitle is a convenience label for logs and support tickets; it is not part of the routing contract and should never be parsed to decide behavior.
Important Notes
-
Category Routing:
categoryis always a number on the wire (0to3).categoryTitleis the same category's enum name as a string, included purely for human-readable logging and support. Receivers must switch on the number, not the title. -
Data Categories: Not all categories may be present in every payload. Categories are included based on what data is available and configured for the specific onboarding request. There is no separate set of "requires" flags. The presence or absence of a category block itself is what signals whether that data applies to this onboarding request. The same applies to optional sub-objects within a category's
dataJson(for example,bankDetails,coidaInfo,shareholderDetailsortradeReferenceswithinCompanyDetails): if the data doesn't exist or wasn't collected, the property is simply absent ornullrather than flagged by a separate boolean. -
Success Status: Each data item has its own
successstatus. A category withsuccess: falsewill have anerrorMessageexplaining the failure. Note that the reverse does not hold:errorMessagecan also be non-null whensuccessistrue(see note 4). Branch onsuccess, not on the presence oferrorMessage. -
Partial results (
success: truewith a non-nullerrorMessage):CompanyDetailscan be delivered with some of its optional sections missing. When that happens the category is still reported assuccess: true, and the omission is carried on that same category'serrorMessage:{
"category": 1,
"categoryTitle": "CompanyDetails",
"dataJson": { "...": "..." },
"success": true,
"errorMessage": "Partial supplier information: contactDetails, addressInfo could not be retrieved."
}There is no
messageproperty on adata[]item. Themessageyou may also see for this category lives one level down, insidedataJson, and carries the same notice.The sections named there are the ones that could not be built: currently
contactDetails,addressInfo,geographicalLocationsandcoreCompanyInfo. Each optional section degrades on its own, so one failed lookup no longer discards the sections that succeeded.Do not treat a non-null
errorMessageas a failed delivery. A receiver that rejects onerrorMessagealone will discard every partialCompanyDetailsdelivery even thoughsuccessistrueand the core data is present. Branch onsuccessfirst; then, iferrorMessageis non-null, treat the sections it names as unknown rather than as empty or deleted, and do not overwrite existing values in your ERP from them. The message is a fixed, human-readable notice. It never contains raw error detail. Several sub-blocks (coidaInfo,numberOfEmployees,tradeReferences,businessTypes, the residency indicators) also carry their ownmessagegiving context when the block came back empty. -
DataJson Structure: The
dataJsonfield structure varies by category:OnboardingRequestDetails(category0): Object with onboarding request informationCompanyDetails(category1): Object with comprehensive company informationDocuments(category2): Object with adocumentsproperty containing an array of document status objectsBbbeeInfo(category3): Object with B-BBEE certificate and ownership details
-
businessUnitsis a list: WithinOnboardingRequestDetails,businessUnitsis an array, not a single object. A supplier's onboarding request may be associated with one business unit, several, or none. It may be absent,null, or empty. Do not assume exactly one entry. -
Type Safety: All
dataJsonfields use strongly typed DTOs with camelCase property naming. This ensures consistent structure and type safety across all webhook payloads. -
Null Values: Many fields may be
nullif data is not available or not applicable. -
Webhook Receiver Configuration: This payload is POSTed by B1Link to your configured webhook receiver endpoint URL. Ensure your endpoint can handle this structure and respond appropriately (typically with a 200 OK status).
Complete Example
See the Complete Example Payload for a full example with all data categories populated.
Next Steps
- Complete Example Payload - Full example with all fields
- Integration Guide - How to send vendor numbers back to B1Link