Cubite LMS ships a headless REST API, HMAC-signed webhooks and a hosted MCP server in its Growth plan at $290 a month or $2,900 a year; the plan highlight reads "Headless API, webhooks and MCP server". This page is the endpoint index: every public route under /api/v1 with the scope it needs, generated from the same registry the admin API keys card shows, plus the authentication, error, rate-limit and webhook conventions as the code implements them.
Request and response schemas and an OpenAPI document are later steps, not on this page yet. The worked example is the SureCart integration post linked below.
Create a key in Admin, under your site's Integrations tab, with the scopes it needs. The secret is shown once. Send it in the X-Cubite-Key header on every request to https://cubite.io/api/v1/...; the key, not the host, selects the site it acts on.
A key can carry a source IP allowlist (single IPs or CIDR ranges); a request from elsewhere gets 403. A credential approved for several sites picks the site per request with the X-Cubite-Site header; a site outside the grant is refused. The header's value is the site's id.
Authorization: Bearer tokens are accepted only by the MCP endpoint, which uses OAuth 2.1 with dynamic client registration; the REST routes take the key header only. Keys and tokens are stored as hashes.
curl -X POST https://cubite.io/api/v1/enrollments \
-H "X-Cubite-Key: ck_..." \
-H "Content-Type: application/json" \
-d '{"email":"learner@example.com","courseId":"...","redirectTo":"/course/foo/courseware","sendInvite":true}'The SureCart post walks through this call end to end: SureCart to Cubite enrollment with Ottokit.
| Status | When | Body |
|---|---|---|
| 400 | The body is malformed or a required field is missing. | { "error": "<what is missing or invalid>" } |
| 401 | No key, or a key that is unknown, revoked or expired. | { "error": "Missing X-Cubite-Key header" }, "Invalid API key", "API key revoked" or "API key expired" |
| 403 | The key lacks the route's scope, its IP allowlist excludes the caller, the X-Cubite-Site header names a site outside the grant, or the credential is a list-only MCP catalog key. | { "error": "Key missing required scope: courses:write" } |
| 404 | The object is not on the key's site. | { "error": "<object> not found" } |
| 429 | The key passed 120 writes or 600 reads in a minute. | { "error": "Rate limit exceeded for this API key. Retry later." } with Retry-After, X-RateLimit-Limit and X-RateLimit-Remaining headers |
A key carries only the scopes you give it. Scopes marked sensitive reach learner personal data, payment data or visitor search terms, create accounts, accept executable content or rewrite the emails learners receive; the consent screen shows them with emphasis when an assistant connection is approved.
| Scope | Grants | Sensitive |
|---|---|---|
| pages:read | View pages and blog posts | |
| pages:write | Create and edit pages and blog posts | |
| enrollments:read | View enrollments | Yes |
| enrollments:write | Enroll and unenroll learners | Yes |
| users:read | View users | Yes |
| users:write | Create, invite and manage users | Yes |
| courses:read | View courses and their content | |
| courses:write | Create and edit courses and their content | |
| site:read | View site settings | |
| site:write | Edit site settings, theme and homepage | |
| question-banks:read | View question banks | |
| question-banks:write | Manage question banks and questions | |
| media:write | Upload media (images and files) | |
| media:read | View the site's video library | |
| members:read | View site members | Yes |
| members:write | Manage site members and roles | Yes |
| groups:read | View groups and cohorts | Yes |
| groups:write | Manage groups and cohorts | Yes |
| learning-paths:read | View learning paths | Yes |
| learning-paths:write | Manage learning paths | Yes |
| packages:read | View uploaded xAPI/SCORM packages | |
| packages:write | Upload xAPI/SCORM packages (executable content) | Yes |
| reports:read | View aggregate analytics and reports | |
| search-console:read | View Google Search Console performance and SEO opportunities | Yes |
| certificates:read | View issued certificates | Yes |
| certificates:write | Issue, revoke and re-render certificates | Yes |
| discussions:read | View course discussions and the moderation queue | Yes |
| discussions:write | Post, moderate and manage course discussions | Yes |
| grading:read | View assignment, open-response and quiz submissions to grade | Yes |
| grading:write | Grade submissions and override scores and completions | Yes |
| forms:read | View form responses and form templates | Yes |
| forms:write | Create and delete reusable form templates | |
| announcements:read | View site announcements | |
| announcements:write | Create, edit and publish site announcements | |
| payments:read | View sales revenue and payment reconciliation | Yes |
| email-templates:write | Edit the site's transactional email copy | Yes |
| webhooks:read | View webhook subscriptions and their delivery log | Yes |
Method, path and the scope a key needs. Segments written :id, :qid, :courseId or :packageId are path parameters. The same table is shown in Admin beside your keys; both read one registry, checked against the route files by a script (npm run check:api-registry) that fails when a route has no row.
/api/v1/pages/api/v1/pages/api/v1/pages/:id/api/v1/pages/:id/api/v1/courses/api/v1/courses/api/v1/courses/:id/api/v1/courses/:id/api/v1/courses/:id/content/api/v1/courses/:id/content/api/v1/courses/:id/versions/api/v1/courses/:id/duplicate/api/v1/site/api/v1/site/api/v1/site/homepage/api/v1/site/homepage/api/v1/question-banks/api/v1/question-banks/api/v1/question-banks/:id/api/v1/question-banks/:id/questions/api/v1/question-banks/:id/questions/api/v1/question-banks/:id/questions/:qid/api/v1/question-banks/tags/api/v1/question-banks/tags/:id/api/v1/media/api/v1/videos/api/v1/packages/:packageId/api/v1/packages/:packageId/api/v1/packages/api/v1/packages/api/v1/users/api/v1/users/api/v1/users/:id/api/v1/users/:id/api/v1/users/invite/api/v1/enrollments/api/v1/enrollments/api/v1/applications/api/v1/applications/:id/api/v1/transcript/api/v1/members/api/v1/members/api/v1/groups/api/v1/groups/api/v1/groups/:id/api/v1/groups/:id/members/api/v1/groups/:id/members/api/v1/groups/:id/leaders/api/v1/groups/:id/leaders/api/v1/learning-paths/api/v1/learning-paths/api/v1/learning-paths/:id/api/v1/learning-paths/:id/api/v1/learning-paths/:id/enroll/api/v1/learning-paths/:id/learners/api/v1/learning-paths/:id/steps/api/v1/learning-paths/:id/prerequisites/api/v1/learning-paths/:id/prerequisites/api/v1/search/api/v1/reports/overview/api/v1/reports/courses/api/v1/reports/learners/api/v1/reports/completion-funnel/api/v1/reports/item-analysis/api/v1/reports/score-distribution/api/v1/reports/cohort-comparison/api/v1/reports/credits/api/v1/reports/page-views/api/v1/reports/at-risk/api/v1/reports/access-expiry/api/v1/reports/grading-sla/api/v1/reports/ecommerce/api/v1/reports/paid-not-enrolled/api/v1/search-console/overview/api/v1/search-console/queries/api/v1/search-console/pages/api/v1/search-console/opportunities/api/v1/search-console/status/api/v1/certificates/api/v1/certificates/api/v1/certificates/:id/api/v1/certificates/:id/api/v1/certificates/rerender/api/v1/certificates/config/api/v1/discussions/api/v1/discussions/api/v1/discussions/threads/:id/api/v1/discussions/threads/:id/api/v1/discussions/threads/:id/replies/api/v1/discussions/moderation/api/v1/discussions/moderation/api/v1/discussions/topics/api/v1/discussions/topics/api/v1/discussions/prompts/api/v1/discussions/prompts/api/v1/discussions/moderators/api/v1/discussions/moderators/api/v1/grading/assignments/api/v1/grading/assignments/:id/api/v1/grading/assignments/:id/grade/api/v1/grading/open-responses/api/v1/grading/open-responses/:id/api/v1/grading/open-responses/:id/assess/api/v1/grading/quiz-attempts/api/v1/grading/quiz-attempts/:id/review/api/v1/grading/quiz-attempts/:id/override/api/v1/grading/courses/:courseId/learners/api/v1/grading/courses/:courseId/completion-override/api/v1/forms/responses/api/v1/forms/templates/api/v1/forms/templates/api/v1/forms/templates/:id/api/v1/forms/templates/:id/api/v1/announcements/api/v1/announcements/api/v1/announcements/:id/api/v1/announcements/:id/api/v1/email-templates/api/v1/email-templates/api/v1/webhooks/api/v1/webhooks/:id/deliveriesSubscriptions are created in Admin, under the same Integrations tab, with a URL, the event types to receive (or * for all) and a signing secret, yours or one Cubite generates and shows once. Each delivery is an HTTP POST with a JSON body and three headers:
Verify by recomputing the HMAC over the raw request body with your secret and comparing it to the header in constant time; reject anything else. Deliveries and their status are readable through GET /api/v1/webhooks and GET /api/v1/webhooks/:id/deliveries (scope webhooks:read).
Event types (17)
A 30-minute call on your data flow, or email amir@cubite.io with the endpoints you need and the system on the other side.
Send us a message and we'll get back to you shortly.