# CLAUDE.md - Moveris API Integration Rules ## Project Identity **Name**: [Your Project Name] **Type**: [Your stack, e.g. Next.js, Express, FastAPI] **Integration**: Moveris Liveness API v2 **Base URL**: https://api.moveris.com **Docs**: https://documentation.moveris.com ## Moveris API Overview Moveris answers one question: **Is there a real, living person in front of the camera right now?** Your app captures video frames from the user's camera, sends them to Moveris, and receives a verdict: **live** (real person) or **fake** (spoofing attempt) with a confidence score. ### Endpoints | Method | Endpoint | Use Case | |--------|----------|----------| | `POST` | `/api/v1/fast-check` | Send all frames at once (simplest integration) | | `POST` | `/api/v1/fast-check-stream` | Send one frame per request (real-time camera capture) | | `POST` | `/api/v1/fast-check-crops` | Send pre-cropped 224×224 faces (fastest processing) | | `GET` | `/health` | Check service status | ### Models | Model ID | Frames | Capture Time | Best For | |----------|--------|-------------|----------| | `mixed-10-v2` (Fast) | 10 | ~0.3 s | Low-friction, high-volume flows | | `mixed-30-v2` (Balanced) | 30 | ~1 s | Standard KYC & identity verification (recommended) | | `mixed-60-v2` (Thorough) | 60 | ~2 s | High-security onboarding | | `mixed-90-v2` (Extended) | 90 | ~3 s | Compliance-heavy flows | | `mixed-120-v2` (Maximum) | 120 | ~4 s | Highest scrutiny, regulatory edge cases | Start with **`mixed-30-v2`** (Balanced) unless you have a reason to choose differently. ### Score Interpretation | Score Range | Classification | Verdict | |-------------|----------------|---------| | 0–34 | VERY LOW | fake | | 35–49 | LOW | fake | | 50–64 | MEDIUM | fake | | 65–79 | HIGH | live | | 80–100 | VERY HIGH | live | Threshold: score ≥ 65 = live, score < 65 = fake. ## Critical Rules ### 1. NEVER Expose API Keys in Client-Side Code Always proxy requests through your backend server. Your backend adds the `X-API-Key` header before forwarding to Moveris. ```javascript // BAD — API key in the browser fetch('https://api.moveris.com/api/v1/fast-check', { headers: { 'X-API-Key': 'sk-your-api-key' } // NEVER DO THIS }); // GOOD — call your own backend, which adds the key fetch('/api/liveness/check', { method: 'POST', body: ... }); ``` ### 2. ALWAYS Store API Keys in Environment Variables Never hardcode credentials in source code. ```python # GOOD import os API_KEY = os.environ["MOVERIS_API_KEY"] # BAD API_KEY = "sk-live-abc123" # NEVER DO THIS ``` ### 3. ALWAYS Validate the Verdict Server-Side Never trust client-side liveness results. Verify the verdict on your server before granting access. ### 4. Frame Count Must Match the Model Send exactly the number of frames the model expects. `mixed-10-v2` expects 10 frames, `mixed-30-v2` expects 30, and so on. Mismatched counts return a 400 error. ### 5. Use PNG Format for Frames PNG is lossless and provides better accuracy than JPEG. The payload is larger, but the detection quality is worth it. ## Authentication Include your API key in the `X-API-Key` header on every request. ```bash curl -X POST "https://api.moveris.com/api/v1/fast-check" \ -H "Content-Type: application/json" \ -H "X-API-Key: sk-your-api-key" \ -d '{ ... }' ``` Get your API key from the [Moveris Developer Portal](https://developers.moveris.com). ## Integration Patterns ### Backend Proxy (Recommended) Your frontend captures frames and sends them to your backend. Your backend adds the API key and forwards to Moveris. ``` Browser/App → Your Backend → Moveris API (adds X-API-Key) ``` ### Fast Check (All Frames at Once) ```javascript const response = await fetch('https://api.moveris.com/api/v1/fast-check', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.MOVERIS_API_KEY, }, body: JSON.stringify({ session_id: crypto.randomUUID(), model: 'mixed-30-v2', source: 'live', frames: frames, // array of { index, timestamp_ms, pixels } }), }); const result = await response.json(); // result.verdict: "live" or "fake" // result.score: 0–100 // result.confidence: 0.0–1.0 ``` ### Fast Check Stream (One Frame at a Time) Send frames sequentially with the same `session_id`. The verdict arrives with the last frame. ```javascript const sessionId = crypto.randomUUID(); for (let i = 0; i < 30; i++) { const frame = captureFrame(i); const res = await fetch('https://api.moveris.com/api/v1/fast-check-stream', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.MOVERIS_API_KEY, }, body: JSON.stringify({ session_id: sessionId, model: 'mixed-30-v2', source: 'live', frame: { index: i, timestamp_ms: i * 33, pixels: frame }, }), }); const data = await res.json(); if (data.verdict) { console.log('Verdict:', data.verdict, 'Score:', data.score); } } ``` ### Escalation Pattern Use a fast model by default and escalate when the result is borderline: ``` User submits → Fast (mixed-10-v2) → High confidence → Done → Borderline → Balanced (mixed-30-v2) retry → Still borderline → Thorough (mixed-60-v2) final check ``` ## Frame Capture Best Practices - **Capture rate**: ~10 FPS for natural signal detection - **Format**: PNG (base64-encoded) - **Resolution**: 640×480 is a good balance of quality and payload size - **Lighting**: Even, front-facing lighting; avoid harsh shadows or backlighting - **Framing**: Face centered, head-and-shoulders composition - **Stillness**: User should be relatively still during capture ### Crop Requirements (for fast-check-crops) If using the crops endpoint: - Output size: 224×224 pixels (square PNG) - Face should fill ~30% of the crop (include hair, neck, some background) - Expand to 3× the detected face size, then resize to 224×224 - Too-tight crops (face > 50%) degrade accuracy ## Error Handling All errors return a consistent JSON format: ```json { "error": "error_code", "message": "Human-readable description" } ``` | Status | Error Code | What to Do | |--------|------------|------------| | 400 | `insufficient_frames` | Send exactly the number of frames the model expects | | 400 | `missing_field` | Check that `session_id`, `frames`/`frame`, and required fields are present | | 401 | `invalid_key` | Verify your API key in the `X-API-Key` header | | 402 | `insufficient_credits` | Top up credits in the [Developer Portal](https://developers.moveris.com) | | 422 | `validation_error` | Check request format (field types, valid UUID, etc.) | | 429 | `rate_limit_exceeded` | Wait `retry_after` seconds, then retry. Limit: 240 requests/minute | | 500 | `internal_error` | Retry later. Check [status.moveris.com](https://status.moveris.com) for incidents | Implement retry with exponential backoff for transient errors (429, 500). ## SDK (Optional) For React and React Native projects, the Moveris SDK handles camera access, frame capture, face detection, and API calls: ```bash npm install @moveris/react @moveris/shared ``` | Package | Description | |---------|-------------| | `@moveris/shared` | Core client, types, constants (platform-agnostic) | | `@moveris/react` | React web components and hooks | | `@moveris/react-native` | React Native components and hooks | Docs: https://documentation.moveris.com/sdk/overview/ ## Security Checklist - [ ] API key stored in environment variables, never in source code - [ ] API key never sent from client-side code (use backend proxy) - [ ] `.env` file added to `.gitignore` - [ ] Verdict validated server-side before granting access - [ ] Rate limiting handled with exponential backoff - [ ] API key rotated periodically via the Developer Portal ## Resources - [Documentation](https://documentation.moveris.com) — Full API reference, guides, examples - [Developer Portal](https://developers.moveris.com) — API keys, credits, usage dashboard - [Models Overview](https://documentation.moveris.com/guide/models/overview/) — Model comparison and selection - [SDK Overview](https://documentation.moveris.com/sdk/overview/) — React and React Native SDK - [MCP](https://documentation.moveris.com/mcp/overview/) — AI agent integration for human verification - [Status Page](https://status.moveris.com) — Service health and incident reports