Skip to main content

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.

Supplier-update category keys are changing

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​

FieldTypeDescription
onboardingRequestErpEventIdGUID (string)Unique identifier for the onboarding request ERP event
clientCompanyIdintegerThe ID of the client company requesting the onboarding
supplierCompanyIdintegerThe ID of the supplier company being onboarded
workflowInstanceIdGUID (string)The workflow instance ID tracking this onboarding process
dataarrayArray of collected data items, each with a category and dataJson, ordered by category ascending

Data Category Types​

Each item in the data array contains:

FieldTypeDescription
categoryintegerThe category, as a number. See Category Values below. Route on this field, not categoryTitle.
categoryTitlestringThe 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.
dataJsonobject or arrayThe actual data for this category (structure varies by category)
successbooleanWhether the data was successfully retrieved
errorMessagestring or nullThe 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 valuecategoryTitle
0OnboardingRequestDetails
1CompanyDetails
2Documents
3BbbeeInfo

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​

  1. Category Routing: category is always a number on the wire (0 to 3). categoryTitle is 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.

  2. 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, shareholderDetails or tradeReferences within CompanyDetails): if the data doesn't exist or wasn't collected, the property is simply absent or null rather than flagged by a separate boolean.

  3. Success Status: Each data item has its own success status. A category with success: false will have an errorMessage explaining the failure. Note that the reverse does not hold: errorMessage can also be non-null when success is true (see note 4). Branch on success, not on the presence of errorMessage.

  4. Partial results (success: true with a non-null errorMessage): CompanyDetails can be delivered with some of its optional sections missing. When that happens the category is still reported as success: true, and the omission is carried on that same category's errorMessage:

    {
    "category": 1,
    "categoryTitle": "CompanyDetails",
    "dataJson": { "...": "..." },
    "success": true,
    "errorMessage": "Partial supplier information: contactDetails, addressInfo could not be retrieved."
    }

    There is no message property on a data[] item. The message you may also see for this category lives one level down, inside dataJson, and carries the same notice.

    The sections named there are the ones that could not be built: currently contactDetails, addressInfo, geographicalLocations and coreCompanyInfo. Each optional section degrades on its own, so one failed lookup no longer discards the sections that succeeded.

    Do not treat a non-null errorMessage as a failed delivery. A receiver that rejects on errorMessage alone will discard every partial CompanyDetails delivery even though success is true and the core data is present. Branch on success first; then, if errorMessage is 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 own message giving context when the block came back empty.

  5. DataJson Structure: The dataJson field structure varies by category:

    • OnboardingRequestDetails (category 0): Object with onboarding request information
    • CompanyDetails (category 1): Object with comprehensive company information
    • Documents (category 2): Object with a documents property containing an array of document status objects
    • BbbeeInfo (category 3): Object with B-BBEE certificate and ownership details
  6. businessUnits is a list: Within OnboardingRequestDetails, businessUnits is 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.

  7. Type Safety: All dataJson fields use strongly typed DTOs with camelCase property naming. This ensures consistent structure and type safety across all webhook payloads.

  8. Null Values: Many fields may be null if data is not available or not applicable.

  9. 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​