> ## Documentation Index
> Fetch the complete documentation index at: https://help.skillsdb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List training records

> Training records across people — filter by email and/or skillId for the per-person and per-skill views, by status, or by expiry (expiredOnly=true, or expiresWithinDays=N for the approaching window). Bounded by the acting identity's access level. Statuses expired/pending/submitted can appear on reads but no API write produces them — they are set only by the CSV history importer.

**Requires scope:** `training:read`.



## OpenAPI

````yaml /api-docs/openapi.v1.json get /api/v1/trainings
openapi: 3.0.0
info:
  title: SkillsDB Public API
  description: >-
    The SkillsDB public REST API. Authenticate every request with an API key
    created in Settings → API Credentials, sent as `Authorization: Bearer
    sdb_live_…`. Errors follow RFC 9457 problem details; every `type` URI
    resolves under https://help.skillsdb.com/api-docs/errors/.
  version: '1'
  contact: {}
servers:
  - url: https://prod.skillsdbnext.com
    description: Production
  - url: https://staging.skillsdbnext.com
    description: Staging
security: []
tags: []
paths:
  /api/v1/trainings:
    get:
      tags:
        - Training
      summary: List training records
      description: >-
        Training records across people — filter by email and/or skillId for the
        per-person and per-skill views, by status, or by expiry
        (expiredOnly=true, or expiresWithinDays=N for the approaching window).
        Bounded by the acting identity's access level. Statuses
        expired/pending/submitted can appear on reads but no API write produces
        them — they are set only by the CSV history importer.


        **Requires scope:** `training:read`.
      operationId: listTrainings
      parameters:
        - name: email
          required: false
          in: query
          schema:
            type: string
          description: >-
            Only trainings recorded for the person with this email address
            (ENG-4110).
        - name: skillId
          required: false
          in: query
          schema:
            type: integer
          description: Only trainings recorded against this skill.
        - name: status
          required: false
          in: query
          schema:
            type: string
            enum:
              - awaiting_approval
              - approved
              - rejected
              - cancelled
              - needs_reapproval
              - expired
              - pending
              - submitted
          description: Only trainings in this status.
        - name: expiresWithinDays
          required: false
          in: query
          schema:
            type: integer
          description: Only trainings expiring within this many days from now.
        - name: expiredOnly
          required: false
          in: query
          schema:
            type: boolean
          description: Pass true to return only already-expired trainings.
        - name: limit
          required: false
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          description: Page size. Out-of-range values are rejected, never clamped.
        - name: offset
          required: false
          in: query
          schema:
            type: integer
            minimum: 0
            maximum: 10000
            default: 0
          description: Rows to skip.
      responses:
        '200':
          description: One page of the collection, enveloped.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - meta
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/TrainingRecordDto'
                  meta:
                    $ref: '#/components/schemas/CollectionMetaDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
        '400':
          description: >-
            Validation failed
            (`https://help.skillsdb.com/api-docs/errors/validation-error`)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
        '401':
          description: >-
            Invalid credential
            (`https://help.skillsdb.com/api-docs/errors/invalid-credential`)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
        '403':
          description: >-
            Insufficient scope
            (`https://help.skillsdb.com/api-docs/errors/insufficient-scope`) ·
            Insufficient permissions
            (`https://help.skillsdb.com/api-docs/errors/insufficient-permissions`)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
        '404':
          description: Not found (`https://help.skillsdb.com/api-docs/errors/not-found`)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
        '429':
          description: >-
            Rate limit exceeded
            (`https://help.skillsdb.com/api-docs/errors/rate-limit-exceeded`)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '500':
          description: >-
            Internal error
            (`https://help.skillsdb.com/api-docs/errors/internal-error`)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailsDto'
          headers:
            X-Request-Id:
              description: Unique id for this request — quote it when contacting support.
              schema:
                type: string
            RateLimit-Limit:
              description: The bucket's hourly allowance.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
      security:
        - apiKey:
            - training:read
components:
  schemas:
    TrainingRecordDto:
      type: object
      properties:
        id:
          type: string
          example: '5120'
          description: Opaque training record id.
        person:
          description: The person who was trained.
          allOf:
            - $ref: '#/components/schemas/ReferenceDto'
        skill:
          description: The skill the training proves.
          allOf:
            - $ref: '#/components/schemas/ReferenceDto'
        trainingDate:
          type: string
          example: '2026-02-10T00:00:00.000Z'
          nullable: true
        trainer:
          type: string
          example: J. Instructor
          nullable: true
          description: >-
            Free text, never a person reference — 'who trained' is unvalidated;
            'who approved' is the person in the decision.
        status:
          type: string
          enum:
            - awaiting_approval
            - approved
            - rejected
            - cancelled
            - needs_reapproval
            - expired
            - pending
            - submitted
          example: approved
        isNotApplicable:
          type: boolean
          example: false
          description: Marked not applicable — excluded without being deleted.
        evidenceNote:
          type: string
          example: Completed the practical assessment.
          nullable: true
        expiresAt:
          type: string
          example: '2027-02-10T00:00:00.000Z'
          nullable: true
          description: Expiry is a date; expired state is derived from it.
        isExpired:
          type: boolean
          example: false
          description: 'Derived: the expiry date has passed.'
        skillVersionId:
          type: string
          example: '402'
          nullable: true
          description: The skill version the training was completed against.
        requestedById:
          type: string
          example: '91'
          nullable: true
          description: Person id who submitted it for approval.
        requestedAt:
          type: string
          example: '2026-02-10T09:00:00.000Z'
          nullable: true
        delegatedApproverId:
          type: string
          example: '88'
          nullable: true
          description: Delegated approver, when one was named.
        decision:
          nullable: true
          description: The decision on this record, once decided.
          allOf:
            - $ref: '#/components/schemas/TrainingDecisionDto'
        isSuperseded:
          type: boolean
          example: false
          description: >-
            True when the record was superseded by a renewal and lives in
            training history.
        createdAt:
          type: string
          example: '2026-02-10T09:00:00.000Z'
          nullable: true
      required:
        - id
        - person
        - skill
        - trainingDate
        - trainer
        - status
        - isNotApplicable
        - evidenceNote
        - expiresAt
        - isExpired
        - skillVersionId
        - requestedById
        - requestedAt
        - delegatedApproverId
        - decision
        - isSuperseded
        - createdAt
    CollectionMetaDto:
      type: object
      properties:
        total:
          type: number
          example: 1342
          description: Total matching records.
        limit:
          type: number
          example: 50
        offset:
          type: number
          example: 0
      required:
        - total
        - limit
        - offset
    ProblemDetailsDto:
      type: object
      properties:
        type:
          type: string
          example: https://help.skillsdb.com/api-docs/errors/validation-error
          description: >-
            A URI identifying the problem type — always resolves to a
            documentation page.
        title:
          type: string
          example: Validation failed
        status:
          type: number
          example: 400
        detail:
          type: string
          example: limit must be between 1 and 200
          description: Human-readable explanation specific to this occurrence.
        instance:
          type: string
          example: /api/v1/people
        requestId:
          type: string
          example: 0192c2f1-6f4e-7ab3-b1c4-5f6a7b8c9d0e
          description: >-
            Matches the X-Request-Id response header — quote it when contacting
            support.
        errors:
          description: Field-level failures, present on validation-error problems.
          type: array
          items:
            $ref: '#/components/schemas/ProblemFieldErrorDto'
        error:
          type: string
          example: trial_expired
          enum:
            - trial_expired
          description: >-
            Present only on a 403 when the workspace's trial has expired, so API
            access is suspended.
        upgrade_url:
          type: string
          example: https://app.skillsdb.com/settings/billing
          description: >-
            Present only alongside `error: trial_expired`: where a workspace
            admin upgrades to restore API access.
      required:
        - type
        - title
        - status
        - detail
        - instance
        - requestId
    ReferenceDto:
      type: object
      properties:
        id:
          type: string
          example: '42'
          description: Opaque resource id.
        name:
          type: string
          example: Welding
          description: Display name.
      required:
        - id
        - name
    TrainingDecisionDto:
      type: object
      properties:
        outcome:
          type: string
          enum:
            - approved
            - rejected
            - cancelled
          example: approved
        decidedById:
          type: string
          example: '88'
          nullable: true
          description: Person id who decided.
        decidedAt:
          type: string
          example: '2026-03-02T14:00:00.000Z'
          nullable: true
        reason:
          type: string
          example: null
          nullable: true
          description: Reason, for rejections and cancellations.
      required:
        - outcome
        - decidedById
        - decidedAt
        - reason
    ProblemFieldErrorDto:
      type: object
      properties:
        field:
          type: string
          example: email
        code:
          type: string
          example: max_length
        message:
          type: string
          example: email must be shorter than or equal to 75 characters
      required:
        - field
        - code
        - message
  securitySchemes:
    apiKey:
      scheme: bearer
      type: http
      description: >-
        An API key issued by a company administrator — an environment prefix
        (production: `sdb_live_`) followed by 32 characters. The prefix
        identifies the environment and MUST NOT be hard-coded or validated by
        clients; treat the whole key as opaque. Shown exactly once at creation;
        only a one-way hash is stored.


        **Scopes** (granted per key on the create screen; `:write` never implies
        `:read`):


        - `skills:read`

        - `skills:write`

        - `people:read`

        - `people:write`

        - `careers:read`

        - `careers:write`

        - `training:read`

        - `training:write`

        - `flags:read`

        - `flags:write`

        - `org:read`

        - `org:write`

        - `assessments:read`

        - `learning:read`

        - `learning:write`

        - `certifications:read`

        - `certifications:write`

        - `assessments:write`

        - `proficiency:read`

        - `proficiency:write`

        - `surveys:read`

        - `surveys:write`

        - `labels:read`

        - `labels:write`

````