Skip to main content
Safe Online Exam exposes all root-account administrator operations under the /api/admin prefix. This page documents every route available through the Canvas-embedded school dashboard — from reading the account summary and browsing connected courses, through controlled password reveals and course resets, to managing reusable school tool presets and processing rollout batches.
Every route under /api/admin requires a verified root-account administrator principal. That principal is established only after a successful LTI 1.3 launch that presents both a signed LTI Administrator role and Canvas’s signed root-account-admin substitution value. The numeric Canvas user ID and root-account ID are taken from the validated token; they cannot be supplied through query parameters or request bodies.
HMAC action token for mutations. All state-changing routes (marked ) additionally require a short-lived HMAC action token bound to the LTI subject, Canvas user ID, root-account ID, deployment ID, and current Express session. The token is issued by the server after a successful LTI launch and must accompany every mutation request. Requests that lack a valid token are rejected before reaching application logic.

Summary and Course Listing

GET /api/admin/summary

Returns a lightweight dashboard summary: Canvas account metadata, administrator permissions, the active operational enrollment term, configured-course totals, and tool-preset assignment counts. This endpoint triggers background course-status reconciliation (bounded to ADMIN_RECONCILE_BATCH_SIZE = 12 courses) and a one-time legacy connection backfill on first access. Auth: Verified root-account administrator. No action token required.

GET /api/admin/courses

Pages through connected courses for the active operational term. Supports cursor-based pagination, optional free-text search, and an includePast flag to include concluded courses. The response also includes the resolved operational term. Auth: Verified root-account administrator. No action token required.
Free-text filter applied to course name. Trimmed to 120 characters; extra whitespace is collapsed.
string
Base64URL-encoded pagination cursor from a previous response’s nextCursor field.
number
Page size, 1–50. Defaults to ADMIN_PAGE_SIZE = 25.
boolean
Pass "true" to include concluded courses. Defaults to false.

GET /api/admin/courses/:courseId

Returns full detail for one connected course, including its assessments, local setup state, and the list of school tool preset IDs currently assigned to it. Auth: Verified root-account administrator. The server validates that :courseId falls within the administrator’s Canvas root account.
string
required
Numeric Canvas course ID.

GET /api/admin/course-catalog

Browses active Canvas courses via the Canvas admin API in bounded, server-filtered pages. Each course entry is annotated with a connected boolean indicating whether it is already in the local connection index. Results come from Canvas directly and are not cached. Auth: Verified root-account administrator. No action token required.
string
Free-text course search forwarded to the Canvas API.
string
Canvas enrollment term ID to filter by.
string
Pagination cursor from a previous response.
boolean
Pass "true" to include unpublished courses.
boolean
Pass "false" to omit enrollment data. Defaults to true.

GET /api/admin/terms

Returns the list of active Canvas enrollment terms and the currently persisted operational term for the root account. The operational term defaults to the currently active term if none has been saved. Auth: Verified root-account administrator. No action token required.

PUT /api/admin/terms/operational

Persists the root account’s shared operational term selection. The supplied termId must be present in the live Canvas term list; otherwise the request is rejected with 400. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas enrollment term ID.

POST /api/admin/courses/connect

Validates, connects, and performs an initial Classic Quiz and New Quiz discovery for one or more Canvas courses. Each course is validated against the administrator’s root-account boundary. Accepts a JSON body with either a courseIds array of numeric IDs or an input string of whitespace- or comma-separated IDs and Canvas course URLs. Maximum 50 courses per request. Auth: Verified root-account administrator. Action token required.
string[]
Array of numeric Canvas course IDs.
string
Whitespace or comma-separated Canvas course IDs or full Canvas course URLs (e.g. https://canvas.example.edu/courses/456).

POST /api/admin/courses/:courseId/refresh

Refreshes Classic Quiz and New Quiz discovery for one connected course using the administrator’s account-level Canvas grant. Updates the course connection record and assessment counts. Auth: Verified root-account administrator. Action token required. Course must be in the connection index.
string
required
Numeric Canvas course ID.

POST /api/admin/courses/:courseId/reset

This operation is destructive. The reset disables every SEB-enabled Canvas assessment in the course (removing Canvas access codes), then deletes all local course setup in a single PostgreSQL transaction. Canvas OAuth authorization for the course users is deliberately preserved.The operation uses a two-phase approach with full compensation:
  1. Preflight — strict read-only Canvas discovery and access-code state capture. No changes are made yet.
  2. Canvas mutations — each access code is removed using the administrator grant.
  3. Database transaction — assessments, course policy, transient state, and per-course preset assignments are deleted atomically. A durable reset receipt is stored on the connection record.
If a Canvas mutation fails, a later Canvas write fails, or the database transaction definitively fails, the service restores the exact pre-reset Canvas access codes and assessment records in reverse order. If the transaction commit response is ambiguous, the service reads the durable receipt before deciding whether to compensate. An unavailable receipt check, failed compensation, or lost operation lease is reported as ADMIN_COURSE_RESET_VERIFY_REQUIRED — an indeterminate result that requires manual refresh and verification.A confirmation field containing the exact numeric course ID must be present in the request body. Without it the request is rejected before any Canvas call is made.
Auth: Verified root-account administrator. Action token required. Course must be in the connection index.
string
required
Numeric Canvas course ID.
string
required
Must equal the exact :courseId value. Used as a mandatory safety confirmation.
Error codes:

Password and Access-Code Management

All password reveal responses are short-lived and no-store. The server sets Cache-Control: no-store and related security headers. Each response carries expiresInSeconds: 30 as a client hint. The Canvas access code is included in the assessment-level reveal. Managed server-default exit passwords are never returned to the browser.

POST /api/admin/courses/:courseId/passwords/reveal

Reveals the course-level start and exit passwords. The effective exit password resolution order is: course-level override → managed server default → none. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas course ID.

POST /api/admin/courses/:courseId/quit-password/rotate

Generates a new cryptographically random exit password for the course, saves it as the course-level override, and returns the new value in the no-store response. Students currently in an active SEB session will use the new password when SEB prompts them to quit. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas course ID.

POST /api/admin/courses/:courseId/assessments/:assessmentId/passwords/reveal

Reveals start password, exit password, and Canvas access code for a single assessment. Each value includes a source indicating whether it is an assessment-level override, a course default, a managed server default (value withheld), or unset. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas course ID.
string
required
Canonical content ID (classicquiz_{id} or newquiz:{courseId}:{assignmentId}).

POST /api/admin/courses/:courseId/assessments/:assessmentId/quit-password/reset

Resets the assessment’s exit password to its effective default (course override or managed default), removing any assessment-level override. Does not rotate the underlying password — it removes the override so the assessment inherits the course or managed value. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas course ID.
string
required
Canonical content ID.

POST /api/admin/courses/:courseId/assessments/:assessmentId/reset-defaults

Returns one assessment to course defaults: clears URL policy, password overrides, and tool-ID selections so the assessment inherits the full course catalog. Does not change the Canvas access code or sebRequired state. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas course ID.
string
required
Canonical content ID.

POST /api/admin/courses/:courseId/assessments/:assessmentId/regenerate-code

Generates a new Canvas access code and applies it to the assessment. Dispatches to the Classic Quiz or New Quiz Canvas API based on the content ID format. Returns the updated SEB setting view on success. Returns 409 if SEB is not currently enabled for the assessment. Auth: Verified root-account administrator. Action token required. Uses the administrator’s account-level Canvas grant.
string
required
Numeric Canvas course ID.
string
required
Canonical content ID.

PUT /api/admin/courses/:courseId/assessments/:assessmentId/seb

Enables or disables SEB enforcement on a single assessment. Acquires both the course-level write lock and the assessment operation lock; ordinary instructor mutations cannot overlap this call. After the Canvas mutation and local state change, the connection record’s assessment counts are updated atomically. Auth: Verified root-account administrator. Action token required.
string
required
Numeric Canvas course ID.
string
required
Canonical content ID.
boolean
required
true to enable SEB and set the Canvas access code; false to disable and remove it.

Tool Presets

School tool presets are reusable exam-tool definitions stored at the root-account level in admin_tool_presets. Assigning a preset to a course synchronizes it into the course catalog as a school-managed entry; instructors may enable or disable it but cannot change its launch URL or resource rules. Each account may have at most 32 presets.

GET /api/admin/tool-presets

Returns all tool presets for the administrator’s root account, including assignment counts and rollout status. Auth: Verified root-account administrator. No action token required.

POST /api/admin/tool-presets

Creates a new school tool preset. The tool definition requires an exact HTTPS launch URL. Resource access rules must be explicit HTTPS URLs or confirmed domains — regex patterns, wildcards, and broad domain rules without broadDomainConfirmed: true are rejected. Preset names must be 1–80 characters; descriptions must not exceed 240 characters. Auth: Verified root-account administrator. Action token required.
string
required
Preset display name, 1–80 characters.
string
Optional description, up to 240 characters.
ExternalToolConfig
required
Tool definition. Must include an exact HTTPS url. Resource rules go in allowedRules; each rule with match: "domain" must have broadDomainConfirmed: true.

PUT /api/admin/tool-presets/:presetId

Updates an existing preset’s name, description, and tool definition. After saving, all active course assignments for the preset are marked "pending" so the next reconciliation run propagates the change to every assigned course. Auth: Verified root-account administrator. Action token required. The preset must belong to the administrator’s root account.
string
required
UUID of the preset to update.

DELETE /api/admin/tool-presets/:presetId

Deletes a preset. The preset must have no active (desiredAssigned: true) course assignments; otherwise the request returns 409. Completed (applied) assignment records for unassigned courses are cleaned up automatically before deletion. Auth: Verified root-account administrator. Action token required.
string
required
UUID of the preset to delete.

PUT /api/admin/tool-presets/:presetId/courses/:courseId

Assigns or unassigns a preset for a single Canvas course. Sets the desired assignment state, then immediately attempts to apply it by running one reconciliation pass. If the synchronization fails, the assignment is saved with status: "failed" for later retry — the response body indicates failure with error_code: "ADMIN_TOOL_PRESET_ROLLOUT_FAILED" but the endpoint returns 502 rather than silently succeeding. Auth: Verified root-account administrator. Action token required. The course must be in the connection index and within the administrator’s root account.
string
required
UUID of the preset.
string
required
Numeric Canvas course ID.
boolean
required
true to assign; false to unassign.

PUT /api/admin/tool-presets/:presetId/assignments

Queues a selected-course or all-course rollout for a preset. Saves desired assignment state for all specified courses, then synchronizes a bounded batch (ADMIN_RECONCILE_BATCH_SIZE = 12) immediately. Maximum 2,000 connected courses per rollout request. Auth: Verified root-account administrator. Action token required.
string
required
UUID of the preset.
boolean
required
true to assign; false to unassign.
boolean
required
When true, the rollout targets all connected courses for the root account. courseIds is ignored when all is true.
string[]
Explicit list of numeric Canvas course IDs. Required when all is false.

POST /api/admin/tool-presets/:presetId/assignments/reconcile

Processes a bounded batch of pending (and optionally failed) assignments for a preset. Each assignment is applied under both a preset-specific operation lock and the course write lock, so it cannot race against a concurrent course reset or tool copy. This endpoint is used for incremental rollout processing and retry. Auth: Verified root-account administrator. Action token required.
string
required
UUID of the preset.
boolean
When true, assignments in "failed" state are retried alongside "pending" ones. Defaults to false.

Assessment View Reference

Admin routes that return assessment lists use the adminAssessmentView shape:
string
Canonical content ID (classicquiz_{id} or newquiz:{courseId}:{assignmentId}).
string
Numeric Canvas course ID.
string
"CLASSIC_QUIZ" or "NEW_QUIZ".
string
Assessment title from the last Canvas discovery run.
boolean
Whether the assessment is published in Canvas.
boolean
Whether SEB enforcement is currently required.
boolean
Whether local SEB state is enabled (may differ from sebRequired during transitions).
boolean
Whether a Canvas access code is currently set.
boolean
Whether a start password is configured.
boolean
Whether an exit password is configured.
boolean
Whether the assessment inherits URL policy and tool catalog from course defaults.
string
Canvas discovery status: "verified", "missing", "stale", or "unverified" for legacy records.
string | null
ISO 8601 timestamp of the last local write.

Common Error Codes

When Canvas rejects the stored OAuth token during a mutation, the server returns a descriptive error. For the course reset specifically, the response is 401 with CANVAS_AUTHORIZATION_REQUIRED and a message explaining that local records were not deleted.