API Documentation

EduNest LMS is a Next.js 16 (App Router) application. There is no separate API server — every endpoint is a route handler living under src/app/api/. They run on the same host as the storefront and admin panel, so the base URL is simply your site origin.

Base URL (local): http://localhost:3000 Base URL (production): https://your-domain.com

There are three families of endpoints, each authenticated differently:

Family Path prefix Auth
Public / storefront /api/v1/*, /api/license/status Open (no auth)
Customer / learner portal /api/v1/portal/* Session cookie member_session (JWT)
Instructor /api/v1/instructor/* Instructor session
Admin /api/v1/admin/* Session cookie admin_token (JWT) + RBAC permission
Install wizard /api/install/* First-run only, gated by the installer
Public REST API add-on /api/v1/ext/api/v1/* Bearer edu_ API key + scope

Authentication

EduNest uses cookie-based sessions for the first-party surfaces (storefront, portal, instructor, admin) and a separate bearer-key scheme for the optional public REST API add-on.

Admin session (admin_token)

Admins sign in at POST /api/v1/admin/auth/login. On success the server sets an HTTP-only admin_token cookie holding a signed JWT. Every /api/v1/admin/* route reads that cookie, and most write routes additionally enforce a permission (RBAC) via requirePermission(...) — there is no global middleware, the check is per-route.

HTTP
POST /api/v1/admin/auth/login
Content-Type: application/json

{ "email": "admin@example.com", "password": "••••••••" }
Endpoint Purpose
POST /api/v1/admin/auth/login Sign in → sets admin_token cookie
POST /api/v1/admin/auth/logout Clear the admin session
GET /api/v1/admin/auth/me Current admin + roles/permissions
POST /api/v1/admin/auth/change-password Change password (clears session)

Customer / learner session (member_session)

Learners register and verify via email OTP, then receive a member_session cookie (JWT). All /api/v1/portal/* routes require it.

Endpoint Purpose
POST /api/v1/portal/auth/register Create an account + send email OTP
POST /api/v1/portal/auth/verify-otp Verify OTP → set session cookie
POST /api/v1/portal/auth/login Sign in → set session cookie
POST /api/v1/portal/auth/logout Clear the session
POST /api/v1/portal/auth/forgot · /reset Password reset via OTP
GET /api/v1/portal/auth/social/:provider Start a social sign-in flow

Public REST API add-on (bearer edu_ keys)

The REST API & Keys add-on (src/product/addons/api/) exposes a read-only data API authenticated by an API key rather than a session. Keys are issued under Admin → API Keys, are stored only as a SHA-256 hash, and carry scopes. Send the raw key either way:

HTTP
Authorization: Bearer edu_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-API-Key:     edu_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Each endpoint requires a scope; a key missing the scope is rejected with 403. The scopes are courses, customers, enrollments, orders (or * for all).

Status Meaning
401 Missing, invalid, or revoked API key
403 Key is missing the endpoint's scope

Interactive API docs (OpenAPI)

EduNest ships a hand-maintained OpenAPI 3.0 document and a Swagger UI page.

Resource URL Notes
Swagger UI /api-docs Swagger UI loaded from CDN, "Try it out" enabled
Raw OpenAPI JSON /api/openapi.json The spec consumed by the docs page

Both are protected by HTTP Basic Auth, enforced before the route is reachable. Credentials come from environment variables, with built-in fallbacks:

Terminal
API_DOCS_USER=admin        # default: admin
API_DOCS_PASS=Password@1    # default: Password@1

Both pages send noindex, nofollow (x-robots-tag) so they never appear in search engines. The spec is served force-static.

Terminal
# Download the live spec (Basic Auth required)
curl -u "$API_DOCS_USER:$API_DOCS_PASS" \
  http://localhost:3000/api/openapi.json -o edunest-openapi.json

The bundled /api/openapi.json documents the public, customer-portal, checkout and a representative slice of the admin endpoints. The REST API add-on publishes its own OpenAPI 3.1 spec separately at /api/v1/ext/api/openapi (see below).


Endpoint reference

The tables below list real route handlers under src/app/api/. List endpoints generally accept query params; :id / :slug are path params.

Storefront auth (public + portal)

Method Path Purpose
POST /api/v1/portal/auth/register Register a learner (email OTP)
POST /api/v1/portal/auth/verify-otp Verify OTP, sign in
POST /api/v1/portal/auth/login Sign in
POST /api/v1/portal/auth/logout Sign out
GET /api/v1/portal/auth/social/providers List enabled social providers
GET /api/v1/portal/me Current learner profile

Courses (catalog)

Method Path Purpose
GET /api/v1/courses List published courses
GET /api/v1/courses/facets Filter facets (level, category, …)
GET /api/v1/courses/:slug Course detail
GET /api/v1/courses/:slug/reviews · POST List / submit course reviews
POST /api/v1/courses/:slug/enroll Enroll in (free/open) course
GET /api/v1/course-categories List categories
GET /api/v1/learn/:slug Player payload (sections, lessons, progress)
POST /api/v1/learn/:slug/lessons/:lessonId/complete Mark a lesson complete

Enrollments & progress (portal)

Method Path Purpose
GET /api/v1/portal/enrollments The learner's enrollments
GET /api/v1/portal/dashboard Dashboard summary
GET /api/v1/portal/grades Quiz/assignment grades
GET /api/v1/portal/learning-paths Learning paths
GET /api/v1/portal/wishlist Wishlist

Orders & checkout

Method Path Purpose
POST /api/v1/checkout Place an order
GET /api/v1/checkout/methods Enabled payment methods
POST /api/v1/checkout/coupon Apply a coupon to the cart
POST /api/v1/checkout/verify Verify a gateway payment
GET /api/v1/checkout/return/:provider Gateway redirect target
GET /api/v1/portal/orders · /:id The learner's orders
POST /api/v1/coupons/validate Validate a coupon
POST /api/v1/gift-cards/validate Validate a gift card

Customers (admin)

Method Path Purpose
GET /api/v1/admin/customers · /:id List / fetch customers
GET /api/v1/admin/learners List learners
GET /api/v1/admin/orders · /:id List / manage orders
GET/POST /api/v1/admin/coupons Manage coupons
GET/POST /api/v1/admin/gift-cards Manage gift cards
GET /api/v1/admin/dashboard · /api/v1/admin/revenue KPIs + revenue series

Admin catalog & content

Method Path Purpose
GET/POST /api/v1/admin/courses · /:id Manage courses
* /api/v1/admin/courses/:id/sections · /lessons Curriculum
POST /api/v1/admin/courses/:id/status Publish / unpublish
GET/POST /api/v1/admin/course-categories Categories
GET/POST /api/v1/admin/instructors Instructors
GET/POST /api/v1/admin/quizzes · /surveys · /bundles Assessments & bundles
GET/POST /api/v1/admin/pages · /blogs · /faqs · /gallery CMS content
GET/POST /api/v1/admin/settings/:section Read / write a settings section

License

Method Path Purpose
GET /api/license/status Public license status (for the frontend banner)
GET/POST /api/v1/admin/license Admin: view / activate the domain license
GET /api/v1/admin/addons/license Add-on entitlements

REST API add-on (/api/v1/ext/api/v1/*)

These are dispatched through the catch-all /api/v1/ext/[addon]/[...path] route into the add-on's handler map. Every endpoint is read-only and requires the scope shown.

Method Path Scope Purpose
GET /api/v1/ext/api/openapi — (public) The add-on's OpenAPI 3.1 spec
GET /api/v1/ext/api/v1/courses courses List published courses
GET /api/v1/ext/api/v1/courses/:slug courses Get a course by slug
GET /api/v1/ext/api/v1/customers customers List members
GET /api/v1/ext/api/v1/enrollments enrollments List enrollments
GET /api/v1/ext/api/v1/orders orders List orders (transactions)

List endpoints accept limit (≤ 100, default 50) and offset (default 0) and return an envelope:

JSON
{ "data": [ /* rows */ ], "limit": 50, "offset": 0 }

Request example (REST add-on)

Terminal
curl https://your-domain.com/api/v1/ext/api/v1/courses?limit=10 \
  -H "Authorization: Bearer edu_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
JSON
{
  "data": [
    {
      "id": 42,
      "slug": "intro-to-data-science",
      "title": "Intro to Data Science",
      "level": "beginner",
      "price_cents": 4999,
      "currency": "USD",
      "status": "published",
      "rating_avg": 4.7,
      "enrollment_count": 1280
    }
  ],
  "limit": 10,
  "offset": 0
}

The same key also works via the X-API-Key header:

Terminal
curl https://your-domain.com/api/v1/ext/api/v1/enrollments \
  -H "X-API-Key: edu_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Error responses

First-party routes return JSON { "error": "..." } with the appropriate HTTP status. The REST add-on uses the same shape:

Code Meaning
400 Bad request / validation error
401 Not signed in (missing/invalid session or API key)
403 Forbidden — missing RBAC permission, missing API-key scope, or unlicensed add-on
404 Resource not found
500 Server error
JSON
{ "error": "This key is missing the 'orders' scope." }

© CreativeCape Solutions · creative-cape.com · support@creative-cape.com