Moveris Meet — API 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)¶
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.
| 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.
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.
Headers
| Header | Value |
|---|---|
Authorization | Bearer sk-bot-<your-bot-key> |
Response 200 OK
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:
or
or
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.
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.
No authentication header. The token is passed in the URL path.
Response 200 OK
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.
No authentication header. Opens an SSE stream for live verdict updates.
Interviewer SPA¶
Serves the read-only React UI for observers.
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).
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
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:
| 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
}
Related¶
- How It Works — Pipeline and architecture
- Integration Guide — End-to-end integration walkthrough
- Session Lifecycle — Bot and participant state transitions
- Overview — Models — Supported model aliases for sessions
- Webhook Setup Guide — Configure webhook delivery