Skip to main content

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

MethodPathPurpose
GET/api/public/v1/scorecards/{scorecard_id}/employeesRetrieve all employees for a scorecard
POST/api/public/v1/scorecards/{scorecard_id}/employeesUpsert (create or update) employees in bulk
DELETE/api/public/v1/scorecards/{scorecard_id}/employees/{employee_id}Delete an employee using the BEEtoolkit-assigned ID for that employee

All requests must be authenticated using your API key and HMAC signature, consistent with the other public APIs.

Authentication

Include the following headers on every request:

  • Authorization: HMAC <signature>
  • X-Api-Key: <your account key>
  • Accept: application/json

See Authentication.


Data Model

Employee 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

FieldTypeExampleNotes
full_namestring"John Smith"Employee full name.
id_numberstring"8801010120001"13-digit SA ID. Required unless foreign = true. Used as a primary external identifier.
foreignbooleanfalseMarks the individual as a foreign national. If true, id_number may be omitted, or replaced with their passport number.
genderstring"Male"See Gender values below.
racestring"Indian"See Race values below.
designationstring"Semi-skilled"Occupational level; see Designation values below. Required when creating a new employee.
disabledbooleantrueIndicates whether the employee is a person with a disability.

Employment & Structure

FieldTypeExampleNotes
hire_datedate (string)"2024-03-15"Employment start date (YYYY-MM-DD).
termination_datedate | nullnullEmployment end date, if applicable.
latest_promotion_datedate | nullnullMost recent promotion date.
employee_codestring"333"Your internal employee identifier. Used as a secondary external identifier.
locationstring"HO"Site/branch, e.g. "HO", "Plant 1".
business_unitstring"HR"Department or business unit.
provincestring"Gauteng"Province used for reporting.
ageinteger24Age of the employee (typically at period end).
voting_rightsnumber | string0 or "0.0"Voting rights percentage (for Ownership/MC linkage where applicable).

System Fields (Response Only)

FieldTypeExampleNotes
idinteger54981057Internal ID of the employee record.
created_atdatetime"2026-01-15T07:59:32.000Z"Creation timestamp.
updated_atdatetime"2026-01-15T07:59:32.000Z"Last update timestamp.
Date formats

All dates must be provided in ISO8601 format: YYYY-MM-DD. null is accepted where a date is not applicable (e.g. termination_date, latest_promotion_date).


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

Typical supported values:

  • Male
  • Female

Race values

Typical supported values:

  • African
  • Coloured
  • Indian
  • White

Designation (Occupational level) values

Typical supported values:

  • Executive Director
  • Non-executive Director
  • Other Executive Manager
  • Senior Manager
  • Middle Manager
  • Junior Manager
  • Semi-skilled
  • Unskilled

Fetch Employees (Index)

Retrieve all employees captured against a specific scorecard.

GET /api/public/v1/scorecards/{scorecard_id}/employees
curl -X GET "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/employees"   -H "Accept: application/json"   -H "X-Api-Key: <your api key>"   -H "Authorization: HMAC <your signature>"

Example 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)

Upserts operate on multiple employees at once via a batch payload.

POST /api/public/v1/scorecards/{scorecard_id}/employees

The request body must be wrapped in 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
}
]
}
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 api 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
}
]
}'

Successful Response

On success, the API returns the upserted employees as an array, using the same shape as the index endpoint:

[
{
"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"
}
]

Matching & Upsert Rules

Each record in the employees array is processed independently.

1. External identifier requirement

Every employee record must include at least one external identifier:

  • id_number, or
  • employee_code

If neither is present for any record, the entire request fails with a 422 Unprocessable Entity and a list of offending records.

{
"error": {
"message": "Employee records must include at least one external identifier (id_number or employee_code).",
"invalid_records": [
{
"full_name": "John NoId",
"gender": "Male"
}
]
}
}

2. Matching precedence

When identifiers are present, the API applies the following precedence to find an existing record within the scorecard's Management Control structure:

  1. By id_number (if provided)
    • The system first attempts to find an existing employee where id_number matches.
  2. By employee_code (if no match was found by id_number and employee_code is provided)
    • If an employee with the same employee_code exists, that record is used.

If no matching employee is found using the above rules, a new employee record is initialised.

3. Attribute assignment

For matched or newly initialised records, the following attributes are assigned from the payload:

id_number
gender
designation
disabled
foreign
race
full_name
hire_date
termination_date
latest_promotion_date
employee_code
location
business_unit
province
age
voting_rights

Any other fields in the incoming payload are ignored.


Validation Errors

If one or more employee records fail validation (e.g. invalid ID number format), the API responds with 422 Unprocessable Entity and includes details of each invalid record.

Example (invalid SA ID number):

{
"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"
}
]
}
}