← Proctoring Documentation

REST integration

Use this path when your platform is not launching Endpoint through LTI. If your platform supports LTI Proctoring Services, use LTI 1.3 Proctoring Services for the full lifecycle.

Production host: https://app.endpoint.solutions

All endpoints here are server-to-server. Do not call them from browser JavaScript; the credential is a long-lived tenant API key.

Authentication

Send:

Authorization: Bearer <api key>

The prefix must be exactly Bearer with one space. Missing or malformed auth returns 401 with {"error":"Missing Authorization header"}. An unknown key returns 401 with {"error":"Invalid API key"}.

Create a session

POST /proctoring/api/v1/webhooks/exam/register
Authorization: Bearer <api key>
Content-Type: application/json
{
  "user": {
    "id": "u-8814",
    "firstName": "Ada",
    "lastName": "Lovelace",
    "email": "ada@example.com"
  },
  "course": {
    "id": "c-204",
    "name": "Network Security"
  },
  "exam": {
    "id": "exam-204",
    "name": "Network Security Final",
    "url": "https://exams.example.com/instances/exam-204",
    "duration": 90,
    "date": "2026-09-10T14:00:00Z",
    "level": "professional",
    "instructions": "Closed book."
  }
}

user, course, and exam must all be present. user.email must be a valid email address. Other fields are stored as metadata and may be blank.

Send user.firstName and user.lastName if you want name matching during ID verification. Send exam.url; it is where the candidate is sent after check-in, and its host must be registered so the extension can arm.

Success:

{
  "success": true,
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "check_in_url": "https://app.endpoint.solutions/proctoring/candidate/start/xF3k...",
  "message": "Exam registration received"
}

Store session_id. It is the stable identifier for lifecycle updates and read endpoints.

Check-in URL

check_in_url is a bearer secret. It is not single-use. The candidate can reopen it to resume check-in or staging.

The URL stops working once the session reaches in_progress, completed, finalized, or cancelled. Deliver it only to the intended candidate.

REST sessions use the default candidate policy unless Endpoint changes tenant settings. There is no REST per-attempt policy claim.

Drive the lifecycle

POST /proctoring/api/v1/webhooks/exam/status
Authorization: Bearer <api key>
Content-Type: application/json
{
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "event_type": "assessment_ended"
}

Identify sessions by session_id whenever possible. reservation_uuid and exam.id fallback lookups exist, but session_id is the reliable key.

event_type Current behavior
assessment_started Starts monitoring only if the candidate has completed staging. Returns 200 either way; check current_status.
assessment_ended Ends the attempt from in_progress or stopping, calculates compliance score, starts recording finalization, and returns results inline.
assessment_finalized Moves a completed session to finalized.
assessment_canceled, assessment_reservation_canceled Cancels the session. Use before the exam starts.
assessment_no_showed, assessment_archived, assessment_passed Logged; no state change.
assessment_errored, assessment_failed, assessment_failed_exit_interview Logged for investigation; no automatic termination.
assessment_built Not a supported partner event. Do not send it.

Standard response:

{
  "success": true,
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "current_status": "completed"
}

assessment_ended also returns:

{
  "results": {
    "compliance_score": 90,
    "started_at": "2026-09-10T14:02:11Z",
    "ended_at": "2026-09-10T15:28:40Z",
    "duration_minutes": 86,
    "violations": [
      {
        "id": 4412,
        "type": "tab_switch",
        "severity": "medium",
        "description": "Switched away from the exam tab",
        "occurred_at": "2026-09-10T14:41:03Z"
      }
    ]
  }
}

Recordings are not in the inline results because they may still be uploading. Use webhooks or the recordings read endpoint.

Cancel is not a clean end for an in-progress attempt. To keep evidence, send assessment_ended.

Reschedule or cancel

POST /proctoring/api/v1/webhooks/exam/reschedule
{
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "exam": {
    "date": "2026-09-12T09:00:00Z",
    "duration": 120
  }
}
POST /proctoring/api/v1/webhooks/exam/cancel
{
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "reason": "candidate withdrew"
}

Both require bearer auth. reschedule requires an exam object. cancel sets status to cancelled and does not produce exam.completed.

Read results

GET /proctoring/api/v1/sessions/{session_id}/violations
Authorization: Bearer <api key>
{
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "violations": [
    {
      "id": 4412,
      "type": "tab_switch",
      "severity": "medium",
      "description": "Switched away from the exam tab",
      "occurred_at": "2026-09-10T14:41:03Z"
    }
  ]
}
GET /proctoring/api/v1/sessions/{session_id}/recordings
Authorization: Bearer <api key>
{
  "session_id": "9d2b6c31-1f45-4a80-b7de-5c1e0a3f9b22",
  "recordings_ready": true,
  "recordings": [
    {
      "type": "camera",
      "url": "s3://your-bucket/proctoring/9d2b6c31/camera.webm",
      "storage_provider": "partner_s3",
      "duration_seconds": 5189,
      "file_size_bytes": 104857600
    }
  ]
}

The recordings endpoint lists only partner_s3 recordings. recordings_ready means no upload is still pending; it does not mean every upload succeeded. Failed and skipped recordings are terminal states.

Routes for GET /proctoring/api/v1/sessions/{session_id}, /status, and /report may appear in older material, but they are not implemented read APIs. Use the two endpoints above.

Prefer webhooks

Configure a webhook URL and secret so you receive live violation.detected events and exam.completed after recording resolution. See Webhooks and events.

Onboarding checklist

  • API key issued.
  • Exam hostnames registered.
  • Optional partner S3 credentials configured.
  • Webhook URL and secret configured.
  • register returns 201 and you store session_id.
  • Candidate completes check-in and reaches your exam URL.
  • Your platform sends assessment_ended when the attempt ends.
  • Your receiver verifies X-Webhook-Signature.

Last verified: 2026-09-03 against main.