Mobile API & SDK
The Mobile API (/api/mobile/v1/*) is a parallel surface designed for native iOS, Android, and React Native apps. It uses publishable client keys (safe to embed in your app binary) plus server-side session state, so you can build multi-step verification flows without ever shipping a secret key.
SDK status (April 2026)
- React Native — first-party SDK available in
verifyhuman-mobile/with a working demo app.- iOS (Swift) — on the roadmap; integrate against the REST API in the meantime.
- Android (Kotlin) — on the roadmap; integrate against the REST API in the meantime.
The REST API documented below is stable and is what every SDK uses under the hood.
Authentication
All mobile endpoints are authenticated with a publishable client key sent in either of these headers:
Authorization: ClientKey vhk_live_...
or
X-Client-Key: vhk_live_...
The legacy
clientKeyquery/body parameter is not accepted on the/api/mobile/v1/*surface. Always send the key in a header.
Publishable keys identify your organization and environment. They cannot make account changes, drain credits beyond verification calls, or read other customers' data. Use a test key during development.
A demo prefix pk_demo_* is also accepted and returns deterministic responses without consuming credits — useful for SDK tutorials and screenshot generation.
Response envelope
All multi-step responses share a common envelope:
{
"success": true,
"session_id": "msess_test_...",
"verification_id": null,
"product": "verifyidentity",
"outcome": null,
"next_step": "upload_id_front",
"data": { "...": "step-specific payload" },
"meta": { "environment": "test", "step": "upload_id_front" }
}
| Field | Description |
|---|---|
success |
true if the request was accepted; false for errors. |
session_id |
The session being acted on (null for single-shot endpoints). |
verification_id |
The verification this session resolved to (populated after submit). |
product |
verifyhuman, verifyage, verifyidentity, or verifycompliance. |
outcome |
pass / fail / undetermined once the flow is terminal. |
next_step |
The step the client should drive next, or null when terminal. |
data |
Step-specific payload (rules, OCR result, scores, message). |
meta |
Environment and current step. |
Errors return success: false with code, message, optional retryable, and the same envelope fields where applicable.
Sessions
Multi-step flows (VerifyAge, VerifyIdentity, VerifyTrust) are coordinated by a server-side session identified by session_id. Sessions track per-step state so the device only sends one image at a time.
POST /api/mobile/v1/verifyidentity/session
→ { session_id: "msess_...", next_step: "upload_selfie", ... }
POST /api/mobile/v1/verifyidentity/upload/selfie (header X-Mobile-Session: msess_...)
POST /api/mobile/v1/verifyidentity/upload/id-front
POST /api/mobile/v1/verifyidentity/upload/id-back
POST /api/mobile/v1/verifyidentity/submit → final verification
Sessions expire after a product-specific TTL (typically 30 minutes of inactivity). Expired sessions cannot be resumed; start a new one.
Endpoints
VerifyHuman (1 credit)
| Method | Path |
|---|---|
| POST | /api/mobile/v1/verifyhuman/verify |
| GET | /api/mobile/v1/verifyhuman/status/{verification_id} |
VerifyAge (10 credits)
| Method | Path |
|---|---|
| GET | /api/mobile/v1/verifyage/rules |
| POST | /api/mobile/v1/verifyage/session |
| POST | /api/mobile/v1/verifyage/step1 (DOB) |
| POST | /api/mobile/v1/verifyage/step2 (selfie) |
| POST | /api/mobile/v1/verifyage/step3 (ID — only if escalation required) |
| GET | /api/mobile/v1/verifyage/status/{session_id} |
VerifyIdentity (40 credits)
| Method | Path |
|---|---|
| POST | /api/mobile/v1/verifyidentity/session |
| POST | /api/mobile/v1/verifyidentity/upload/selfie |
| POST | /api/mobile/v1/verifyidentity/upload/id-front |
| POST | /api/mobile/v1/verifyidentity/upload/id-back |
| POST | /api/mobile/v1/verifyidentity/submit |
| GET | /api/mobile/v1/verifyidentity/status/{session_id} |
| GET | /api/mobile/v1/verifyidentity/result/{session_id} |
VerifyTrust / KYC+ (60 credits)
| Method | Path |
|---|---|
| POST | /api/mobile/v1/verifycompliance/session |
| POST | /api/mobile/v1/verifycompliance/upload/selfie |
| POST | /api/mobile/v1/verifycompliance/upload/id-front |
| POST | /api/mobile/v1/verifycompliance/upload/id-back |
| POST | /api/mobile/v1/verifycompliance/submit |
| GET | /api/mobile/v1/verifycompliance/status/{session_id} |
| GET | /api/mobile/v1/verifycompliance/result/{session_id} |
Image format
Images are sent as base64 in the documented field for the step:
| Step | Field |
|---|---|
| Selfie upload | selfie_b64 |
| ID front | id_front_b64 |
| ID back | id_back_b64 |
| VerifyAge step1 (DOB) | date_of_birth (string, YYYY-MM-DD) |
Recommended: JPEG, ≤ 2 MB after compression, longest edge ≤ 1920 px. Larger images are accepted up to 8 MB but increase latency. The server validates magic bytes and rejects malformed payloads with INVALID_IMAGE.
Error states
| Outcome / HTTP | Code | Meaning | Mobile UX guidance |
|---|---|---|---|
200, outcome: pass |
— | Verified | Continue user flow |
200, outcome: fail |
— | Not verified (e.g. spoof, age below threshold, ID mismatch) | Allow one or two retries; consider escalation |
| 4xx | MISSING_REQUIRED_FIELD, INVALID_IMAGE, SESSION_WRONG_STEP, SESSION_EXPIRED |
Client error | Fix the client request |
| 401 | INVALID_CLIENT_KEY |
Wrong/revoked key, or env mismatch | Show "configuration error" |
| 402 | CREDITS_EXHAUSTED |
Account out of credits | Surface a billing prompt |
| 403 | SCOPE_NOT_AUTHORIZED |
Key scope doesn't include the product | Re-issue the key with correct scope |
| 429 | RATE_LIMITED |
Per-key rate limit hit | Honor Retry-After |
5xx with retryable: true |
SYSTEM_ERROR |
Provider/transient | Retry with backoff (1s, 3s, 9s); credit not consumed |
Privacy & data handling
VerifyHuman processes face images and ID documents only for the duration needed to produce a verification result.
- Single-shot calls (
/api/mobile/v1/verifyhuman/verify) process the image in memory and discard it as soon as the response is returned. - Multi-step session flows (VerifyAge, VerifyIdentity, VerifyTrust) hold uploaded image bytes inside the verification session so the flow can be assembled across requests. Image bytes are cleared from the session row as soon as the verification is submitted (pass or fail). Sessions that expire without being submitted (typically 30 minutes of inactivity) become unreachable through the API and are removed by routine housekeeping.
- No biometric vectors / facial templates are persisted at any time.
For the long-form security disclosure see Enterprise Security & Compliance.
React Native quick start
import { VerifyHuman } from '@verifyhuman/react-native';
const client = new VerifyHuman({ clientKey: 'vhk_live_...' }); // SDK adds the header for you
const result = await client.verifyHuman({ image: photo.base64 });
if (result.outcome === 'pass') {
// Send result.data.token to your backend for validation
}
Full SDK docs and example app: verifyhuman-mobile/.