Training Programs
Training programs represent Skills Development training captured on a BEEtoolkit Scorecard. This API allows you to create, retrieve, and delete training programs for a specific scorecard.
Training data is always scoped to a single scorecard and stored against that scorecard's ID. Participants belong to exactly one training program, and each training program can have many participants. See Training Program Participants.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/public/v1/scorecards/{scorecard_id}/training_programs | Retrieve all training programs for a scorecard |
POST | /api/public/v1/scorecards/{scorecard_id}/training_programs | Create or update training programs for a scorecard |
DELETE | /api/public/v1/scorecards/{scorecard_id}/training_programs/{id} | Delete a single training program |
Include the following headers on every request:
Authorization: HMAC <signature>X-Api-Key: <your account key>Accept: application/json
See Authentication.
Attributes
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Training program name. |
category | string | yes | Training category code: A, B, C, D, E, F or G, as per the B-BBEE codes. |
abet | boolean | no | Indicates ABET training. |
scholarship | boolean | no | Indicates a scholarship program. |
municipality | string | null | no | Municipality name when applicable. |
mandatory | boolean | no | Indicates mandatory training. |
training_provider | string | null | no | Training provider name when applicable. |
scarce_or_critical_skills | boolean | no | Indicates scarce or critical skills training. |
rail_related | boolean | no | Indicates rail-related training. |
is_tourism_related_expenditure | boolean | no | Indicates tourism-related expenditure. |
bursary_program | boolean | no | Indicates a bursary program. |
invoice_transaction_date | string | no | Invoice transaction date (YYYY-MM-DD). |
specialised_areas_of_law | string | null | no | Specialised legal area when applicable. |
continuous_legal_education_program | string | null | no | CLE program when applicable. |
System Fields (Response Only)
| Field | Type | Description |
|---|---|---|
id | integer | Internal identifier for the training program. |
total_number_of_participants | integer | Number of participants in this program. |
created_at | datetime | Record creation timestamp. |
updated_at | datetime | Record update timestamp. |
Notes
- Records are matched by the combination of
name,category,abet,mandatory,training_provider, andmunicipality. If a match exists, the record is updated; otherwise it is created. - Dates must be in ISO 8601 format (
YYYY-MM-DD). - After creating, updating, or deleting training programs, recalculate the scorecard to refresh totals.
List training programs
Returns a paginated list of training programs for a scorecard.
GET /api/public/v1/scorecards/{scorecard_id}/training_programs
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
scorecard_id | string | yes | The scorecard identifier. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | no | Page number (min 1, max 100000). Default is 1. |
per_page | integer | no | Page size (min 1, max 1000). Default is 50. |
Code examples
- cURL
- JavaScript (axios)
curl -X GET "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/training_programs?page=1&per_page=50" \
-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}/training_programs`;
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
Returns a JSON object with data and meta keys.
{
"data": [
{
"id": 32003,
"name": "Excel Advanced",
"category": "E",
"abet": true,
"scholarship": false,
"municipality": null,
"mandatory": false,
"training_provider": null,
"scarce_or_critical_skills": false,
"rail_related": false,
"is_tourism_related_expenditure": false,
"bursary_program": false,
"invoice_transaction_date": "2021-03-21",
"specialised_areas_of_law": null,
"continuous_legal_education_program": null,
"total_number_of_participants": 13,
"created_at": "2026-02-10T07:23:33.000Z",
"updated_at": "2026-02-10T07:23:34.000Z"
}
],
"meta": {
"prev_url": null,
"next_url": null,
"count": 1,
"page": 1,
"items": 50,
"pages": 1
}
}
Create or update training programs
Creates training programs for a scorecard. Records are matched by the combination of name, category, abet, mandatory, training_provider, and municipality. If a match exists, the record is updated; otherwise it is created.
POST /api/public/v1/scorecards/{scorecard_id}/training_programs
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
scorecard_id | string | yes | The scorecard identifier. |
Request body
Send a JSON object with a training_programs array:
{
"training_programs": [
{
"name": "Leadership Development Program",
"category": "E",
"abet": false,
"scholarship": false,
"municipality": "Johannesburg",
"mandatory": false,
"training_provider": "ABC Training Solutions",
"scarce_or_critical_skills": false,
"invoice_transaction_date": "2024-01-15"
}
]
}
Code examples
- cURL
- JavaScript (axios)
curl -X POST "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/training_programs" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>" \
-d '{
"training_programs": [
{
"name": "Leadership Development Program",
"category": "E",
"abet": false,
"scholarship": false,
"municipality": "Johannesburg",
"mandatory": false,
"training_provider": "ABC Training Solutions",
"scarce_or_critical_skills": false,
"invoice_transaction_date": "2024-01-15"
}
]
}'
const scorecardId = "scorecard_mG712bEVavpq3ukr0Z5R89qY";
const url = `https://www.beetoolkit.co.za/api/public/v1/scorecards/${scorecardId}/training_programs`;
const payload = {
training_programs: [
{
name: "Leadership Development Program",
category: "E",
abet: false,
scholarship: false,
municipality: "Johannesburg",
mandatory: false,
training_provider: "ABC Training Solutions",
scarce_or_critical_skills: false,
invoice_transaction_date: "2024-01-15",
},
],
};
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
Returns the created or updated training program records.
[
{
"id": 32005,
"name": "Leadership Development Program",
"category": "E",
"abet": false,
"scholarship": false,
"municipality": "Johannesburg",
"mandatory": false,
"training_provider": "ABC Training Solutions",
"scarce_or_critical_skills": false,
"rail_related": false,
"is_tourism_related_expenditure": false,
"bursary_program": false,
"invoice_transaction_date": "2024-01-15",
"specialised_areas_of_law": null,
"continuous_legal_education_program": null,
"total_number_of_participants": 0,
"created_at": "2026-02-10T07:23:33.000Z",
"updated_at": "2026-02-10T07:23:33.000Z"
}
]
After creating or updating training programs, call the scorecard recalculate endpoint to refresh scores: Recalculate a scorecard.
Errors
| Status | Description |
|---|---|
422 | One or more training program records are invalid. |
422 | The scorecard type does not support training programs. |
{
"error": {
"message": "One or more training program records are invalid.",
"invalid_records": [
{
"name": "Leadership Development Program",
"category": "z",
"abet": false,
"mandatory": false,
"training_provider": "ABC Training Solutions",
"municipality": "Johannesburg",
"errors": [
"Category is not a valid category"
]
}
]
}
}
Delete a training program
Deletes a single training program by ID. The endpoint returns 204 No Content even if the ID does not exist for the scorecard.
DELETE /api/public/v1/scorecards/{scorecard_id}/training_programs/{id}
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
scorecard_id | string | yes | The scorecard identifier. |
id | integer | yes | Training program ID. |
Code examples
- cURL
- JavaScript (axios)
curl -X DELETE "https://www.beetoolkit.co.za/api/public/v1/scorecards/{scorecard_id}/training_programs/{id}" \
-H "Accept: application/json" \
-H "X-Api-Key: <your account key>" \
-H "Authorization: HMAC <your signature>"
const scorecardId = "scorecard_mG712bEVavpq3ukr0Z5R89qY";
const trainingProgramId = 32005;
const url = `https://www.beetoolkit.co.za/api/public/v1/scorecards/${scorecardId}/training_programs/${trainingProgramId}`;
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 training programs, call the scorecard recalculate endpoint to refresh scores: Recalculate a scorecard.
Errors
| Status | Description |
|---|---|
422 | The scorecard type does not support training programs. |