Employees
Employees represent the individuals reported under the Management Control pillar of a BEEtoolkit Scorecard. This API allows you to fetch and upsert employees for a specific scorecard.
Employees are always scoped to a single scorecard and are stored against that scorecard's ID.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/public/v1/scorecards/{scorecard_id}/employees | Retrieve all employees for a scorecard |
POST | /api/public/v1/scorecards/{scorecard_id}/employees | Upsert (create or update) employees in bulk |
DELETE | /api/public/v1/scorecards/{scorecard_id}/employees/{employee_id} | Delete an employee by ID |
Include the following headers on every request:
Authorization: HMAC <signature>X-Api-Key: <your account key>Accept: application/json
See Authentication.
Attributes
Unless otherwise stated, all fields are optional from the API's perspective. However, some are required in practice to create valid B-BBEE records (see notes below).
Core Identity & Classification
| Field | Type | Required | Description |
|---|---|---|---|
full_name | string | yes | Employee full name. |
id_number | string | yes | 13-digit SA ID. Required unless foreign = true. Used as a primary external identifier. |
foreign | boolean | no | Marks the individual as a foreign national. If true, id_number may be omitted or replaced with a passport number. |
gender | string | yes | See Gender values. |
race | string | yes | See Race values. |
designation | string | yes | Occupational level. See Designation values. Required when creating a new employee. |
disabled | boolean | no | Indicates whether the employee is a person with a disability. |
Employment & Structure
| Field | Type | Required | Description |
|---|---|---|---|
hire_date | string | no | Employment start date (YYYY-MM-DD). |
termination_date | string | null | no | Employment end date, if applicable. |
latest_promotion_date | string | null | no | Most recent promotion date. |
employee_code | string | no | Your internal employee identifier. Used as a secondary external identifier. |
location | string | no | Site/branch, e.g. "HO", "Plant 1". |
business_unit | string | no | Department or business unit. |
province | string | no | Province used for reporting. |
age | integer | no | Age of the employee (typically at period end). |
voting_rights | number | string | no | Voting rights percentage (for Ownership/MC linkage where applicable). |
System Fields (Response Only)
| Field | Type | Description |
|---|---|---|
id | integer | Internal ID of the employee record. |
created_at | datetime | Creation timestamp. |
updated_at | datetime | Last update timestamp. |
Enumerations
The API expects values that align with your B-BBEE configuration. The lists below show typical values; your environment may be configured with a subset or variant of these.
Gender values
MaleFemale
Race values
AfricanColouredIndianWhite
Designation values
Executive DirectorNon-executive DirectorOther Executive ManagerSenior ManagerMiddle ManagerJunior ManagerSemi-skilledUnskilled
Notes
- All dates must be in ISO 8601 format (
YYYY-MM-DD).nullis accepted where a date is not applicable. - Each employee record must include at least one external identifier:
id_numberoremployee_code. - Upserts match by
id_numberfirst, then byemployee_code. If no match is found, a new record is created.
List employees
Retrieve all employees captured against a specific scorecard.
GET /api/public/v1/scorecards/{scorecard_id}/employees
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
scorecard_id | string | yes | The scorecard identifier. |
Code examples
- cURL
- JavaScript (axios)
curl -X GET "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/employees" \
-H "Accept: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>"
const url = `https://www.beetoolkit.co.za/api/public/v1/scorecards/${scorecardId}/employees`;
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
[
{
"id": 54981057,
"gender": "Male",
"designation": "Semi-skilled",
"disabled": true,
"foreign": false,
"race": "Indian",
"full_name": "John Smith",
"id_number": "8801010120001",
"hire_date": null,
"termination_date": null,
"latest_promotion_date": null,
"employee_code": "333",
"location": "HO",
"business_unit": "HR",
"province": "Gauteng",
"age": 24,
"voting_rights": "0.0",
"created_at": "2026-01-15T07:59:32.000Z",
"updated_at": "2026-01-15T07:59:32.000Z"
}
]
Upsert employees (bulk)
Create or update multiple employees at once via a batch payload. Records are matched by id_number first, then by employee_code. If no match is found, a new record is created.
POST /api/public/v1/scorecards/{scorecard_id}/employees
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
scorecard_id | string | yes | The scorecard identifier. |
Request body
Send a JSON object with an employees array:
{
"employees": [
{
"gender": "Male",
"designation": "Semi-skilled",
"disabled": true,
"foreign": false,
"race": "Indian",
"full_name": "John Smith",
"id_number": "8801010120001",
"hire_date": null,
"termination_date": null,
"latest_promotion_date": null,
"employee_code": "333",
"location": "HO",
"business_unit": "HR",
"province": "Gauteng",
"age": 24,
"voting_rights": 0
}
]
}
Code examples
- cURL
- JavaScript (axios)
curl -X POST "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/employees" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>" \
-d '{
"employees": [
{
"gender": "Male",
"designation": "Semi-skilled",
"disabled": true,
"foreign": false,
"race": "Indian",
"full_name": "John Smith",
"id_number": "8801010120001",
"employee_code": "333",
"location": "HO",
"business_unit": "HR",
"province": "Gauteng",
"age": 24,
"voting_rights": 0
}
]
}'
const scorecardId = "scorecard_b8Jyl56MPDRH3jrVMeqZkpDw";
const url = `https://www.beetoolkit.co.za/api/public/v1/scorecards/${scorecardId}/employees`;
const payload = {
employees: [
{
gender: "Male",
designation: "Semi-skilled",
disabled: true,
foreign: false,
race: "Indian",
full_name: "John Smith",
id_number: "8801010120001",
hire_date: null,
termination_date: null,
latest_promotion_date: null,
employee_code: "333",
location: "HO",
business_unit: "HR",
province: "Gauteng",
age: 24,
voting_rights: 0,
},
],
};
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
On success, the API returns the upserted employees as an array:
[
{
"id": 54981057,
"gender": "Male",
"designation": "Semi-skilled",
"disabled": true,
"foreign": false,
"race": "Indian",
"full_name": "John Smith",
"id_number": "8801010120001",
"hire_date": null,
"termination_date": null,
"latest_promotion_date": null,
"employee_code": "333",
"location": "HO",
"business_unit": "HR",
"province": "Gauteng",
"age": 24,
"voting_rights": "0.0",
"created_at": "2026-01-15T07:59:32.000Z",
"updated_at": "2026-01-15T07:59:32.000Z"
}
]
After creating or updating employees, call the scorecard recalculate endpoint to refresh scores: Recalculate a scorecard.
Errors
| Status | Description |
|---|---|
422 | One or more employee records are invalid, or missing required external identifiers. |
Missing external identifier:
{
"error": {
"message": "Employee records must include at least one external identifier (id_number or employee_code).",
"invalid_records": [
{
"full_name": "John NoId",
"gender": "Male"
}
]
}
}
Invalid field values:
{
"error": {
"message": "One or more employee records are invalid.",
"invalid_records": [
{
"errors": [
"Id number needs to be a valid 13-digit SA ID number or individual should be marked as foreign"
],
"id_number": "888888877789",
"employee_code": "333",
"full_name": "John Smith"
}
]
}
}
Delete an employee
Delete a single employee by ID.
DELETE /api/public/v1/scorecards/{scorecard_id}/employees/{employee_id}
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
scorecard_id | string | yes | The scorecard identifier. |
employee_id | integer | yes | The BEEtoolkit-assigned employee ID. |
Code examples
- cURL
- JavaScript (axios)
curl -X DELETE "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/employees/{employee_id}" \
-H "Accept: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>"
const scorecardId = "scorecard_b8Jyl56MPDRH3jrVMeqZkpDw";
const employeeId = 54981057;
const url = `https://www.beetoolkit.co.za/api/public/v1/scorecards/${scorecardId}/employees/${employeeId}`;
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); // 204
Response
Returns 204 No Content on success.
After deleting employees, call the scorecard recalculate endpoint to refresh scores: Recalculate a scorecard.