---
title: "Get a user's training status by email"
method: GET
path: "/training/status"
tags: ["Training", "Preview"]
---

# Get a user's training status by email

`GET /training/status`

## Request

- Base URL: `https://app.ketryx.com/api/v1`
- URL: `https://app.ketryx.com/api/v1/training/status`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/ketryx/apis/ketryx-api/docs/training/status/get.ts> (a function with typed inputs; its response is checked against the schema)

Returns one organization member's full training status: an overall trained flag, the statuses external systems reported, and the per-document breakdown across all of the organization's projects (or one project via projectId) plus the central project, where a project-level document wins over the same central document. Heavier the more projects and documents are in scope, since the whole scope is computed on every call.

## Query parameters

- `startAt` integer: Index to start at. Defaults to 0.
- `maxResults` integer: Maximum number of results to return
- `email` string, email, required: Email address of the organization member to query the training status for
- `projectId` string: Ketryx ID of the project, e.g., `KXPRJ12345`

## Response `200`

Successful response

- object
  - `startAt` integer, required: Index that the pagination started at
  - `maxResults` integer, required: Maximum number of results returned
  - `user` object, required: The organization member the status is for
    - `id` string, required: Ketryx ID of the user
    - `email` string, required: Normalized email address of the user
    - `name` string, nullable, required: Display name of the user
  - `isTrained` boolean, required: Whether the user has no overdue training: no required document in scope is OVERDUE and no external source reports OVERDUE. Computed over the full scope regardless of pagination, and independent of the require-training enforcement switch of each project.
  - `externalTrainingStatuses` object[], required: Training statuses reported for the user by external systems
    - `source` string, required: Source system the status was reported by
    - `status` 'TRAINED' | 'OVERDUE', required: The training status the source system reported
    - `message` string, nullable, required: Stored explanation, if any
    - `url` string, nullable, required: Stored source system link, if any
    - `updatedAt` string, date-time, required: When the status was last written
  - `documents` object[], required: The user's training status per controlled document with training configured, including NOT_REQUIRED documents, ordered by document title. Pagination applies to this list only.
    - `id` string, required: Ketryx ID of the document item
    - `itemKey` string, nullable, required: Human-readable Ketryx item key (e.g. `KX-PROJ-1`), when the organization has item keys enabled and the project has a key
    - `title` string, required: Title of the controlled document
    - `projectId` string, required: Ketryx ID of the project the document belongs to
    - `state` 'NOT_REQUIRED' | 'OVERDUE' | 'TRAINED' | 'TRAINING_PERIOD', required: The user's training state on the document. NOT_REQUIRED means the document has training configured, but not for any group the user is in. The state can be inherited from the previous controlled revision, so OVERDUE can appear while the current revision's own period is still ongoing (the previous revision was never acknowledged).
    - `trainingSchedule` 'ONCE' | 'MONTHLY' | 'QUARTERLY' | 'YEARLY', nullable, required: The recurrence of the training. Null for NOT_REQUIRED documents and documents without a schedule.
    - `currentPeriod` object, nullable, required: The training period the user is measured against: the ongoing period, or the most recent one when none is ongoing (an overdue period, or the completed sole period of a ONCE schedule, counts as current). For an overdue recurring schedule the period is anchored to the user's last acknowledgement, so its deadline can lie well in the past. Exactly one of currentPeriod and nextPeriod is set for documents with period-based training; the successor of an ongoing period is not computed. Null for legacy schedules without periods.
      - `start` string, date-time, required: When the training period starts
      - `deadline` string, date-time, required: When the training must be completed
    - `nextPeriod` object, nullable, required: The upcoming training period when none has started yet. See currentPeriod for the current-XOR-next semantics.
      - `start` string, date-time, required: When the training period starts
      - `deadline` string, date-time, required: When the training must be completed
    - `acknowledgement` object, nullable, required: The acknowledgement counting towards the user's trained state, if any
      - `acknowledgedAt` string, date-time, required: When the user acknowledged the document
      - `inheritedFromPreviousRevision` boolean, required: Whether the acknowledgement was carried over from a previous controlled revision
    - `previousAcknowledgement` object, nullable, required: The user's most recent acknowledgement on any previous controlled revision of the document, if any
      - `acknowledgedAt` string, date-time, required: When the user acknowledged the previous revision
      - `revision` integer, nullable, required: Revision number of the acknowledged record
      - `controlledRevision` integer, nullable, required: Controlled revision number of the acknowledged record

## Other responses

- `400`: Invalid input data
- `401`: Authorization not provided
- `403`: Insufficient access
- `404`: Not found
- `500`: Internal server error

---

[API](https://skmtc.dev/ketryx/apis/ketryx-api.md) - [All operations](https://skmtc.dev/ketryx/apis/ketryx-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ketryx/apis/ketryx-api/revisions/a2a484dc35ca?raw)
