API reference

Employee status

Two read endpoints answer where an employee stands: /today for the gate question ("did they finish today's lesson?") plus a launch URL when they have not, and /week for a full-week view suited to kiosks and mobile apps. In both, {externalId} is your employee code, the id your systems already use.

Try it now

Every example below runs as-is against the sandbox company "Acme Logistics" using the public sandbox key tbm_test_wWlSr6q-BPXUN67BPbzyVhR703QGmSlk34EEWGqRBtA. It has employees E-1001 through E-1008 (the examples use E-1001, Dana Worker), and its return URL allowlist contains https://example.com/return, http://localhost:3000/return, and http://localhost:5173/return. Sandbox data resets nightly at 04:00 UTC.

Today's status

GET /api/v1/employees/{externalId}/today

Returns the employee's status for today's lesson, where "today" is the calendar day in the employee's timezone. While the lesson is incomplete (not_started or in_progress) the response includes a single-use launchUrl; redirect the employee there to play the lesson. When the status is completed or no_lesson_scheduled, launchUrl is null.

Path parameters

ParameterTypeDescription
externalIdstringThe employee's external id (your employee code).

Query parameters

ParameterTypeDescription
returnUrlstring, optional Where we send the employee after they finish the lesson. Must exactly match an entry in your return URL allowlist, configured in Admin > Settings. Matching is exact (no wildcards, no prefix matching), which is what rules out open redirects. When omitted, the tenant default applies (the first allowlisted entry). Only used on calls that mint a launchUrl.

Response fields

FieldTypeDescription
externalIdstringEchoes the id you called with.
lessonDatestringToday as yyyy-MM-dd in the employee's timezone.
statusstringOne of the four status values below.
lessonobject or nullToday's lesson; null when nothing is scheduled.
lesson.lessonIdstring (uuid)The lesson's id.
lesson.titlestringThe lesson's title.
lesson.videoDurationSecondsnumberVideo length in seconds.
subTopicstring or nullThe subtopic (this week's theme).
topicstring or nullThe topic the subtopic belongs to.
launchUrlstring or nullSingle-use URL to redirect the employee to; present only while the lesson is incomplete.

Status values

ValueMeaninglaunchUrl
completedFinished today's lesson.null
in_progressStarted today's lesson, not finished.Present
not_startedHas not begun today's lesson.Present
no_lesson_scheduledNothing is due today. lesson is null.null

Launch token semantics

  • The launchUrl carries an opaque token. It is single-use: the first visit establishes the viewer session and consumes it. Repeat exchange within the TTL is tolerated, so link prefetchers and double taps do not strand the employee.
  • Tokens expire roughly 30 minutes after minting.
  • Every call to /today while the lesson is incomplete mints a fresh URL. Redirect with the latest one; never store launch URLs or embed them in anything long-lived.
  • The employee arrives anonymously through the token. No Toolbox Minute account or password is involved.

Request

curl -H "X-Api-Key: tbm_test_wWlSr6q-BPXUN67BPbzyVhR703QGmSlk34EEWGqRBtA" \
  "https://toolboxminute.com/api/v1/employees/E-1001/today?returnUrl=https%3A%2F%2Fexample.com%2Freturn"

Response, lesson not started

# HTTP/1.1 200 OK
{
  "externalId": "E-1001",
  "lessonDate": "2026-07-15",
  "status": "not_started",
  "lesson": {
    "lessonId": "7f2f0d3a-4c1e-4b6e-9a2d-8f5c3b1e6d40",
    "title": "Pedestrian Awareness",
    "videoDurationSeconds": 62
  },
  "subTopic": "Forklift Safety",
  "topic": "Powered Equipment",
  "launchUrl": "https://toolboxminute.com/viewer/start?token=nZ3Kx0mW..."
}

Response, lesson completed

# HTTP/1.1 200 OK
{
  "externalId": "E-1001",
  "lessonDate": "2026-07-15",
  "status": "completed",
  "lesson": {
    "lessonId": "7f2f0d3a-4c1e-4b6e-9a2d-8f5c3b1e6d40",
    "title": "Pedestrian Awareness",
    "videoDurationSeconds": 62
  },
  "subTopic": "Forklift Safety",
  "topic": "Powered Equipment",
  "launchUrl": null
}

Errors

Unknown external id:

# HTTP/1.1 404 Not Found
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
  "title": "unknown_user",
  "status": 404,
  "detail": "No employee was found for external id 'E-9999'."
}

returnUrl not on the allowlist:

# HTTP/1.1 400 Bad Request
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "invalid_return_url",
  "status": 400,
  "detail": "The returnUrl is not in this tenant's allowlist."
}

This week's schedule

GET /api/v1/employees/{externalId}/week

Returns the employee's current week: one entry per calendar day from weekStart through weekEnd (per the company's configured week start day), each with its lesson, status, and whether it can be completed right now. Use it to render a week view in a kiosk or mobile app.

Path parameters

ParameterTypeDescription
externalIdstringThe employee's external id (your employee code).

Response fields

FieldTypeDescription
externalIdstringEchoes the id you called with.
weekStartstringFirst day of the current week, yyyy-MM-dd.
weekEndstringLast day of the current week, yyyy-MM-dd.
timeZonestringThe employee's effective IANA timezone, for example America/Chicago.
subTopicobject or nullThe week's subtopic; null when nothing is scheduled this week.
subTopic.idstring (uuid) or nullThe subtopic's id.
subTopic.namestring or nullThe subtopic's name.
subTopic.topicstring or nullThe topic the subtopic belongs to.
workAheadEnabledbooleanWhether this employee may complete future days within the current week.
daysarrayOne entry per calendar day, weekStart through weekEnd.
days[].datestringThe day, yyyy-MM-dd.
days[].dayIndexnumber or nullThe day's position within the subtopic (0 is the week's first lesson); null when nothing is scheduled.
days[].lessonNamestring or nullThe scheduled lesson's title; null when nothing is scheduled.
days[].statusstringSame four values as /today.
days[].canCompletebooleanWhether the employee may complete this day's lesson right now.
days[].denyReasonstring or nullWhy canComplete is false; null when it is true, and also null on already-completed days.

Deny reasons

ValueMeaning
PastDayThe day is in the past; missed lessons cannot be back-filled.
FutureDayWorkAheadOffThe day is in the future and work-ahead is off for this employee.
BeyondCurrentWeekThe day is beyond the current week (work-ahead never crosses the week boundary).
NoLessonScheduledNothing is scheduled for that day.
EmployeeInactiveThe employee has been deactivated.

Request

curl -H "X-Api-Key: tbm_test_wWlSr6q-BPXUN67BPbzyVhR703QGmSlk34EEWGqRBtA" \
  "https://toolboxminute.com/api/v1/employees/E-1001/week"

Response

Taken on a Wednesday, for an employee with work-ahead off:

# HTTP/1.1 200 OK
{
  "externalId": "E-1001",
  "weekStart": "2026-07-13",
  "weekEnd": "2026-07-19",
  "timeZone": "America/Chicago",
  "subTopic": {
    "id": "1b8a4a6e-2f7d-49c3-b6a1-0c9d2e5f7a13",
    "name": "Forklift Safety",
    "topic": "Powered Equipment"
  },
  "workAheadEnabled": false,
  "days": [
    { "date": "2026-07-13", "dayIndex": 0, "lessonName": "Pre-Shift Inspection", "status": "completed", "canComplete": false, "denyReason": null },
    { "date": "2026-07-14", "dayIndex": 1, "lessonName": "Load Limits & Stability", "status": "not_started", "canComplete": false, "denyReason": "PastDay" },
    { "date": "2026-07-15", "dayIndex": 2, "lessonName": "Pedestrian Awareness", "status": "in_progress", "canComplete": true, "denyReason": null },
    { "date": "2026-07-16", "dayIndex": 3, "lessonName": "Safe Travel & Speed", "status": "not_started", "canComplete": false, "denyReason": "FutureDayWorkAheadOff" },
    { "date": "2026-07-17", "dayIndex": 4, "lessonName": "Parking & Shutdown", "status": "not_started", "canComplete": false, "denyReason": "FutureDayWorkAheadOff" },
    { "date": "2026-07-18", "dayIndex": null, "lessonName": null, "status": "no_lesson_scheduled", "canComplete": false, "denyReason": "NoLessonScheduled" },
    { "date": "2026-07-19", "dayIndex": null, "lessonName": null, "status": "no_lesson_scheduled", "canComplete": false, "denyReason": "NoLessonScheduled" }
  ]
}

Errors

Unknown external id returns 404 unknown_user, the same shape as /today above.

Note: canComplete is a UI hint. The completion write path re-checks the same rules server-side, so showing a stale flag can never let an employee complete a day they should not.