The LMS REST API

The module ships a REST API under /wp-json/torii-lms/v1/, usable by mobile apps, headless frontends, and automation scripts. It is a deliberate public API: the course listing endpoints work for anonymous visitors, and everything about a specific member requires authentication.

The API respects the same access rules as the website. A course hidden from anonymous visitors by your membership tags is absent from the anonymous listing; a member's course detail includes their own progress and completion state. You cannot read through the API what the site would not show you.

Public endpoints

  • GET /courses lists courses with pagination, honoring enrolled= when authenticated to filter to the member's own.
  • GET /courses/{id} returns a course with its full outline: modules, lessons, and per-lesson completion state for the calling member. Locked lessons carry their lock reason, including drip unlock dates.
  • GET /courses/{id}/modules and GET /courses/{id}/lessons return the flat structure.

Anonymous calls see only courses their access rules allow, with progress at zero and enrolled false.

Member endpoints

These require a logged-in member, via cookie with a REST nonce or an application password:

  • GET /progress returns progress summaries for one course or all of the member's courses.
  • GET /enrollment and POST /enrollment read and change enrollment. The POST action is enroll or unenroll, and enroll runs the same prerequisite checks as the website: an unmet prerequisite returns the list of courses to finish first, not a silent failure.
  • GET /quizzes/{id} returns the quiz config, whether the member can start it, their best result, and any active attempt.
  • POST /quizzes/{id}/start starts an attempt and pre-seeds the served question set.
  • GET /attempts/{id}/questions, POST /attempts/{id}/save, and POST /attempts/{id}/submit drive an attempt; submit grades against the served set, so unanswered questions count toward the maximum at zero points, and a submit after the time limit expires grades only what was saved before expiry.
  • GET /attempts/{id}/results returns the graded breakdown.
  • GET /instructors/{id}/courses returns an instructor's own courses.

Progress-permission endpoints

Student and analytics data is exposed for integrations, guarded by the view_torii_progress capability that instructors hold:

  • GET /students and GET /students/{id}/courses
  • GET /analytics/overview, GET /analytics/course/{id}, and GET /analytics/student/{id}

Instructor-scoped calls are filtered to the instructor's own courses; the analytics endpoints return the same data the admin Analytics screen charts.

Choosing it over shortcodes

Shortcodes render HTML in pages; the REST API returns data for anything else. A mobile app that plays lessons and tracks progress, a progress dashboard in your member portal built in JavaScript, and a nightly export of completion data into a warehouse are the natural fits. For server-to-server work, prefer an application password over cookie authentication: it survives session expiry and does not depend on a browser.

A rate-limit note: the quiz endpoints write on every save, so a client that autosaves per keystroke will hammer the database. Save on page change and submit at the end, mirroring the website's own quiz interface.