Video Detect (Async, Tenant-Scoped)¶
Submit a pre-recorded video for asynchronous liveness verification, then poll for the result.
In plain terms
Use this when you already have a full video file (for example, uploaded from a mobile app) and do not want to send frames one-by-one. You send the video once, get a submission_id, and check status until processing finishes.
Endpoints¶
| Method | Endpoint | Purpose |
|---|---|---|
POST | /api/v1/{tenant_slug}/video/detect | Submit video for async processing |
GET | /api/v1/{tenant_slug}/video/detect/{submission_id} | Poll status and get final result |
Authentication and Scopes¶
- Header:
X-API-Key: sk-... - Optional retry-safety header on submit:
Idempotency-Key: <unique-client-key> - Required scopes:
- Submit:
detection:write - Poll:
detection:read
- Submit:
- The API key organization must match
tenant_slug(tenant_mismatchotherwise).
Tenant slug and metadata schema
The {tenant_slug} path segment must match your organization’s configured tenant slug in the Developer Portal (Settings). If your org defines a video metadata schema, the optional metadata field is validated against it (see Video Metadata Schema in the Glossary).
Submit Video¶
POST /api/v1/{tenant_slug}/video/detect
Request¶
Content type: multipart/form-data
Optional header for safe retries:
| Header | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | No | Client-generated unique key for retry-safe submit requests. If you resend the same key with the same API key, the API returns the original submission instead of creating a duplicate job. |
| Field | Type | Required | Description |
|---|---|---|---|
video_file | file | Conditional | Video file upload. Provide exactly one of video_file or video_url. |
video_url | string | Conditional | Presigned/public video URL. Provide exactly one of video_file or video_url. |
model | string | No | Model alias. Default: mixed-10-v2. |
metadata | string (JSON object) | No | Tenant metadata as JSON string. Validated against tenant schema when configured. |
Allowed file extensions: mp4, avi, mov, webm, mkv.
cURL Example (file upload)¶
curl -X POST "https://api.moveris.com/api/v1/acme/video/detect" \
-H "X-API-Key: sk-your-api-key" \
-H "Idempotency-Key: onboarding-42-attempt-1" \
-F "video_file=@/path/to/selfie-video.mp4" \
-F "model=mixed-30-v2" \
-F 'metadata={"session_type":"onboarding","channel":"mobile"}'
Success Response (201)¶
All responses are wrapped in the standard envelope.
| Field | Type | Description |
|---|---|---|
submission_id | UUID string | Unique submission ID used for polling |
tenant | string | Tenant slug from path |
status | string | Always pending on submit |
model | string | Resolved model alias used for this submission |
message | string | Human-readable submission status |
tenant_metadata | object | null | Validated metadata echo |
created_at | string (ISO 8601) | Submission timestamp |
{
"data": {
"submission_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant": "acme",
"status": "pending",
"model": "mixed-30-v2",
"message": "Video submitted for processing. Poll the status endpoint for results.",
"tenant_metadata": {
"session_type": "onboarding",
"channel": "mobile"
},
"created_at": "2026-03-27T12:00:00Z"
},
"success": true,
"message": "OK"
}
Poll Submission Status¶
GET /api/v1/{tenant_slug}/video/detect/{submission_id}
cURL Example¶
curl -X GET "https://api.moveris.com/api/v1/acme/video/detect/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: sk-your-api-key"
Status Values¶
pending: queuedprocessing: runningcompleted: finished with resultfailed: finished with error
Completed Response (200)¶
| Field | Type | Description |
|---|---|---|
submission_id | UUID string | Submission identifier |
tenant | string | Tenant slug |
status | string | pending, processing, completed, or failed |
result | object | null | Unified verification result when status=completed |
tenant_metadata | object | null | Validated metadata echo |
message | string | null | Human-readable status text |
error | string | null | Error when status=failed |
created_at | string (ISO 8601) | Submission creation timestamp |
completed_at | string (ISO 8601) | null | Completion timestamp |
result object fields¶
| Field | Type | Description |
|---|---|---|
verdict | string | live or fake |
confidence | float | Confidence (0-1) |
real_score | float | Raw liveness probability (0-1) |
score | float | Percentage score (0-100) |
type | string | VERY LOW, LOW, MEDIUM, HIGH, VERY HIGH |
session_id | UUID string | Mirrors submission_id |
model | string | Model alias used |
input_source | string | video_upload |
processing_ms | integer | Processing time in milliseconds |
frames_processed | integer | Number of frames analyzed |
tenant_metadata | object | null | Metadata echo for correlation |
warning | string | null | Warning message if any |
created_at | string (ISO 8601) | Verification result generation timestamp |
{
"data": {
"submission_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant": "acme",
"status": "completed",
"result": {
"verdict": "live",
"confidence": 0.84,
"real_score": 0.84,
"score": 84.0,
"type": "VERY HIGH",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"model": "mixed-30-v2",
"input_source": "video_upload",
"processing_ms": 932,
"frames_processed": 30,
"tenant_metadata": {
"session_type": "onboarding",
"channel": "mobile"
},
"warning": null,
"created_at": "2026-03-27T12:00:01Z"
},
"tenant_metadata": {
"session_type": "onboarding",
"channel": "mobile"
},
"message": "Processing complete.",
"error": null,
"created_at": "2026-03-27T12:00:00Z",
"completed_at": "2026-03-27T12:00:01Z"
},
"success": true,
"message": "OK"
}
Common Errors¶
| HTTP | error | Meaning |
|---|---|---|
400 | invalid_video_input | Missing/duplicated video input, invalid format, or invalid model |
400 | invalid_metadata | Metadata is invalid JSON or fails tenant schema |
401 | invalid_key | Missing/invalid API key |
402 | insufficient_credits | Not enough credits for selected model |
403 | tenant_mismatch | API key does not belong to the requested tenant |
404 | tenant_not_found / submission_not_found | Tenant or submission does not exist |
503 | service_unavailable | Storage/queue/database dependency unavailable |
Integration Notes¶
Polling strategy
Poll every 1-2 seconds with exponential backoff. Stop when status is completed or failed.
Metadata
The API echoes tenant_metadata in both submit and status responses, so you can correlate results in your own systems.
Idempotent retries
Use one Idempotency-Key per business operation (for example, one onboarding attempt). If the client times out or loses connection, retry with the same key to get the same submission_id and avoid duplicate async processing.
Postman collection
Import the Moveris API Postman collection to test Video Detect (submit and poll) and the rest of the API.