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

# Register a draft application

> Registers a new application in draft status and provisions OAuth client
credentials for the client credentials flow.

The response includes `applicationId`, `appUrn`, `publisherId`, the
non-secret `productionCredentials` (and, on the happy path,
`sandboxCredentials`), and a single `secretClaimUrl`. No `clientSecret`
is returned inline (ITD 9): opening `secretClaimUrl` forces a Google-IdP
SSO sign-in and reveals every minted secret once. The accompanying
`securityNote` warns agents not to open the URL on the developer's
behalf.

If your account is linked to more than one publisher, include `publisherId`
in the request body. If you belong to zero or one publisher, omit
`publisherId` and the platform assigns or creates the appropriate publisher.



## OpenAPI

````yaml /openapi/learn-with-ai/platform-api.yaml post /applications/1.0/drafts
openapi: 3.1.1
info:
  title: TimeBack Platform API
  description: >-
    RESTful API for the TimeBack Platform. Covers authentication, rostering,
    curriculum, insights, assessments, content grading, and more.
  version: 2026.09.10.1
servers:
  - url: https://platform.dev.timeback.com
    description: integration
security: []
tags:
  - name: Auth
    description: Authentication and authorization endpoints
  - name: Organizations
    description: Organizations module contains all endpoints around organization management
  - name: Applications
    description: Applications module contains all endpoints for managing LTI applications
  - name: Users
    description: >-
      Users module contains all endpoints around user creation, update and
      consultation
  - name: Students
    description: Students module contains all endpoints around student management
  - name: Demographics
    description: >-
      Demographics module contains all endpoints around demographics
      consultation
  - name: Consent
    description: >-
      Initiate and query TimeBack parental consent for a student, backed by an
      immutable audit trail.
  - name: Classes
    description: Classes module contains all endpoints around class management
  - name: Courses
    description: Courses module contains all endpoints around course management
  - name: Enrollments
    description: Enrollments module contains all endpoints around enrollment consultation
  - name: CASE
    description: Competency and Academic Standards Exchange (CASE) 1.1 API
  - name: Curriculum
    description: Curriculum module contains endpoints for managing curriculum data
  - name: Competency Track
    description: Competency track endpoints
  - name: Content Grading
    description: >-
      Registration and management of graders for free-response content items —
      bring-your-own external graders (Tier 2) and, once shipped,
      platform-managed grading prompts (Tier 1).
  - name: Caliper
    description: The Caliper module contains all endpoints around Caliper Analytics
  - name: Insights
    description: Coaching insights and session analytics endpoints
paths:
  /applications/1.0/drafts:
    post:
      tags:
        - Applications
      summary: Register a draft application
      description: >-
        Registers a new application in draft status and provisions OAuth client

        credentials for the client credentials flow.


        The response includes `applicationId`, `appUrn`, `publisherId`, the

        non-secret `productionCredentials` (and, on the happy path,

        `sandboxCredentials`), and a single `secretClaimUrl`. No `clientSecret`

        is returned inline (ITD 9): opening `secretClaimUrl` forces a Google-IdP

        SSO sign-in and reveals every minted secret once. The accompanying

        `securityNote` warns agents not to open the URL on the developer's

        behalf.


        If your account is linked to more than one publisher, include
        `publisherId`

        in the request body. If you belong to zero or one publisher, omit

        `publisherId` and the platform assigns or creates the appropriate
        publisher.
      operationId: registerAppAsDraft
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterAppAsDraftRequest'
      responses:
        '201':
          description: Draft App registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterAppAsDraftResponse'
        '400':
          $ref: '#/components/responses/BadRequest2'
        '403':
          description: Caller is not a member of the requested publisher
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError1'
        '409':
          description: Application name already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError1'
        '500':
          $ref: '#/components/responses/InternalError2'
      security:
        - CognitoUserPoolAuthorizer: []
components:
  schemas:
    RegisterAppAsDraftRequest:
      type: object
      description: Request body for `POST /applications/1.0/drafts`.
      required:
        - name
        - description
        - launchUrl
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 256
          description: >-
            Display name of the App; must be unique across the developer
            platform.
        description:
          type: string
          minLength: 1
          maxLength: 1024
          description: Short description (max 1024 chars).
        launchUrl:
          type: string
          format: uri
          maxLength: 512
          description: URL to which LTI launch messages will be posted.
        applicationType:
          $ref: '#/components/schemas/LtiApplicationType'
        publisherId:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            Optional Publisher ID. Omit when the caller belongs to zero or one
            Publisher. Required when multiple memberships exist; the service
            returns 400 with a `nextAction` otherwise.
    RegisterAppAsDraftResponse:
      type: object
      description: |-
        Response from `POST /applications/1.0/drafts`. Returns the non-secret
        production-draft credentials and, on the happy path, the non-secret
        sandbox credentials. No `clientSecret` is returned inline (ITD 9): the
        secret(s) are revealed once via the single SSO-gated `secretClaimUrl`.

        On a sandbox transient failure the production side still commits:
        `sandboxCredentials` is null and `sandboxStatus` is `pending`; the App
        is reconciled by the hourly sandbox-provisioning reconciler.
      required:
        - appUrn
        - applicationId
        - publisherId
        - productionCredentials
        - sandboxStatus
        - secretClaimUrl
        - securityNote
      properties:
        appUrn:
          $ref: '#/components/schemas/AppUrn'
        applicationId:
          type: string
          format: uuid
          description: Unique identifier of the newly registered draft application.
        publisherId:
          type: string
          format: uuid
          description: >-
            Publisher that owns this application (assigned automatically or from
            your request).
        productionCredentials:
          $ref: '#/components/schemas/RegisteredCredentials'
        sandboxCredentials:
          oneOf:
            - $ref: '#/components/schemas/RegisteredCredentials'
            - type: 'null'
          description: >-
            Sandbox credentials valid against `sandbox.platform.timeback.com`.
            Null when `sandboxStatus` is `pending`.
        sandboxStatus:
          type: string
          enum:
            - provisioned
            - pending
          description: >-
            `provisioned` when both credential sets are returned; `pending` when
            this response carries no sandbox credentials — either the sandbox
            side has not completed (the hourly sandbox-provisioning reconciler
            finishes it) or it was provisioned concurrently and the secret must
            be claimed via `rotate_credentials` (`get_app_credentials` then
            reports `awaiting_secret_claim`).
        secretClaimUrl:
          type: string
          format: uri
          description: >-
            Single signed, single-use URL that reveals every minted client
            secret once, behind a Google-IdP SSO gate. The developer must open
            it in their own browser.
        securityNote:
          type: string
          description: >-
            Warning that the agent must not open `secretClaimUrl` on the
            developer's behalf; the secret is shown only to the authenticated
            developer and never returned through the API.
    ApiError1:
      type: object
      description: >-
        Structured API error envelope. May include `docsUrl` and `nextAction` to
        guide recovery.
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Stable error code (matches `ApiError.name` on the server).
        message:
          type: string
          description: Human-readable error message.
        docsUrl:
          type: string
          format: uri
          description: Documentation URL for the failing surface.
        nextAction:
          type: string
          description: One-sentence instruction describing how to recover from this error.
        offendingField:
          type: string
          description: >-
            When the error is field-scoped, the request field that caused the
            failure.
        fields:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
            required:
              - field
              - message
    LtiApplicationType:
      type: string
      description: Type of the LTI application
      enum:
        - learning_app
        - assessment
        - internal
    AppUrn:
      type: string
      description: |
        Canonical URN identifying your registered application.

        Format: `urn:uuid:{applicationId}` (RFC 4122). Use this value as Caliper
        `edApp.id` when emitting events from your app.
      pattern: >-
        ^urn:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
      examples:
        - urn:uuid:53f0d94d-786d-409a-b5eb-7a6c1db8957b
    RegisteredCredentials:
      type: object
      description: |-
        One non-secret OAuth credential set (client credentials flow). The
        `clientSecret` is NOT returned inline (ITD 9): it is revealed once via
        the SSO-gated `secretClaimUrl` on the parent response.
      required:
        - clientId
        - tokenUrl
        - scopes
      properties:
        clientId:
          type: string
          description: >-
            OAuth client ID for authenticating your application (client
            credentials flow).
        tokenUrl:
          type: string
          format: uri
          description: >-
            Token endpoint for this environment. POST `client_id` +
            `client_secret` with `grant_type=client_credentials` to mint an
            access token.
        scopes:
          type: array
          items:
            type: string
          description: OAuth scopes authorized on this client.
    imsxStatusInfoDType:
      description: >
        This is the container for the status code and associated information
        returned within the HTTP messages received from the Service Provider.
      type: object
      required:
        - imsx_codeMajor
        - imsx_severity
      properties:
        imsx_codeMajor:
          description: |
            The code major value (from the corresponding enumerated vocabulary).
          type: string
          enum:
            - success
            - processing
            - failure
            - unsupported
        imsx_severity:
          description: |
            The severity value (from the corresponding enumerated vocabulary).
          type: string
          enum:
            - status
            - warning
            - error
        imsx_description:
          description: >-
            A human readable description supplied by the entity creating the
            status code information.
          type: string
        imsx_CodeMinor:
          $ref: '#/components/schemas/imsxCodeMinorDType'
      additionalProperties: false
    imsxCodeMinorDType:
      description: >
        This is the container for the set of code minor status codes reported in
        the responses from the Service Provider.
      type: object
      required:
        - imsx_codeMinorField
      properties:
        imsx_codeMinorField:
          description: |
            Each reported code minor status code.
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/imsxCodeMinorFieldDType'
      additionalProperties: false
    imsxCodeMinorFieldDType:
      description: |
        This is the container for a single code minor status code.
      type: object
      required:
        - imsx_codeMinorFieldName
        - imsx_codeMinorFieldValue
      properties:
        imsx_codeMinorFieldName:
          description: >-
            This should contain the identity of the system that has produced the
            code minor status code report. In most cases this will be the target
            service provider denoted as 'TargetEndSystem'.
          type: string
          default: TargetEndSystem
        imsx_codeMinorFieldValue:
          description: >
            The code minor status code (this is a value from the corresponding
            enumerated vocabulary).
          type: string
          enum:
            - fullsuccess
            - invalid_filter_field
            - invalid_selection_field
            - invaliddata
            - unauthorisedrequest
            - forbidden
            - server_busy
            - unknownobject
            - internal_server_error
      additionalProperties: false
  responses:
    BadRequest2:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/imsxStatusInfoDType'
          examples:
            invalidData:
              value:
                imsx_codeMajor: failure
                imsx_severity: error
                imsx_description: Invalid data provided
                imsx_CodeMinor:
                  imsx_codeMinorField:
                    - imsx_codeMinorFieldName: TargetEndSystem
                      imsx_codeMinorFieldValue: invaliddata
            invalidFilter:
              value:
                imsx_codeMajor: failure
                imsx_severity: error
                imsx_description: Invalid filter field
                imsx_CodeMinor:
                  imsx_codeMinorField:
                    - imsx_codeMinorFieldName: TargetEndSystem
                      imsx_codeMinorFieldValue: invalid_filter_field
    InternalError2:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/imsxStatusInfoDType'
          examples:
            default:
              value:
                imsx_codeMajor: failure
                imsx_severity: error
                imsx_description: Internal server error
                imsx_CodeMinor:
                  imsx_codeMinorField:
                    - imsx_codeMinorFieldName: TargetEndSystem
                      imsx_codeMinorFieldValue: internal_server_error
  securitySchemes:
    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-demographics.readonly: roster-demographics readonly
            https://timeback-platform.trilogy.com/consent/scope/consent.write: consent write
            https://timeback-platform.trilogy.com/consent/scope/consent.read: consent read
            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://timeback-platform.trilogy.com/content/scope/content.write: content write
            https://timeback-platform.trilogy.com/content/scope/content.read: content read
            https://purl.imsglobal.org/spec/caliper/v1p2/scope/events.write: events write
            https://purl.imsglobal.org/spec/caliper/v1p2/scope/events.readonly: events readonly
            https://timeback-platform.trilogy.com/webhooks/scope/webhooks.write: webhooks write
            https://timeback-platform.trilogy.com/webhooks/scope/webhooks.read: webhooks read
            https://timeback-platform.trilogy.com/webhooks/scope/webhooks.delete: webhooks delete

````