Back

Skilljar

Manage courses, students, and enrollments.

MCP server URL

https://skilljar.gumstack.com/mcp

Works with

Tools 81

  • List Students

    List students for the authenticated organization. **Required OAuth scope:** `students:read`

  • Create Students

    Create up to BATCH_MAX_ITEMS students in a single request. The ``data`` array must contain at least one item and at most ``BATCH_MAX_ITEMS`` items. Each item is processed independently — a failure on one row does not abort the rest. Response is 200 if all items succeed, 207 if any fail, 400 if the request envelope is empty or over the cap. Within-batch duplicate detection is first-wins: the first occurrence of an email is processed; subsequent occurrences are pre-marked as ``duplicate_in_batch`` without reaching the service. See ``api_v2/docs/batch-responses.md`` for the 200/207/400 status convention and per-item error code vocabulary. **Required OAuth scope:** `students:write`

  • Update Students

    Update up to DEFAULT_BATCH_MAX_ITEMS students in a single request. Replaces single-resource PATCH /v2/students/{id}/ from ACCEL-256 — never publicly released. Each item identifies a student via ``id`` (preferred) or ``attributes.email`` (fallback). The ``email`` field is read-only — it serves as the lookup identifier when ``id`` is absent, or as confirmation when ``id`` is present. It cannot be changed via this endpoint. Updatable attributes: ``first_name``, ``last_name``, ``is_inactive``. Each item is processed independently — failures on one row do not abort the rest. Response is 200 if all items succeed, 207 if any fail, 400 if the request envelope is empty or over the cap. Per-item failure ``code`` is one of: - ``not_found`` — student missing in this org - ``validation_error`` — anonymized/SSO/inactive guard rejected the update, or email confirmation did not match the student's current email To reactivate AND modify other fields, send two PATCHes: 1. First PATCH: ``{"data": [{"id": "...", "attributes": {"is_inactive": false}}]}`` 2. Second PATCH: ``{"data": [{"id": "...", "attributes": {"first_name": "..."}}]}`` See ``api_v2/docs/batch-responses.md`` for the envelope shape. **Required OAuth scope:** `students:write`

  • Get Student

    Retrieve a single student by ID. **Required OAuth scope:** `students:read`

  • Deactivate Student

    Deactivate (soft-delete) a student. **Required OAuth scope:** `students:deactivate`

  • Anonymize Student

    Permanently erase a student's PII. Requires the X-Confirm-Destructive: true header. **Required OAuth scope:** `students:anonymize`

  • Send Password Reset

    Send a password reset email to a student. ?domain=learn.example.com is required. **Required OAuth scope:** `students:manage-password`

  • Set Student Password

    Set a student's password directly. Password must meet the organization's requirements. **Required OAuth scope:** `students:manage-password`

  • List Student Domain Memberships

    List the domain memberships for a single student, cursor-paginated. Returns 404 if the student is not in the caller's organization. **Required OAuth scope:** `students:read`

  • Add Student Domain Memberships

    Grant the student membership to one or more domains. The request body is the canonical ``{data: [{type: "domains", id: ...}]}`` envelope — each item is a domain resource identifier (the student is in the path). This is the (re)activation path (there is no PATCH): a new membership is created active, an inactive membership (e.g. after a prior DELETE) is reactivated, and an already-active membership is a **idempotent** no-op — returned as ``succeeded`` with no separate ``already_exists`` code and no event. See ``batch_add_domain_memberships`` for the create-vs-reactivate semantics and the delegation to ``Domain.add_member``. Within-batch duplicate detection is first-wins on ``id`` (the domain id), with the JSON:API source pointer at ``/data/{i}/id``. Response is 200 if all items succeed, 207 if any fail, 400 if the request envelope is empty or over the cap. The student lookup runs **before** the envelope guard so a missing student is reported as 404 regardless of body content. ``exclude_none=True`` matches the batch-envelope convention shared by every sibling batch endpoint (assets, courses, lessons): null attributes such as an unset ``expires_at`` are omitted here, whereas the GET list renders them as ``null``. Same resource, two serializers — the drift is inherent to the batch-vs-list convention across ``api_v2``, not specific to this route. See ``api_v2/docs/batch-responses.md`` for the envelope shape and ``api_v2/docs/domain-memberships.md`` for the design. **Required OAuth scope:** `students:write`

  • Remove Student Domain Membership

    Remove a single domain membership from a student (soft-deactivate). Identifies the membership by the ``(student, domain)`` pair: the student is the ``{id}`` path segment, the domain is ``{domain_id}``. DELETE **deactivates** the membership (``active=False``, ``expires_at=now``) rather than destroying the row — the mirror of the (re)activating POST, and what the dashboard does — so history is preserved and a later POST can reactivate it. Returns 204 on success, 404 if the student, the domain, or the membership does not exist in the caller's organization. Deactivating an already-inactive membership is an idempotent 204 no-op (no event); the removed event fires only on an actual active → inactive transition. **Required OAuth scope:** `students:write`

  • List Lessons

    List non-draft lessons for the authenticated organization. **Required OAuth scope:** `lessons:read`