openapi: 3.1.1
info:
  title: TimeBack Platform - Auth API
  description: Authentication and authorization endpoints
  version: 1.0.0
tags:
  - name: Auth
    description: Authentication and authorization endpoints
servers:
  - url: https://platform.dev.timeback.com
    description: integration
paths:
  /auth/1.0/token:
    post:
      tags:
        - Auth
      summary: Request an access token
      description: Used to request a new token with the grant_type "client_credentials"
      operationId: getToken
      security:
        - BasicAuth: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TokenRequest'
      responses:
        '200':
          description: Token response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  schemas:
    TokenRequest:
      type: object
      required:
        - grant_type
      properties:
        grant_type:
          type: string
          enum:
            - client_credentials
        scope:
          type: string
          description: Space-separated list of scopes
        authorization_details:
          type: string
          description: >-
            RFC 9396 Rich Authorization Requests (subset). URL-encoded JSON
            array of typed objects. Supported type: "org_scope" with "locations"
            containing org UUIDs to narrow the token's org scope. The value must
            be URL-encoded in the form body. Decoded example:
            [{"type":"org_scope","locations":["org-uuid-1","org-uuid-2"]}]. The
            token's custom:orgRoles claim will contain only the requested orgs
            (must be a subset of the client's allowed orgs).
    TokenResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
      properties:
        access_token:
          type: string
        token_type:
          type: string
          enum:
            - bearer
        expires_in:
          type: integer
          description: Token expiration time in seconds
        scope:
          type: string
          description: Space-separated list of granted scopes
  responses:
    Unauthorized:
      description: Unauthorized
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: >-
        Basic authentication using client_id as username and client_secret as
        password
    CognitoUserPoolAuthorizer:
      type: oauth2
      description: >-
        OAuth 2.0 client credentials flow. Contact timeback@trilogy.com to
        request credentials for your application.
      flows:
        clientCredentials:
          tokenUrl: https://platform.dev.timeback.com/auth/1.0/token
          scopes:
            https://purl.imsglobal.org/spec/or/v1p2/scope/roster.readonly: roster readonly
            https://purl.imsglobal.org/spec/or/v1p2/scope/roster-core.readonly: roster-core readonly
            https://purl.imsglobal.org/spec/or/v1p2/scope/roster.createput: roster createput
            https://purl.imsglobal.org/spec/lti/v1p3/scope/lti.readonly: lti readonly
            https://purl.imsglobal.org/spec/or/v1p2/scope/roster-core.createput: roster-core createput
            https://purl.imsglobal.org/spec/or/v1p2/scope/roster.delete: roster delete
            https://purl.imsglobal.org/spec/or/v1p2/scope/roster-core.delete: roster-core delete
            https://purl.imsglobal.org/spec/case/v1p0/scope/case.readonly: case readonly
            https://purl.imsglobal.org/spec/case/v1p0/scope/case.createput: case createput
            https://purl.imsglobal.org/spec/case/v1p0/scope/case.delete: case delete
            https://timeback-platform.trilogy.com/competency-track/scope/competency-track.readonly: competency-track readonly
            https://timeback-platform.trilogy.com/competency-track/scope/competency-track.write: competency-track write
            https://timeback-platform.trilogy.com/competency-track/scope/competency-track.delete: competency-track delete
            https://purl.imsglobal.org/spec/caliper/v1p2/scope/events.write: events write
            https://purl.imsglobal.org/spec/caliper/v1p2/scope/events.readonly: events readonly
  parameters:
    limit:
      name: limit
      in: query
      description: Maximum number of items to return
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 10
    offset:
      name: offset
      in: query
      description: Number of items to skip
      required: false
      schema:
        type: integer
        minimum: 0
        default: 0
    sort:
      name: sort
      in: query
      description: Field to sort by
      required: false
      schema:
        type: string
    orderBy:
      name: orderBy
      in: query
      description: Sort direction
      required: false
      schema:
        type: string
        enum:
          - ASC
          - DESC
        default: ASC
    fields:
      name: fields
      in: query
      description: >
        Comma-separated list of fields to include in the response.

        Available fields: sourcedId, status, dateCreated, dateLastModified,
        metadata, applicationType, name, description, isLtiCompliant,
        isLtiV1P3Compliant, isRecordingEnabled, idlingThreshold, launchUrl,
        landingUrl, homepageUrl, clientId, deploymentId, version, domains,
        fullDescription, learningAppSpecification, gradeRangeStart,
        gradeRangeEnd, languageSupport, caliperSupport, tags, publisherName,
        wasteMeter, idling, proctoringMode, subjects, logoUrl, coverImageUrl,
        tools (deprecated), tools.sourcedId (deprecated), tools.status
        (deprecated), tools.name (deprecated), tools.description (deprecated),
        tools.launchUrl (deprecated), tools.logoUrl (deprecated),
        tools.coverImageUrl (deprecated), tools.deploymentId (deprecated),
        tools.version (deprecated), tools.domains (deprecated),
        tools.fullDescription (deprecated), tools.gradeRangeStart (deprecated),
        tools.gradeRangeEnd (deprecated), tools.languageSupport (deprecated),
        tools.caliperSupport (deprecated), tools.tags (deprecated),
        tools.publisherName (deprecated), tools.wasteMeter (deprecated),
        tools.idling (deprecated), tools.proctoringMode (deprecated),
        tools.subjects (deprecated)
      required: false
      schema:
        type: string
      style: form
      explode: false
    filter:
      name: filter
      in: query
      description: >
        Filter results using OneRoster syntax: filter=<field><predicate><value>

        Predicates: = (equals), != (not equals), ~ (contains), >, >=, <, <=

        Logical operators: AND, OR (max 2 predicates per OneRoster spec)

        Available fields: sourcedId, status, name, description, tools.sourcedId
        (deprecated), tools.name (deprecated), tools.status (deprecated)

        Example: filter=name='MyApp'
      required: false
      schema:
        type: string
    documentIds:
      name: documentIds
      in: query
      description: >-
        Comma-separated list of document IDs to filter curriculum by specific
        packages
      required: true
      schema:
        type: string
      examples:
        default:
          value: >-
            c1d2e3f4-g5h6-7890-ijkl-mn1234567890,d2e3f4g5-h6i7-8901-jklm-no2345678901
    subjectIds:
      name: subjectIds
      in: query
      description: Comma-separated list of subject IDs to filter by
      required: true
      schema:
        type: string
      examples:
        default:
          value: >-
            fb375793-75d8-11ea-b707-067ee555162f,a1b2c3d4-e5f6-7890-abcd-ef1234567890
    courseIds:
      name: courseIds
      in: query
      description: Comma-separated list of course IDs to filter by
      required: false
      schema:
        type: string
      examples:
        default:
          value: >-
            5ef7ba25-fff5-11ed-bfbf-0e2145d6cfdf,b2c3d4e5-f6g7-8901-bcde-f23456789012
    limit1:
      name: limit
      in: query
      description: Maximum number of items to return
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    type:
      name: type
      in: query
      description: >-
        Comma-separated list of insight type slugs to filter by (e.g.,
        Journal,AwayFromSeat). Takes precedence over category and default.
      required: false
      schema:
        type: string
        examples:
          - Journal,AwayFromSeat
    category:
      name: category
      in: query
      description: >-
        Comma-separated list of categories to filter by (e.g.,
        Engagement,Proctoring,Cheating). Takes precedence over default but is
        overridden by type.
      required: false
      schema:
        type: string
        examples:
          - Engagement,Proctoring,Cheating
    orderBy1:
      name: orderBy
      in: query
      description: Sort direction
      required: false
      schema:
        type: string
        enum:
          - ASC
          - DESC
    fields1:
      name: fields
      in: query
      description: Comma-separated list of fields to include
      required: false
      schema:
        type: string
      style: form
      explode: false
    fields2:
      name: fields
      in: query
      description: >
        Comma-separated list of fields to include in the response.

        Available fields: sourcedId, status, dateLastModified, username,
        enabledUser, givenName, familyName, middleName, email, phone, sms,
        identifier, roles, grades, agents, userIds, userMasterIdentifier,
        preferredFirstName, preferredMiddleName, preferredLastName,
        primaryOrg.sourcedId, primaryOrg.type, userProfiles,
        userProfiles.profileId, userProfiles.profileType, userProfiles.vendorId,
        userProfiles.applicationId
      required: false
      schema:
        type: string
      style: form
      explode: false
    filter1:
      name: filter
      in: query
      description: >
        Filter results using OneRoster syntax: filter=<field><predicate><value>

        Predicates: = (equals), != (not equals), ~ (contains), >, >=, <, <=

        Logical operators: AND, OR (max 2 predicates per OneRoster spec)

        Available fields: sourcedId, status, email, familyName, givenName,
        middleName, username, enabledUser, identifier, roles

        Example: filter=email='john@example.com'
      required: false
      schema:
        type: string
    sourcedId:
      name: sourcedId
      in: path
      description: Unique identifier of the CASE entity
      required: true
      schema:
        type: string
    fields21:
      name: fields
      in: query
      description: Comma-separated list of fields to include
      required: false
      schema:
        type: string
      style: form
      explode: false
    since:
      name: since
      in: query
      description: The date and time to filter credentials by
      required: false
      schema:
        type: string
        format: date-time
        examples:
          - {}
