> ## 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.

# Onboard a student into one or more learning apps

> For most apps, forwards the request to the onboarding orchestrator, which validates the student and each app, then enqueues each app to SQS (3× retry + DLQ). Incept, Mentava, and Happy Numbers are synchronous, in-repo exceptions and must each be requested alone. This endpoint validates the request **structure**; the orchestrator validates the **values** (valid app names, grade ranges, mathacademy course matching).

## Payload

```jsonc
{
  "email": "student@alpha.school",   // required
  "apps": [                           // required, non-empty
    { "app": "<name>", "args": { "grade": 5 } }
  ]
}
```

- Each `apps` entry is an object: `app` (routing key) + optional `args` bag.
- `args.grade` is required for **every app except `google`**.
- Grade ranges below are generally enforced **downstream**. The synchronous in-repo exceptions enforce their own restrictions here before any provider write.

## Supported apps

_Expand an app to see its `args` and a sample entry._

<details>
<summary><strong>anton</strong> — grade: any integer</summary>

```json
{ "app": "anton", "args": { "grade": 5 } }
```

</details>

<details>
<summary><strong>membean</strong> — grade: 4–12</summary>

Class is assigned from the student's campus + level (not all campuses are configured).

```json
{ "app": "membean", "args": { "grade": 7 } }
```

</details>

<details>
<summary><strong>egumpp</strong> — grade: any integer</summary>

```json
{ "app": "egumpp", "args": { "grade": 6 } }
```

</details>

<details>
<summary><strong>clearfluency</strong> — grade: 1–2</summary>

```json
{ "app": "clearfluency", "args": { "grade": 1 } }
```

</details>

<details>
<summary><strong>freckle</strong> — grade: -1–12 (PreK–12)</summary>

Optional `renaissance_class_id` overrides the class assignment.

```json
{ "app": "freckle", "args": { "grade": 3, "renaissance_class_id": "abc-123" } }
```

</details>

<details>
<summary><strong>lalilo</strong> — grade: -1–12 (PreK–12)</summary>

Optional `renaissance_class_id` overrides the class assignment.

```json
{ "app": "lalilo", "args": { "grade": 1 } }
```

</details>

<details>
<summary><strong>mobymax</strong> — grade: 0–8 (K–8)</summary>

Optional: `course` (e.g. `"reading"`), `account` (string[]), `subject`.

```json
{ "app": "mobymax", "args": { "grade": 4, "course": "reading", "subject": "math" } }
```

</details>

<details>
<summary><strong>mathacademy</strong> — grade: 4–12 (`course_name` optional)</summary>

Each grade resolves to a default course (grades 9–12 default to the traditional track: Algebra I, Geometry, Algebra II, Precalculus). `course_name` is an optional override to select a different Math Academy catalog course (e.g. an Integrated Math (Honors) or SAT course).

```json
{ "app": "mathacademy", "args": { "grade": 10 } }
```

</details>

<details>
<summary><strong>incept</strong> - grades: 3-4 (Math). Runs the full Incept enrollment flow (same as the progression engine grade-3/4 Math base enrollment): rosters the student in Incept and provisions their individualized TimeBack Math base course.</summary>

Unlike the other apps, `incept` is validated and executed by **THIS service** (not the async orchestrator) and runs **synchronously**. It must be the **only** app in the request. Responses: `202` enrolled (or already enrolled), `207` enrollment failed (e.g. Incept/TimeBack desync), `404` no active student for the email, `409` the email matches multiple active users, `503` Incept not configured in this env, or Incept/TimeBack temporarily unavailable (retry).

```json
{ "app": "incept", "args": { "grade": 4 } }
```

</details>

<details>
<summary><strong>mentava</strong> — PK by default; non-PK requires Academics Reading approval. Runs synchronously through Bridge API.</summary>

`class_id` optionally overrides the configured current Mentava class UUID. The service always uses the approved starting level (`letter_sounds`, shown in Mentava as Letter Sounds only / no blending), sends the student's TimeBack OneRoster sourcedId to Mentava, enrolls the Mentava Basics TimeBack course, and stores the standard learning-app credentials. Set `approval_confirmed: true` for non-PK students and whenever the student's authoritative TimeBack grade is unavailable. The no-approval PK form is accepted only when TimeBack itself identifies the student as PK. The Bridge consumer used by this service must have `mentava:read` and `mentava:roster:students:create` (or `mentava:roster:write`) scopes. Device assignment/app installation remains an operational prerequisite outside this API.

```json
{ "app": "mentava", "args": { "grade": -1 } }
```

```json
{ "app": "mentava", "args": { "grade": -1, "approval_confirmed": true } }
```

```json
{ "app": "mentava", "args": { "grade": 1, "class_id": "00000000-0000-4000-8000-000000000000", "approval_confirmed": true } }
```

</details>

<details>
<summary><strong>edia</strong> — grade: 3–8</summary>

```json
{ "app": "edia", "args": { "grade": 5 } }
```

</details>

<details>
<summary><strong>vocabloco</strong> — grade: any integer</summary>

Word lists are auto-assigned by grade: G3 → Vocabulary + Spelling, G4 → Vocabulary + Spelling, G5 → Word List, G6+ → account only (no word lists).

```json
{ "app": "vocabloco", "args": { "grade": 4 } }
```

</details>

<details>
<summary><strong>zearn</strong> — grade: 0–3 (K–3)</summary>

```json
{ "app": "zearn", "args": { "grade": 2 } }
```

</details>

<details>
<summary><strong>happynumbers</strong> — Pre-K only</summary>

Resolves the active student roster record, provisions the student into `Alpha`, `Alpha 2`, and so on, rolling to a newly created class when the current class reaches 95 students, and stores the Happy Numbers identity mapping and TimeBack display-name/PIN credentials. It runs synchronously in this service through Bridge and must be the only app in the request. This is provider-roster onboarding only: it does not create or replace a TimeBack course enrollment. Normal progression assigns the TimeBack course separately. The TimeBack service identity must have Bridge `happynumbers:read` and `happynumbers:roster:write` scopes.

```json
{ "app": "happynumbers", "args": { "grade": -1 } }
```

</details>

<details>
<summary><strong>google</strong> — grade: optional</summary>

`args` may be omitted entirely. Optional `google_password` (system default if omitted); `grade` is only used for OU assignment.

```json
{ "app": "google" }
```

```json
{ "app": "google", "args": { "google_password": "CustomPass1!" } }
```

</details>

## Responses

- **200** — Mentava course onboarding or Happy Numbers provider rostering completed synchronously; check `results[].status`.
- **202** — every app was queued.
- **207** — partial success; check each entry's `queued`/`error` field.
- **400** — malformed body (here) or invalid app name / app-specific value validation (orchestrator).
- **404** — student not found for the given email.

Served by the onboard-student Lambda.



## OpenAPI

````yaml /openapi/beyond-ai/edubridge-api.yaml post /edubridge/progression/onboard-student
openapi: 3.1.0
info:
  title: Edubridge API
  version: 1.0.0
  description: >
    # EduBridge API Overview


    The Edubridge API provides simplified interfaces for digital schools to
    manage their digital courses and student enrollments,

    abstracting away the complexities of the OneRoster standard while
    maintaining compatibility.


    It offers streamlined endpoints to enroll students in courses without the
    need to understand the underlying academic hierarchy.


    This API significantly reduces integration complexity for third-party
    systems by handling

    the background creation and management of academic sessions (per year),
    classes (per course), and enrollment relationships,

    allowing consumers to focus on educational experiences rather than data
    management.


    Entities involved in the Edubridge API:


    - Year academic session (per school)

    - Term academic session (spans the whole year)

    - Class (per course + term)

    - Enrollment (per student per class)


    ## Auto-managed entities


    The Edubridge API automatically manages the following entities:


    - Year academic session

    - Term academic session (spans the whole year)

    - Class (per course + term)


    ## Course-centric enrollment


    This API offers a course-centric view of enrollments, allowing consumers to
    focus on what courses the student is enrolled in rather than details about
    the underlying academic hierarchy.


    You as an API consumer do not need to understand the underlying academic
    hierarchy to use this API, if you are only interested in what courses a
    student is enrolled in.


    Consumers that need to interact with the underlying academic hierarchy
    through flows not covered by this API can do so by using the raw OneRoster
    API.


    ## Pre-requisites


    Before you can enroll a user in a course, you need the following entities
    created:


    - A school or equivalent organization

    - A course (linked to the organization via orgSourcedId)

    - A user (that will be enrolled in the course)


    ## Analytics API


    The Edubridge Analytics API provides student activity data and metrics
    across enrollments.


    ### Available Endpoints


    **Weekly Facts** - Get facts for a specific week by student email or ID

    - Returns: List of individual facts grouped by date


    **Activity (Date Range)** - Get facts for a custom date range by student
    email or ID

    - Returns: Aggregated metrics grouped by date → subject and date → subject →
    app


    **Enrollment Facts** - Get facts for a specific enrollment

    - Returns: Aggregated metrics for all activity within an enrollment

    - Supports optional date range filtering via `startDate` and `endDate` query
    parameters

    - Supports timezone conversion via `timezone` query parameter


    **Highest Grade Mastered** - Get the highest grade a student has mastered
    for a subject

    - Returns: Grade data from multiple sources (Edulastic, placement tests,
    test-out)


    **Student Percentiles** - Get the latest MAP percentile snapshots for a
    student

    - Returns: Per-subject percentile, RIT score, assessment date, and season

    - Used by: Goals UI setup and percentile/x-factor previews


    ### Metrics Included


    - **Activity Metrics**: Questions answered (total/correct), XP earned, units
    mastered

    - **Time Metrics**: Active seconds, inactive seconds, waste seconds

    - **Grouping**: Subject, application/platform, course, campus, date


    ### Authorization


    All analytics endpoints require the `analytics.readOnly` OAuth scope.


    ## Goals API


    The Goals API enables students to preview, track, and update learning goals
    through the Lambda-backed `/goals/*` surface.


    ### Goal Types


    | Type | Description | Required Fields |

    |------|-------------|-----------------|

    | `minimum` | Daily minimum XP target (ongoing) | `subject`, `targetValue`,
    `targetMetric` |

    | `grade_mastery` | Master content up to target grade | `subject`,
    `targetValue` |

    | `percentile` | Reach target percentile (RIT subjects only) | `subject`,
    `targetValue` |

    | `x_factor` | Grow Nx faster than typical (e.g., 2x growth) | `subject`,
    `targetValue` |

    | `course` | Complete a specific course or explicit course set | `subject`,
    `targetValue`, `targetMetric`, and either `stageId` or `courseIds` |


    ### Pace Type


    Milestone goals (`grade_mastery`, `percentile`, `x_factor`, `course`)
    support two pacing approaches:


    | paceType | User Sets | System Calculates |

    |----------|-----------|-------------------|

    | `target_date` | End date | Daily XP needed |

    | `daily_time` | Daily time commitment | Projected completion timeline |


    Example: "Reach 6th grade Math by May 15" (`target_date`) vs "Work toward
    6th grade Math at a steady daily pace" (`daily_time`).


    ### Available Endpoints


    **Subject Goals**

    - `GET /:studentId/subjects` - List subject goal snapshots for a student;
    bootstrap reads ensure managed minimum goals exist for currently enrolled
    supported subjects

    - `POST /:studentId/subjects` - Create the active learner-facing subject
    goal for a subject

    - `PATCH /:studentId/subjects/:subject` - Update the active learner-facing
    subject goal for a subject

    - `DELETE /:studentId/subjects/:subject` - Delete the active learner-facing
    subject goal for a subject

    - `PATCH /:studentId/subjects/:subject/minimum` - Update the managed minimum
    baseline for a subject

    - `POST /:studentId/subjects/preview` - Preview a learner-facing subject
    goal without saving it


    **Course Goals**

    - `GET /:studentId/courses` - List course goal snapshots for a student

    - `POST /:studentId/courses` - Create an atomic course goal

    - `PATCH /:studentId/courses/:goalId` - Update an atomic course goal

    - `DELETE /:studentId/courses/:goalId` - Delete an atomic course goal

    - `POST /:studentId/courses/preview` - Preview an atomic course goal without
    saving it


    ### Response Notes


    - Subject list responses return `{ studentId, subjects: [...] }`.

    - Subject create/update/minimum-patch responses return `{ subject: ... }`.

    - Subject preview responses return `{ preview: ... }`.

    - Course list responses return `{ studentId, courses: [...] }`.

    - Course create/update responses return `{ course: ... }`.

    - Course preview responses return `{ preview: ... }`.
      - `progress.resolution`
    - Preview responses return `{ preview: { goal: ... } }` using the same inner
    goal shape as saved goal detail.

    - Minimum goals are internally managed baseline rows:
      - auto-created for supported enrolled subjects on the canonical bootstrap goals-list read
      - readable and patchable
      - not creatable or deletable by clients
    - Filtered/history list reads are pure reads and do not run minimum-goal
    sync.

    - Standalone pace and NWEA helper endpoints are intentionally not part of
    the public goals surface.


    ### Supported Subjects


    RIT subjects (for percentile and x-factor goals): Math, Reading, Language,
    Science


    All subjects: Math, Reading, Language, Vocabulary, Science, Writing,
    FastMath, Social Studies


    ### Authorization


    All goals endpoints require authentication. Endpoints that rely on upstream
    analytics or sequence resolution also require the same auth context/API
    Gateway flow used by the Lambda-backed goals service.


    ## Student Progress API


    These Lambda-backed endpoints expose non-goal progress projections outside
    the goals namespace.


    ### Available Endpoints


    - `GET /students/:studentId/courses/:courseId/progress` - Get progress for a
    single course

    - `GET /students/:studentId/subjects/:subject/grades/:grade/progress` - Get
    aggregate progress for all courses in a subject-grade band


    ### Authorization


    Student progress endpoints require the same authenticated Lambda-backed flow
    used by the goals service.


    ## AP Readiness API


    The AP Readiness API provides a specialized workflow for AP exam
    preparation. It stores AP readiness goals in `learning_goals` using the
    `ap_readiness` goal type, but it has its own API surface, scoring pipeline,
    dashboard, and drill-down views.


    ### Available Endpoints


    **Reference Data**

    - `GET /subjects` - List supported AP exam subjects and title-matching
    patterns


    **Dashboard & Drill-down**

    - `GET /dashboard?subject=...` - Get dashboard rows for all active AP
    readiness goals in one AP subject

    - `GET /students/:studentId/drill-down?goalId=...` - Get per-unit drill-down
    data for one student's AP goal


    **Goal Management**

    - `GET /goals?subject=...` - List active AP readiness goals for an AP
    subject

    - `POST /goals` - Create an AP readiness goal

    - `PATCH /goals/:goalId` - Update the tracked courses or exam date for an AP
    readiness goal


    **Enrollment Validation**

    - `GET /enrollment-check?studentId=...&courseIds=id1,id2,...` - Return
    courses where the student has no active enrollment


    ### Goal Model


    - `goalType` is always `ap_readiness`

    - `targetMetric` is always `percent`

    - `paceType` is always `target_date`

    - `targetValue` is currently fixed to the readiness threshold for a
    predicted AP score of `5`

    - `courseIds` stores all tracked courses

    - `metadata.practice_test_course_ids` stores the subset of tracked courses
    that are practice tests

    - `curriculumCourseIds` is a derived field returned by the API and equals
    `courseIds - practice_test_course_ids`


    ### Dashboard Metrics


    Each dashboard row includes:


    - `readiness.componentA` - curriculum course progress percentage from XP

    - `readiness.componentB` - weighted practice-test accuracy percentage

    - `readiness.componentC` - final readiness percentage

    - `readiness.predictedScore` - predicted AP score from `1-5`

    - `coverage` - how many curriculum units have assessed activity

    - `topFocusAreas` - weakest unit names

    - `timeRemainingPct` - percent of time remaining until the exam date


    ### Response Notes


    - Create and update responses return `{ goal: ... }`

    - List responses return `{ goals: [...], totalCount }`

    - Dashboard responses return `{ rows: [...] }`

    - Drill-down responses return `{ units: [...] }`

    - Enrollment-check responses return `{ missingEnrollments: [...] }`


    ### Authorization


    AP Readiness endpoints require authentication and the same API Gateway auth
    context used by the Lambda-backed service.
servers:
  - url: https://api.alpha-1edtech.ai
    description: Edubridge API
security:
  - OAuth2: []
tags:
  - name: Analytics
    description: >-
      Analytics endpoints for retrieving and aggregating student activity data,
      including weekly facts and activity reports across date ranges.
  - name: AP Readiness
    description: >-
      AP exam readiness endpoints for creating AP readiness goals, viewing
      dashboard metrics, drilling into weak units, and checking enrollment gaps
      for AP preparation courses.
  - name: Application Metrics
    description: Track and manage application metrics for monitoring and analytics purposes
  - name: Applications
    description: >-
      Manage and retrieve applications available in the system. Applications
      represent different learning platforms or educational software that can be
      integrated.
  - name: Calendar Days
    description: >-
      Calendar day management for tracking instructional days, holidays, breaks,
      and other non-instructional days. Enables accurate school day counting for
      attendance, progress tracking, and compliance reporting.
  - name: Enrollments
    description: >-
      Simplified, course-centric enrollment management that abstracts away the
      complex OneRoster academic hierarchy
  - name: Goals
    description: >-
      Learning goal management endpoints for setting, tracking, and projecting
      learning goals including daily minimums, grade mastery targets, percentile
      targets, and course completion goals.
  - name: Learning Reports
    description: >-
      Learning reports endpoints for retrieving and aggregating student activity
      data, including weekly facts and activity reports.
  - name: Progression
    description: >-
      Proxy endpoints for the student progression pipeline. These routes forward
      requests to Lambda-backed API Gateway endpoints that handle Caliper event
      ingestion, progression enqueuing, and hole-filling course creation.
  - name: Reports
    description: >-
      Report PDF endpoints for storing generated reports and retrieving
      short-lived signed URLs for browser viewing.
  - name: Subject Track
    description: >-
      Subject tracks determine the target course for each subject and grade
      level. For example, for subject 'Math' grade level '9', the target course
      can be 'Math Academy 9th Grade' (this is the course that students will be
      enrolled in when they get placed to Math Grade 9). There can be only one
      target course per subject and grade level.
  - name: Users
    description: >-
      User management endpoints that provide simplified access to user data with
      enhanced filtering and querying capabilities beyond the standard OneRoster
      API.
paths:
  /edubridge/progression/onboard-student:
    post:
      tags:
        - Progression
      summary: Onboard a student into one or more learning apps
      description: >-
        For most apps, forwards the request to the onboarding orchestrator,
        which validates the student and each app, then enqueues each app to SQS
        (3× retry + DLQ). Incept, Mentava, and Happy Numbers are synchronous,
        in-repo exceptions and must each be requested alone. This endpoint
        validates the request **structure**; the orchestrator validates the
        **values** (valid app names, grade ranges, mathacademy course matching).


        ## Payload


        ```jsonc

        {
          "email": "student@alpha.school",   // required
          "apps": [                           // required, non-empty
            { "app": "<name>", "args": { "grade": 5 } }
          ]
        }

        ```


        - Each `apps` entry is an object: `app` (routing key) + optional `args`
        bag.

        - `args.grade` is required for **every app except `google`**.

        - Grade ranges below are generally enforced **downstream**. The
        synchronous in-repo exceptions enforce their own restrictions here
        before any provider write.


        ## Supported apps


        _Expand an app to see its `args` and a sample entry._


        <details>

        <summary><strong>anton</strong> — grade: any integer</summary>


        ```json

        { "app": "anton", "args": { "grade": 5 } }

        ```


        </details>


        <details>

        <summary><strong>membean</strong> — grade: 4–12</summary>


        Class is assigned from the student's campus + level (not all campuses
        are configured).


        ```json

        { "app": "membean", "args": { "grade": 7 } }

        ```


        </details>


        <details>

        <summary><strong>egumpp</strong> — grade: any integer</summary>


        ```json

        { "app": "egumpp", "args": { "grade": 6 } }

        ```


        </details>


        <details>

        <summary><strong>clearfluency</strong> — grade: 1–2</summary>


        ```json

        { "app": "clearfluency", "args": { "grade": 1 } }

        ```


        </details>


        <details>

        <summary><strong>freckle</strong> — grade: -1–12 (PreK–12)</summary>


        Optional `renaissance_class_id` overrides the class assignment.


        ```json

        { "app": "freckle", "args": { "grade": 3, "renaissance_class_id":
        "abc-123" } }

        ```


        </details>


        <details>

        <summary><strong>lalilo</strong> — grade: -1–12 (PreK–12)</summary>


        Optional `renaissance_class_id` overrides the class assignment.


        ```json

        { "app": "lalilo", "args": { "grade": 1 } }

        ```


        </details>


        <details>

        <summary><strong>mobymax</strong> — grade: 0–8 (K–8)</summary>


        Optional: `course` (e.g. `"reading"`), `account` (string[]), `subject`.


        ```json

        { "app": "mobymax", "args": { "grade": 4, "course": "reading",
        "subject": "math" } }

        ```


        </details>


        <details>

        <summary><strong>mathacademy</strong> — grade: 4–12 (`course_name`
        optional)</summary>


        Each grade resolves to a default course (grades 9–12 default to the
        traditional track: Algebra I, Geometry, Algebra II, Precalculus).
        `course_name` is an optional override to select a different Math Academy
        catalog course (e.g. an Integrated Math (Honors) or SAT course).


        ```json

        { "app": "mathacademy", "args": { "grade": 10 } }

        ```


        </details>


        <details>

        <summary><strong>incept</strong> - grades: 3-4 (Math). Runs the full
        Incept enrollment flow (same as the progression engine grade-3/4 Math
        base enrollment): rosters the student in Incept and provisions their
        individualized TimeBack Math base course.</summary>


        Unlike the other apps, `incept` is validated and executed by **THIS
        service** (not the async orchestrator) and runs **synchronously**. It
        must be the **only** app in the request. Responses: `202` enrolled (or
        already enrolled), `207` enrollment failed (e.g. Incept/TimeBack
        desync), `404` no active student for the email, `409` the email matches
        multiple active users, `503` Incept not configured in this env, or
        Incept/TimeBack temporarily unavailable (retry).


        ```json

        { "app": "incept", "args": { "grade": 4 } }

        ```


        </details>


        <details>

        <summary><strong>mentava</strong> — PK by default; non-PK requires
        Academics Reading approval. Runs synchronously through Bridge
        API.</summary>


        `class_id` optionally overrides the configured current Mentava class
        UUID. The service always uses the approved starting level
        (`letter_sounds`, shown in Mentava as Letter Sounds only / no blending),
        sends the student's TimeBack OneRoster sourcedId to Mentava, enrolls the
        Mentava Basics TimeBack course, and stores the standard learning-app
        credentials. Set `approval_confirmed: true` for non-PK students and
        whenever the student's authoritative TimeBack grade is unavailable. The
        no-approval PK form is accepted only when TimeBack itself identifies the
        student as PK. The Bridge consumer used by this service must have
        `mentava:read` and `mentava:roster:students:create` (or
        `mentava:roster:write`) scopes. Device assignment/app installation
        remains an operational prerequisite outside this API.


        ```json

        { "app": "mentava", "args": { "grade": -1 } }

        ```


        ```json

        { "app": "mentava", "args": { "grade": -1, "approval_confirmed": true }
        }

        ```


        ```json

        { "app": "mentava", "args": { "grade": 1, "class_id":
        "00000000-0000-4000-8000-000000000000", "approval_confirmed": true } }

        ```


        </details>


        <details>

        <summary><strong>edia</strong> — grade: 3–8</summary>


        ```json

        { "app": "edia", "args": { "grade": 5 } }

        ```


        </details>


        <details>

        <summary><strong>vocabloco</strong> — grade: any integer</summary>


        Word lists are auto-assigned by grade: G3 → Vocabulary + Spelling, G4 →
        Vocabulary + Spelling, G5 → Word List, G6+ → account only (no word
        lists).


        ```json

        { "app": "vocabloco", "args": { "grade": 4 } }

        ```


        </details>


        <details>

        <summary><strong>zearn</strong> — grade: 0–3 (K–3)</summary>


        ```json

        { "app": "zearn", "args": { "grade": 2 } }

        ```


        </details>


        <details>

        <summary><strong>happynumbers</strong> — Pre-K only</summary>


        Resolves the active student roster record, provisions the student into
        `Alpha`, `Alpha 2`, and so on, rolling to a newly created class when the
        current class reaches 95 students, and stores the Happy Numbers identity
        mapping and TimeBack display-name/PIN credentials. It runs synchronously
        in this service through Bridge and must be the only app in the request.
        This is provider-roster onboarding only: it does not create or replace a
        TimeBack course enrollment. Normal progression assigns the TimeBack
        course separately. The TimeBack service identity must have Bridge
        `happynumbers:read` and `happynumbers:roster:write` scopes.


        ```json

        { "app": "happynumbers", "args": { "grade": -1 } }

        ```


        </details>


        <details>

        <summary><strong>google</strong> — grade: optional</summary>


        `args` may be omitted entirely. Optional `google_password` (system
        default if omitted); `grade` is only used for OU assignment.


        ```json

        { "app": "google" }

        ```


        ```json

        { "app": "google", "args": { "google_password": "CustomPass1!" } }

        ```


        </details>


        ## Responses


        - **200** — Mentava course onboarding or Happy Numbers provider
        rostering completed synchronously; check `results[].status`.

        - **202** — every app was queued.

        - **207** — partial success; check each entry's `queued`/`error` field.

        - **400** — malformed body (here) or invalid app name / app-specific
        value validation (orchestrator).

        - **404** — student not found for the given email.


        Served by the onboard-student Lambda.
      operationId: onboardStudent
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                  description: Student email — must exist in Timeback.
                  example: student@alpha.school
                apps:
                  type: array
                  items:
                    type: object
                    properties:
                      app:
                        type: string
                        enum:
                          - anton
                          - membean
                          - egumpp
                          - clearfluency
                          - freckle
                          - lalilo
                          - mobymax
                          - mathacademy
                          - incept
                          - edia
                          - vocabloco
                          - zearn
                          - happynumbers
                          - google
                          - mentava
                        description: App routing key.
                        example: mathacademy
                      args:
                        type: object
                        properties:
                          grade:
                            anyOf:
                              - type: string
                              - type: number
                            description: >-
                              Grade level (string or number). Required for every
                              app except `google`.
                            example: 5
                          course_name:
                            type: string
                            description: >-
                              `mathacademy` only — OPTIONAL course override.
                              When omitted, the grade's default course is used
                              (9–12 default to the traditional track: Algebra I
                              / Geometry / Algebra II / Precalculus); when
                              provided it selects a matching Math Academy
                              catalog course.
                            example: Algebra I
                          course:
                            type: string
                            description: '`mobymax` only — optional course filter.'
                            example: reading
                          account:
                            type: array
                            items:
                              type: string
                            description: '`mobymax` only — optional account selection.'
                          subject:
                            type: string
                            description: '`mobymax` only — optional subject filter.'
                            example: math
                          renaissance_class_id:
                            type: string
                            description: >-
                              `freckle`/`lalilo` only — override class
                              assignment.
                          google_password:
                            type: string
                            description: >-
                              `google` only — custom password (system default if
                              omitted).
                          class_id:
                            type: string
                            format: uuid
                            description: >-
                              `mentava` only — optional Mentava class UUID
                              override. The configured current class is used
                              when omitted.
                          approval_confirmed:
                            type: boolean
                            description: >-
                              `mentava` only — must be true for non-PK students
                              after Academics Reading approval, and whenever the
                              authoritative TimeBack grade is unavailable.
                          forceTimebackCredentials:
                            type: boolean
                            description: >-
                              Per-app override: (re)write Timeback credentials
                              even if the account already exists.
                        additionalProperties: true
                        description: >-
                          App-specific configuration. Omit entirely when the app
                          needs no args.
                    required:
                      - app
                    additionalProperties: false
                  minItems: 1
                  description: >-
                    Apps to onboard the student into. Each entry is an object
                    with `app` and an optional `args` bag. `args.grade` is
                    required for every app except `google`. Structure is
                    validated here; app/grade/course *values* are validated by
                    the orchestrator.
                  example:
                    - app: anton
                      args:
                        grade: 5
                    - app: mathacademy
                      args:
                        grade: 10
                        course_name: Integrated Math II (Honors)
                    - app: google
                forceTimebackCredentials:
                  type: boolean
                  description: >-
                    Request-level default: (re)write Timeback credentials even
                    for existing accounts (per-app
                    `args.forceTimebackCredentials` overrides this).
              required:
                - email
                - apps
              additionalProperties: false
            examples:
              allApps:
                summary: All apps in one request
                value:
                  email: student@alpha.school
                  apps:
                    - app: anton
                      args:
                        grade: 5
                    - app: membean
                      args:
                        grade: 5
                    - app: egumpp
                      args:
                        grade: 5
                    - app: clearfluency
                      args:
                        grade: 1
                    - app: freckle
                      args:
                        grade: 5
                    - app: lalilo
                      args:
                        grade: 1
                    - app: mobymax
                      args:
                        grade: 4
                    - app: mathacademy
                      args:
                        grade: 10
                        course_name: Integrated Math II (Honors)
                    - app: edia
                      args:
                        grade: 5
                    - app: vocabloco
                      args:
                        grade: 4
                    - app: zearn
                      args:
                        grade: 2
                    - app: google
              anton:
                summary: anton — any grade
                value:
                  email: student@alpha.school
                  apps:
                    - app: anton
                      args:
                        grade: 5
              membean:
                summary: membean — grades 4–12
                value:
                  email: student@alpha.school
                  apps:
                    - app: membean
                      args:
                        grade: 7
              egumpp:
                summary: egumpp — any grade
                value:
                  email: student@alpha.school
                  apps:
                    - app: egumpp
                      args:
                        grade: 6
              clearfluency:
                summary: clearfluency — grades 1–2
                value:
                  email: student@alpha.school
                  apps:
                    - app: clearfluency
                      args:
                        grade: 1
              freckle:
                summary: freckle — PreK–12 (optional class override)
                value:
                  email: student@alpha.school
                  apps:
                    - app: freckle
                      args:
                        grade: 3
                        renaissance_class_id: abc-123
              lalilo:
                summary: lalilo — PreK–12
                value:
                  email: student@alpha.school
                  apps:
                    - app: lalilo
                      args:
                        grade: 1
              mobymax:
                summary: mobymax — K–8 (optional course/subject)
                value:
                  email: student@alpha.school
                  apps:
                    - app: mobymax
                      args:
                        grade: 4
                        course: reading
                        subject: math
              mathacademyGrades4to8:
                summary: mathacademy — grades 4–8 (course auto-resolved)
                value:
                  email: student@alpha.school
                  apps:
                    - app: mathacademy
                      args:
                        grade: 5
              mathacademyGrades9to12:
                summary: >-
                  mathacademy — grades 9–12 (grade default; course_name optional
                  override)
                value:
                  email: student@alpha.school
                  apps:
                    - app: mathacademy
                      args:
                        grade: 10
              incept:
                summary: >-
                  incept — grades 3–4 Math (full Incept enrollment, synchronous,
                  in-repo)
                value:
                  email: student@alpha.school
                  apps:
                    - app: incept
                      args:
                        grade: 4
              mentava:
                summary: mentava — PK, synchronous Bridge onboarding
                value:
                  email: student@alpha.school
                  apps:
                    - app: mentava
                      args:
                        grade: -1
              edia:
                summary: edia — grades 3–8
                value:
                  email: student@alpha.school
                  apps:
                    - app: edia
                      args:
                        grade: 5
              vocabloco:
                summary: vocabloco — any grade (word lists by grade)
                value:
                  email: student@alpha.school
                  apps:
                    - app: vocabloco
                      args:
                        grade: 4
              zearn:
                summary: zearn — grades K–3
                value:
                  email: student@alpha.school
                  apps:
                    - app: zearn
                      args:
                        grade: 2
              happynumbers:
                summary: happynumbers — Pre-K only
                value:
                  email: student@alpha.school
                  apps:
                    - app: happynumbers
                      args:
                        grade: -1
              googleDefaultPassword:
                summary: google — no args (default password)
                value:
                  email: student@alpha.school
                  apps:
                    - app: google
              googleCustomPassword:
                summary: google — custom password
                value:
                  email: student@alpha.school
                  apps:
                    - app: google
                      args:
                        google_password: CustomPass1!
      responses:
        '200':
          description: >-
            Mentava enrollment or Happy Numbers provider rostering completed
            synchronously
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: >-
                      True when every app was queued (202) or synchronous
                      in-repo onboarding succeeded (200); false on partial
                      success (207).
                    example: true
                  message:
                    type: string
                    description: Human-readable summary
                    example: All 3 app(s) queued for student@alpha.school
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        app:
                          type: string
                          description: App name
                          example: anton
                        queued:
                          type: boolean
                          description: >-
                            Whether the app was enqueued; false for synchronous
                            in-repo results.
                          example: true
                        messageId:
                          type: string
                          description: SQS message ID (when queued)
                        status:
                          type: string
                          enum:
                            - enrolled
                            - already_enrolled
                            - provider_rostered
                            - provider_already_rostered
                          description: >-
                            Synchronous result. Happy Numbers uses
                            provider_rostered/provider_already_rostered because
                            this endpoint does not create a TimeBack course
                            enrollment.
                        studentSourcedId:
                          type: string
                          description: >-
                            Resolved TimeBack student sourcedId for synchronous
                            onboarding.
                        error:
                          type: string
                          description: Reason an asynchronous app was not queued.
                      required:
                        - app
                        - queued
                    description: Per-app queue results
                required:
                  - success
                  - message
                  - results
        '202':
          description: >-
            All apps queued (for `incept`: enrolled synchronously in this
            service)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: >-
                      True when every app was queued (202) or synchronous
                      in-repo onboarding succeeded (200); false on partial
                      success (207).
                    example: true
                  message:
                    type: string
                    description: Human-readable summary
                    example: All 3 app(s) queued for student@alpha.school
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        app:
                          type: string
                          description: App name
                          example: anton
                        queued:
                          type: boolean
                          description: >-
                            Whether the app was enqueued; false for synchronous
                            in-repo results.
                          example: true
                        messageId:
                          type: string
                          description: SQS message ID (when queued)
                        status:
                          type: string
                          enum:
                            - enrolled
                            - already_enrolled
                            - provider_rostered
                            - provider_already_rostered
                          description: >-
                            Synchronous result. Happy Numbers uses
                            provider_rostered/provider_already_rostered because
                            this endpoint does not create a TimeBack course
                            enrollment.
                        studentSourcedId:
                          type: string
                          description: >-
                            Resolved TimeBack student sourcedId for synchronous
                            onboarding.
                        error:
                          type: string
                          description: Reason an asynchronous app was not queued.
                      required:
                        - app
                        - queued
                    description: Per-app queue results
                required:
                  - success
                  - message
                  - results
        '207':
          description: Partial success — some apps queued, some failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: >-
                      True when every app was queued (202) or synchronous
                      in-repo onboarding succeeded (200); false on partial
                      success (207).
                    example: true
                  message:
                    type: string
                    description: Human-readable summary
                    example: All 3 app(s) queued for student@alpha.school
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        app:
                          type: string
                          description: App name
                          example: anton
                        queued:
                          type: boolean
                          description: >-
                            Whether the app was enqueued; false for synchronous
                            in-repo results.
                          example: true
                        messageId:
                          type: string
                          description: SQS message ID (when queued)
                        status:
                          type: string
                          enum:
                            - enrolled
                            - already_enrolled
                            - provider_rostered
                            - provider_already_rostered
                          description: >-
                            Synchronous result. Happy Numbers uses
                            provider_rostered/provider_already_rostered because
                            this endpoint does not create a TimeBack course
                            enrollment.
                        studentSourcedId:
                          type: string
                          description: >-
                            Resolved TimeBack student sourcedId for synchronous
                            onboarding.
                        error:
                          type: string
                          description: Reason an asynchronous app was not queued.
                      required:
                        - app
                        - queued
                    description: Per-app queue results
                required:
                  - success
                  - message
                  - results
        '400':
          description: >-
            Malformed body (structural validation here) or invalid app name /
            app-specific value validation (from the orchestrator).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  details:
                    description: Additional error details
                required:
                  - error
        '404':
          description: >-
            Student not found for the given email (synchronous apps require one
            active student match)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  details:
                    description: Additional error details
                required:
                  - error
        '409':
          description: >-
            Synchronous onboarding found an ambiguous/conflicting student or
            provider identity
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  details:
                    description: Additional error details
                required:
                  - error
        '422':
          description: >-
            The resolved active student is missing the sourcedId required for
            onboarding
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  details:
                    description: Additional error details
                required:
                  - error
        '502':
          description: Upstream onboarding orchestrator, TimeBack, or Bridge error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  details:
                    description: Additional error details
                required:
                  - error
        '503':
          description: >-
            A synchronous onboarding dependency is not configured or temporarily
            unavailable (retryable)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  details:
                    description: Additional error details
                required:
                  - error
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        clientCredentials:
          scopes:
            https://purl.imsglobal.org/spec/or/v1p1/scope/admin: Admin access to the API
            https://purl.imsglobal.org/spec/or/v1p2/scope/admin.own: Admin access restricted to own resources
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster-core.readonly: Read access to roster core
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster.readonly: Read access to roster
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster.createput: Create and update access to roster
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster.delete: Delete access to roster
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster-demographics.readonly: Read access to roster demographics
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster-demographics.createput: Create and update access to roster demographics
            https://purl.imsglobal.org/spec/or/v1p1/scope/roster-demographics.delete: Delete access to roster demographics
            https://purl.imsglobal.org/spec/or/v1p1/scope/resource.readonly: Read access to resource
            https://purl.imsglobal.org/spec/or/v1p1/scope/resource.createput: Create and update access to resource
            https://purl.imsglobal.org/spec/or/v1p1/scope/resource.delete: Delete access to resource
            https://purl.imsglobal.org/spec/or/v1p1/scope/gradebook.readonly: Read access to gradebook
            https://purl.imsglobal.org/spec/or/v1p1/scope/gradebook.createput: Create and update access to gradebook
            https://purl.imsglobal.org/spec/or/v1p1/scope/gradebook.delete: Delete access to gradebook
            https://purl.imsglobal.org/spec/powerpath/v1p1/scope/powerpath.readonly: Read access to powerpath
            https://purl.imsglobal.org/spec/powerpath/v1p1/scope/powerpath.createput: Create and update access to powerpath
            https://purl.imsglobal.org/spec/powerpath/v1p1/scope/powerpath.delete: Delete access to powerpath
            https://purl.imsglobal.org/spec/powerpath/v1p1/scope/powerpath.admin: Admin access to powerpath
            https://purl.imsglobal.org/spec/ob/v3p0/scope/credential.readonly: Read your issued badges
            https://purl.imsglobal.org/spec/ob/v3p0/scope/credential.upsert: Store new badges in your account
            https://purl.imsglobal.org/spec/ob/v3p0/scope/credential.delete: Delete access to open badges
            https://purl.imsglobal.org/spec/ob/v3p0/scope/credential.admin: Administrative access to open badges
            https://purl.imsglobal.org/spec/clr/v2p0/scope/credential.readonly: Read access to CLR
            https://purl.imsglobal.org/spec/clr/v2p0/scope/credential.upsert: Create and update access to CLR
            https://purl.imsglobal.org/spec/clr/v2p0/scope/credential.admin: Administrative access to CLR
            https://api.alpha-1edtech.ai/edubridge/progression.readonly: Browse lesson catalog via progression proxy
            https://api.alpha-1edtech.ai/edubridge/progression.createput: Create hole-filling courses via progression proxy
          tokenUrl: >-
            https://prod-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com/oauth2/token

````