Skip to content

Moveris MeetAPI Reference

REST endpoints exposed by Moveris Meet service. Base URL: https://<bot-url> (provided by Moveris for your environment).

In plain terms

These are the HTTP endpoints your backend calls to start and stop bot sessions. The interviewer view uses separate token-based endpoints that do not require your bot API key.

Endpoint Map

flowchart TB
    subgraph M2M["M2M — Bearer sk-bot-*"]
        P1[POST /api/sessions]
        P2[GET /api/sessions/:id]
        P3[DELETE /api/sessions/:id]
        P4[GET /api/sessions/:id/events]
        P4a[POST .../scan/:pid]
        P4b[POST .../retry/:pid]
        P4c[POST .../stop/:pid]
        P5[GET /api/analyses]
        P6[GET/PUT /api/settings/api-key]
    end

    subgraph Token["Interview token — no API key"]
        T1[GET /api/interview/:token]
        T2[GET /api/interview/:token/events]
        T3[GET /interview/* SPA]
    end

    subgraph Platform["Moveris platform — bot validates keys"]
        V1[POST /api/auth/v1/org-bot-keys/validate/]
    end
Method Path Auth Purpose
POST /api/sessions Bot API key Start bot for a meeting
GET /api/sessions/:id Bot API key Session state + results
DELETE /api/sessions/:id Bot API key Stop bot early
GET /api/sessions/:id/events Bot API key SSE — bot status + live verdicts
POST /api/sessions/:id/scan/:participantId Bot API key Start a scan for a waiting participant
POST /api/sessions/:id/retry/:participantId Bot API key Re-scan a participant who already has a result
POST /api/sessions/:id/stop/:participantId Bot API key Cancel an in-progress frame collection
GET /api/interview/:token Interview token Validate token; session ID + status
GET /api/interview/:token/events Interview token SSE — interviewer live view
GET /interview/* Interview token (URL) React SPA for observers
GET /api/analyses Bot key or OAuth Paginated analysis history
GET / PUT /api/settings/api-key Browser OAuth Org Moveris API key (UI)

Authentication

Machine-to-machine (your backend)

Authorization: Bearer sk-bot-<your-bot-key>

Required for all /api/sessions routes and settings endpoints.

Sessions are scoped to your org

A session created with your bot key can only be read, stopped, or controlled by that same key's org—GET/DELETE /api/sessions/:id, its SSE stream, scan, retry, and stop all return 404 (not 403) for a session belonging to another org, same as a session ID that doesn't exist at all. GET /api/analyses only returns your org's history.

Interview token (read-only observer)

Routes under /api/interview/:token use the signed interviewToken from session creation. No Authorization header.


Sessions

Create Session

Start a bot for a video meeting.

POST /api/sessions

Headers

Header Value
Authorization Bearer sk-bot-<your-bot-key>
Content-Type application/json

Request body

{
  "meetingUrl": "https://meet.google.com/abc-defg-hij",
  "model": "mixed-10-v3_1",
  "targetParticipantNames": ["John Smith"],
  "excludeParticipantNames": ["Jane Doe"]
}
Field Type Required Description
meetingUrl string Yes Google Meet, Zoom, or Microsoft Teams URL
model string No Mixed V2, V3, V3.1, or V3.1.1 alias — e.g. mixed-10-v2, mixed-30-v3, mixed-10-v3_1, mixed-30-v3_1_1, mixed-90-v3_1_1 (see Overview — Models)
meetingName string No Optional label for the meeting, stored with the session for your own analysis-history views. Not used by the bot or sent to Moveris
targetParticipantNames string[] No If provided, only participants whose names match are scanned. See Targeted participant scanning
excludeParticipantNames string[] No Names to skip — useful for excluding interviewers or known hosts
faceGate boolean No Enable face geometry / pose quality checks in addition to blur and brightness. Defaults to the deployment setting from Moveris. See Frame quality gating

Response 200 OK

{
  "sessionId": "550e8400-e29b-41d4-a716-446655440000",
  "botId": "bot_abc123",
  "status": "bot_created",
  "interviewToken": "eyJzZXNzaW9uSWQiOiI1NTBlODQwMC4uLiJ9.abc123sig",
  "message": "Bot is being created and will join the meeting shortly"
}

Get Session

Retrieve session state and stored results.

GET /api/sessions/:id

Headers

Header Value
Authorization Bearer sk-bot-<your-bot-key>

Response 200 OK

Returns session metadata, bot status, participants, and analysis results (shape varies by deployment and database configuration).


Delete Session

Stop the bot and end the session.

DELETE /api/sessions/:id

Headers

Header Value
Authorization Bearer sk-bot-<your-bot-key>

Response 200 OK

{
  "status": "stopped"
}

Manual Participant Control

Control frame collection for a single participant while the bot is in the call. Same bot-key auth as session create. Only one participant can accumulate frames at a time — a second scan or retry while another is accumulating returns 409.

POST /api/sessions/:id/scan/:participantId
POST /api/sessions/:id/retry/:participantId
POST /api/sessions/:id/stop/:participantId

Headers

Header Value
Authorization Bearer sk-bot-<your-bot-key>
Endpoint When to use Success response
scan Participant is waiting / ready — start collection { "status": "scanning", "participantId": "..." }
retry Participant already has a result — re-analyze { "status": "retrying", "participantId": "..." }
stop Cancel an in-progress accumulation (wedged quality gate, etc.) { "status": "stopped", "participantId": "..." }

409 Conflict — another participant is accumulating, the camera is off, or the session has already ended:

{ "error": "Another participant is currently being scanned" }

or

{ "error": "Camera is off — can't scan yet" }

or

{ "error": "This session has already ended" }

The third case fires when scan/retry targets a session that still exists (so it passes auth/org checks) but whose bot has already stopped — for example after the meeting ended or DELETE /api/sessions/:id was called.

Stop reasons

Frame collection can end before a verdict for four reasons, all surfaced as SSE participant-stage stopped: reason: "timeout" (stuck accumulating past the timeout; dynamic: scales with the model's frame count and whether face/background gating is enabled; 30s for a 10-frame scan with no gates, more for larger models or with gating on), reason: "camera-off" (participant's camera turned off mid-scan), reason: "manual" (your backend called stop, or the interviewer clicked Stop), or reason: "left" (participant left the meeting mid-scan). See Session Lifecycle: Participant Analysis Lifecycle.


Session Events (SSE)

Real-time session updates for authenticated clients.

GET /api/sessions/:id/events

Headers

Header Value
Authorization Bearer sk-bot-<your-bot-key>

Returns a Server-Sent Events (SSE) stream with bot status changes and participant verdict updates.

Event types

Event Fires when Key fields
session-status The bot status changes status (including fatal when a stale session expires and the bot leaves the meeting)
clear-participants Once, right after the session is created none — reset any participant state left over from a previous connection before the first real event arrives
participant-joined A participant is seen on camera for the first time participantId, participantName
participant-left A participant leaves the meeting participantId — see Participant Leaves the Meeting
participant-stage A participant moves between stages participantId, participantName, stage (waiting, matched, accumulating, analyzing, done, stopped); when stopped, includes reason (manual, timeout, camera-off, or left)
participant-matched A name matches targetParticipantNames (before the person speaks) participantId, participantName, matchedTarget, numericId
frame-progress A frame is added to a participant's buffer while accumulating participantId, participantName, frames, required
frame-quality-rejected A frame fails the quality gate (throttled ~1/sec per participant) participantId, participantName, reason, framesCollected, framesRequired
webcam-on / webcam-off A participant's camera turns on/off participantId, participantName
recall-connected / recall-disconnected The meeting provider's WebSocket connects/disconnects for this session (not per participant) none
participant-result A liveness verdict is ready participantId, participantName, verdict, score, confidence, isLive

Targeted scan stages

participant-stage and participant-matched are most useful in targeted scan mode. In scan-all mode you typically only need participant-result. Note: Moveris's own reference client doesn't listen for participant-matched directly — it renders the "matched, waiting for speech" state from participant-stage's stage: "matched" instead, so matchedTarget/numericId are there for your own integration to use if useful, not because the reference UI depends on them.

Quality feedback for M2M clients

Listen for frame-quality-rejected to show interviewer guidance without polling. Common reason values: too-blurry, too-dark, too-bright, no-face, multiple-faces, face-too-far, face-too-close, face-cut-off, face-not-centered, backlit, angle-yaw, angle-pitch, angle-roll. See Frame quality gating.


Interview (Token Auth)

Resolve Interview Token

Validate a token and return session status. Used by the interviewer SPA on page load.

GET /api/interview/:token

No authentication header. The token is passed in the URL path.

Response 200 OK

{
  "sessionId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "in_call_recording"
}

Just the session ID and bot status — no participant list. Participant names, stages, and verdicts arrive only over the SSE stream below, which replays current state on connect.


Interview Events (SSE)

Real-time participant updates for the interviewer view.

GET /api/interview/:token/events

No authentication header. Opens an SSE stream for live verdict updates.


Interviewer SPA

Serves the read-only React UI for observers.

GET /interview/*

No API key. The app route expects the signed token in the path: /interview/<interviewToken>.


Analysis History

List Analyses

Paginated history of past analyses (when database persistence is enabled).

GET /api/analyses

Headers

Header Value
Authorization Bearer sk-bot-<your-bot-key> or browser session (Google OAuth)
Query param Description
limit Page size. Default 50, capped at 200
offset Pagination offset. Default 0
verdict Filter by verdict
model Filter by model alias
meeting_source Filter by meeting platform
date_from / date_to Filter by creation date range

Response 200 OK

{
  "analyses": [ ],
  "total": 0,
  "limit": 50,
  "offset": 0
}

Requires database persistence enabled for your deployment (501 otherwise). Bot-key callers only ever see their own org's history.


Settings (Browser UI)

These endpoints support the bot's web UI for org API key management. M2M integrations typically configure the Moveris API key through Moveris staff or environment variables instead.

Method Path Description
GET /api/settings/api-key Get stored Moveris API key status
PUT /api/settings/api-key Update org Moveris API key

Error Responses

All errors return:

{
  "error": "Human-readable error message"
}
Status Meaning
400 Missing required field (e.g. POST /api/sessions without meetingUrl), meetingUrl isn't a valid http(s) URL, or model isn't a recognized alias
401 Invalid or revoked bot API key
403 POST /api/sessions only, bot-key-authenticated calls: your bot key has no Moveris API key linked for billing yet. Ask Moveris to link one; no session or bot is created
404 Session or resource not found—also returned for a session that belongs to a different org than your bot key, indistinguishable from a nonexistent ID
409 Another participant is already accumulating, the target participant's camera is off, or the session has already ended—see Manual Participant Control
500 Internal server error
501 GET /api/analyses only — database persistence isn't enabled for this deployment
503 Two distinct cases: (1) POST /api/sessions only: the bot's public callback URL is not reachable, so it refuses to create a session that could join the meeting but never receive video; (2) any bot-key-authenticated route: the bot could not reach Moveris key validation. Neither means your key is invalid. Retry once the service is reachable

Moveris Platform Endpoints (Bot Validation)

The bot validates your sk-bot- key against the Moveris Developer Portal API (not the bot itself):

POST https://<moveris-api-url>/api/auth/v1/org-bot-keys/validate/
Content-Type: application/json

{
  "key": "sk-bot-<your-bot-key>"
}

Success response (wrapped in the standard Moveris API envelope):

{
  "data": {
    "organization_id": 42,
    "organization_name": "Your Organization",
    "organization_slug": "your-org",
    "bot_display_name": "Liveness Verifier",
    "logo_url": "https://example.com/logo.png",
    "primary_color": "#0066ff"
  },
  "success": true
}