Suppliers
Suppliers represent the organisations to which you allocate spend within Procurement Scorecards. All interactions with the Supplier API use your own vendor codes as the primary identifier. You will use these codes when creating, updating, retrieving, and deleting suppliers, as well as when loading procurement data.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/suppliers/heartbeat | Confirm API availability and authentication |
GET | /api/v1/suppliers | List suppliers, paginated, with optional filters |
GET | /api/v1/suppliers/{vendor_code} | Retrieve a supplier by vendor code |
POST | /api/v1/suppliers | Create a new supplier |
PUT | /api/v1/suppliers/{vendor_code} | Update an existing supplier |
DELETE | /api/v1/suppliers/{vendor_code} | Delete a supplier |
Include the following headers on every request:
Authorization: HMAC <signature>X-Api-Key: <your account key>Accept: application/json
See Authentication.
Attributes
Below is the full list of supported supplier fields. Unless stated otherwise, all fields are optional.
| Field | Type | Required | Description |
|---|---|---|---|
trading_name | string | yes | Supplier's trading name. |
vendor_code | string | yes | Your internal supplier identifier. Must be unique. |
vat_number | string | conditional | VAT number. Required when the account enforces compulsory VAT numbers and the supplier is not VAT exempt. |
excluded | boolean | no | Whether the supplier is excluded from B-BBEE procurement. |
excluded_reason | string | conditional | Reason for exclusion. Required when exclusion is enabled for the supplier. |
intragroup | boolean | no | Whether the supplier is part of your group. |
intragroup_account_name | string | conditional | Internal intragroup account name. Required when intragroup is true. |
date_of_first_procurement | string | no | First recorded procurement date (DD/MM/YYYY). |
contract_start_date | string | no | Contract start date (DD/MM/YYYY). |
contract_end_date | string | no | Contract end date (DD/MM/YYYY). |
supplier_development_recipient | boolean | no | Whether the supplier receives Supplier Development support. |
registered_name | string | no | Registered legal name. |
registration_number | string | no | Company registration number. |
telephone | string | no | Supplier telephone number. |
email | string | no | Supplier email address. |
postal_address | string | no | Postal address. |
cost_centre | string | no | Cost centre reference. |
priority | string | no | Priority level (if applicable). |
custom_1 | string | no | Custom field 1. |
custom_2 | string | no | Custom field 2. |
custom_3 | string | no | Custom field 3. |
custom_4 | string | no | Custom field 4. |
property_service_provider | boolean | no | Whether this is a property service provider. |
_disabled_participation | boolean | no | Indicates >5% disabled ownership participation. |
living_with_disability | boolean | no | Whether the supplier is living with a disability. |
stockbroker | boolean | no | Whether the supplier is a stockbroker. |
fund_manager | boolean | no | Whether the supplier is a fund manager. |
intermediary | boolean | no | Whether the supplier is an intermediary. |
System Fields (Response Only)
| Field | Type | Description |
|---|---|---|
vat_exempt | string | VAT exemption status. |
greater_than_5_percent_disabled_participation | string | Disabled participation flag. |
status | string | null | Free-form label tracking where the supplier sits in your B-BBEE scorecard-gathering workflow. Written only by internal tooling, not by the API — sending status in a create/update payload is silently ignored. null if never set. See the common values table below. |
created_at | string | Creation timestamp (DD/MM/YYYY HH:MM:SS). |
updated_at | string | Last update timestamp (DD/MM/YYYY HH:MM:SS). |
status_updated_at | string | null | Timestamp of the most recent status change (DD/MM/YYYY HH:MM:SS). null if the supplier has never had its status set. |
scorecards | array | Array of scorecard objects with the same shape as the Scores API. Always returned on the single-supplier show endpoint. On List suppliers only included when include=scorecards is passed. |
Notes
- Dates must be formatted as
DD/MM/YYYY. vendor_codemust be unique and is required for creation, updates, and lookups.- Boolean fields must be sent as JSON booleans (
true/false). statusis read-only through this API. You can filter by it and you will see it in responses, but sendingstatusin aPOST/PUTbody is silently dropped — the field is maintained by internal SMS tooling. Values are free-form strings; the common vocabulary is shown below.status_updated_atis derived from the most recent status change recorded against the supplier; it is not a stored column, so it updates automatically wheneverstatusis written by whichever internal tool is responsible.
Common status values
You can filter by any of them via filter[status]=; you cannot set them via this API.
| Value | Typical meaning |
|---|---|
requested | You have asked the supplier for their scorecard but haven't received it yet. |
received | The supplier has sent through a scorecard, pending review / capture. |
obtained | A valid scorecard is on file for the supplier. |
expired | The supplier's most recent scorecard has passed its valid_until date and a fresh one hasn't been obtained. |
pending | Some other in-flight state (e.g. awaiting internal sign-off, waiting on a verification agency). |
non-compliant | The supplier has indicated they will not / cannot provide a scorecard. |
exempt | The supplier is not required to provide a scorecard (e.g. below turnover thresholds, or excluded from procurement). |
filter[status]= (empty) matches suppliers with no status set (null).
List suppliers
List the suppliers on your account, paginated, with optional filters.
GET /api/v1/suppliers
Query parameters
All parameters are optional.
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | no | Page number (1-indexed). Defaults to 1. |
per_page | integer | no | Page size. Defaults to 50, maximum 1000. |
filter[status] | string | no | Exact-match filter on the supplier's status field. Pass an empty string to return suppliers with no status set. |
filter[updated_at_from] | string | no | Lower bound (inclusive) on the supplier's updated_at. Accepts ISO 8601 (2026-04-01T00:00:00Z) or DD/MM/YYYY. |
filter[updated_at_to] | string | no | Upper bound (exclusive) on updated_at. Same formats as updated_at_from. |
filter[status_updated_at_from] | string | no | Lower bound (inclusive) on the most recent status change. |
filter[status_updated_at_to] | string | no | Upper bound (exclusive) on the most recent status change. |
include | string | no | Comma-separated list of related collections to embed. Only scorecards is currently honoured. |
Code examples
- cURL
- JavaScript (axios)
curl -X GET "https://www.suppliermanagement.co.za/api/v1/suppliers?page=1&per_page=50&filter%5Bstatus%5D=obtained&include=scorecards" \
-H "Accept: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>"
const url = "https://www.suppliermanagement.co.za/api/v1/suppliers";
const query = "?page=1&per_page=50&filter[status]=obtained&include=scorecards";
const path = new URL(url).pathname;
const signature = await generateSignature(path, "", apiSecret, 5);
const response = await axios.get(`${url}${query}`, {
headers: {
Accept: "application/json",
Authorization: `HMAC ${signature}`,
"X-Api-Key": apiKey,
},
});
console.log(response.data);
Response
Walk the collection by following meta.next_url or by incrementing page yourself until page reaches meta.pages.
{
"data": [
{
"trading_name": "African Reinforcing Construction",
"vendor_code": "af001",
"status": "obtained",
"status_updated_at": "01/04/2026 10:15:00",
"created_at": "18/05/2022 11:14:34",
"updated_at": "02/04/2026 09:12:00",
"scorecards": [
{
"id": "beagle_k2b9",
"level": "4",
"score": "80.0",
"source": "beagle",
"beagle_scorecard_url": "https://beagle.mpowered.co.za/scorecards/k2b9?token=...&expiry=...",
"beagle_scorecard_url_expires_at": "2026-05-02T10:15:00Z",
"valid_from": "02/07/2025",
"valid_until": "01/07/2026"
}
]
}
],
"meta": {
"prev_url": null,
"next_url": "https://www.suppliermanagement.co.za/api/v1/suppliers?page=2&per_page=50&filter%5Bstatus%5D=obtained&include=scorecards",
"count": 124,
"page": 1,
"limit": 50,
"pages": 3
}
}
The include=scorecards option expands each supplier with its full scorecard set, which may trigger a lookup against the Beagle Database for every supplier that has a linked company. Use include=scorecards with a narrow filter (or a smaller per_page) when browsing large collections.
Retrieve a supplier
Retrieve a single supplier by vendor code.
GET /api/v1/suppliers/{vendor_code}
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
vendor_code | string | yes | The supplier's vendor code. |
Code examples
- cURL
- JavaScript (axios)
curl -X GET "https://www.suppliermanagement.co.za/api/v1/suppliers/af001" \
-H "Accept: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>"
const url = "https://www.suppliermanagement.co.za/api/v1/suppliers/af001";
const path = new URL(url).pathname;
const signature = await generateSignature(path, "", apiSecret, 5);
const response = await axios.get(url, {
headers: {
Accept: "application/json",
Authorization: `HMAC ${signature}`,
"X-Api-Key": apiKey,
},
});
console.log(response.data);
Response
{
"trading_name": "African Reinforcing Construction",
"vendor_code": "af001",
"status": "obtained",
"vat_number": "4312345678",
"vat_exempt": "false",
"excluded": "false",
"excluded_reason": "",
"intragroup": "false",
"intragroup_account_name": "",
"date_of_first_procurement": "",
"contract_start_date": "",
"contract_end_date": "",
"supplier_development_recipient": "false",
"registered_name": "",
"registration_number": "",
"telephone": "",
"email": "",
"postal_address": "",
"cost_centre": "",
"priority": "",
"custom_1": "",
"custom_2": "",
"custom_3": "",
"custom_4": "",
"property_service_provider": "false",
"greater_than_5_percent_disabled_participation": "false",
"living_with_disability": "false",
"stockbroker": "false",
"fund_manager": "false",
"intermediary": "false",
"created_at": "18/05/2022 11:14:34",
"updated_at": "18/05/2022 11:23:17",
"status_updated_at": "01/04/2026 10:15:00",
"scorecards": []
}
Create a supplier
Create a new supplier.
POST /api/v1/suppliers
Request body
Send a JSON object with a supplier key:
{
"supplier": {
"trading_name": "New Supplier",
"vendor_code": "NS001"
}
}
Code examples
- cURL
- JavaScript (axios)
curl -X POST "https://www.suppliermanagement.co.za/api/v1/suppliers" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>" \
-d '{
"supplier": {
"trading_name": "New Supplier",
"vendor_code": "NS001"
}
}'
const url = "https://www.suppliermanagement.co.za/api/v1/suppliers";
const payload = {
supplier: {
trading_name: "New Supplier",
vendor_code: "NS001",
},
};
const path = new URL(url).pathname;
const signature = await generateSignature(path, payload, apiSecret, 5);
const response = await axios.post(url, payload, {
headers: {
Accept: "application/json",
Authorization: `HMAC ${signature}`,
"X-Api-Key": apiKey,
},
});
console.log(response.data);
Response
{
"trading_name": "New Supplier",
"vendor_code": "NS001",
"vat_number": "",
"vat_exempt": "false",
"excluded": "false",
"excluded_reason": "",
"intragroup": "false",
"intragroup_account_name": "",
"date_of_first_procurement": "",
"contract_start_date": "",
"contract_end_date": "",
"supplier_development_recipient": "false",
"registered_name": "",
"registration_number": "",
"telephone": "",
"email": "",
"postal_address": "",
"cost_centre": "",
"priority": "",
"custom_1": "",
"custom_2": "",
"custom_3": "",
"custom_4": "",
"property_service_provider": "false",
"greater_than_5_percent_disabled_participation": "false",
"living_with_disability": "false",
"stockbroker": "false",
"fund_manager": "false",
"intermediary": "false",
"created_at": "16/02/2026 08:08:12",
"updated_at": "16/02/2026 08:08:12"
}
Update a supplier
Update an existing supplier by vendor code.
PUT /api/v1/suppliers/{vendor_code}
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
vendor_code | string | yes | The supplier's vendor code. |
Request body
Send a JSON object with a supplier key containing only the fields to update:
{
"supplier": {
"trading_name": "Updated Supplier Name"
}
}
Code examples
- cURL
- JavaScript (axios)
curl -X PUT "https://www.suppliermanagement.co.za/api/v1/suppliers/NS001" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>" \
-d '{
"supplier": {
"trading_name": "Updated Supplier Name"
}
}'
const url = "https://www.suppliermanagement.co.za/api/v1/suppliers/NS001";
const payload = {
supplier: {
trading_name: "Updated Supplier Name",
},
};
const path = new URL(url).pathname;
const signature = await generateSignature(path, payload, apiSecret, 5);
const response = await axios.put(url, payload, {
headers: {
Accept: "application/json",
Authorization: `HMAC ${signature}`,
"X-Api-Key": apiKey,
},
});
console.log(response.data);
Response
Returns the updated supplier record.
Delete a supplier
Delete a supplier by vendor code.
DELETE /api/v1/suppliers/{vendor_code}
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
vendor_code | string | yes | The supplier's vendor code. |
Code examples
- cURL
- JavaScript (axios)
curl -X DELETE "https://www.suppliermanagement.co.za/api/v1/suppliers/NS001" \
-H "Accept: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>"
const url = "https://www.suppliermanagement.co.za/api/v1/suppliers/NS001";
const path = new URL(url).pathname;
const signature = await generateSignature(path, "", apiSecret, 5);
const response = await axios.delete(url, {
headers: {
Accept: "application/json",
Authorization: `HMAC ${signature}`,
"X-Api-Key": apiKey,
},
});
console.log(response.status);
Response
Returns 204 No Content on success.