Othento REST API
Single-step, synchronous, API-key-driven verification endpoints. Call one step directly — no SDK and no session flow required. Each endpoint either creates a new session for you or attaches to an existing one you pass in.
Base URL
https://be.<your-domain>/api/v1/steps
Use the host assigned to your environment — sandbox or production.
Authentication
Every request must include your API key in a header:
X-API-KEY: <your_api_key>
Server-to-server only. Never put your API key in a browser-facing URL or in client-side code.
- Missing or malformed key →
401 Unauthorized. - Suspended organization or application →
403 Forbidden. - No active subscription →
402 Payment Required.
Session handling
Every request body accepts these two fields, whichever endpoint you call:
| Field | Required | Description |
|---|---|---|
sessionId |
No | An existing session’s external ID. When provided, this step is attached to that session. |
workflowId |
Only if sessionId is omitted |
The workflow to create a new session under. Ignored when sessionId is provided. |
If you omit sessionId, a new session is created automatically and its ID is returned in the response as sessionId — use that value to chain further steps onto the same session.
If the step has already completed or failed on that session, calling it again returns the existing result instead of re-running it. If it is still in progress you will get a 409.
Response shape
Every endpoint returns the same envelope:
{
"sessionId": "string",
"stepCode": "step_xxx",
"status": "Completed | Failed | Pending | SentToInference",
"decision": "Approved | Declined | InReview | null",
"statusReason": "string | null",
"result": { /* step-specific — see each endpoint below */ }
}result is null until the step reaches Completed.
Error format
Validation and business-rule errors return an RFC 9110 problem-details body:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "The request could not be processed",
"status": 400,
"errors": {
"<fieldName>": ["<message>"]
},
"instance": "/api/v1/steps/..."
}| Status | Meaning |
|---|---|
400 |
Validation error — missing or invalid field |
401 |
Missing or invalid API key |
402 |
No active subscription on your account |
403 |
Application or organization suspended, or feature not enabled on your plan |
404 |
sessionId or workflowId not found, or not owned by your application |
409 |
Step already in progress for this session |
ID Verification
POST /api/v1/steps/id-verification
Verifies an identity document — front and back images — against your configured document template.
{
"sessionId": null,
"workflowId": "wf_xxx",
"documentId": "doc_xxx",
"frontImageBase64": "<base64>",
"backImageBase64": "<base64 | null>",
"fileExtension": "jpg"
}documentId— required only if the session does not already have a document type selected.backImageBase64— required only if the selected document requires both sides.
{
"firstName": "string | null",
"lastName": "string | null",
"fullName": "string | null",
"dateOfBirth": "yyyy-MM-dd | null",
"dateOfExpiry": "yyyy-MM-dd | null",
"documentNumber": "string | null",
"personalNumber": "string | null",
"nationality": "ISO3 | null",
"nationalityCountryId": "string | null",
"issuingCountry": "ISO3 | null",
"issuingCountryId": "string | null",
"isMismatch": true,
"errorCategory": "string | null"
}Face Match
POST /api/v1/steps/face-match
Compares a live or candidate face image against a reference face image. Both images are always required directly in the request — this endpoint does not read a portrait from a prior ID-verification step.
{
"sessionId": null,
"workflowId": "wf_xxx",
"selfieImageBase64": "<base64>",
"refImageBase64": "<base64>",
"fileExtension": "jpg"
}{
"verified": true,
"similarity": 0.99,
"faceDetected": true,
"multipleFaces": false,
"errorCategory": "string | null"
}similarity is in the range [0, 1].
Liveness Check
POST /api/v1/steps/liveness-check
Passive liveness — checks whether the submitted face media is a live capture or a spoof (a photo of a photo, a screen replay, a mask). No interactive challenge is required from the user.
{
"sessionId": null,
"workflowId": "wf_xxx",
"selfieImageBase64": "<base64>",
"fileExtension": "jpg"
}selfieImageBase64 accepts either a single photo (jpg, jpeg, png, webp) or a short video (mp4) — set fileExtension accordingly. A video generally yields a more confident score through multi-frame fusion than a single photo does.
{
"livenessPassed": true,
"livenessConfidence": 99.9,
"livenessType": "Fusion(mfas=1.00)",
"faceDetected": true,
"multipleFaces": false,
"errorCategory": "string | null"
}livenessConfidence is in the range [0, 100].
AML Screening
POST /api/v1/steps/aml-screening
Screens an individual’s identity details against sanctions, PEP and watchlist data.
{
"sessionId": null,
"workflowId": "wf_xxx",
"firstName": "string | null",
"lastName": "string | null",
"fullName": "string | null",
"dateOfBirth": "yyyy-MM-dd | null",
"nationality": "ISO3 | null",
"nationalityCountryId": "string | null",
"issuingCountry": "ISO3 | null",
"issuingCountryId": "string | null",
"documentNumber": "string | null",
"personalNumber": "string | null",
"gender": "string | null"
}{
"matchStatus": "clear | potential_match | true_match",
"riskLevel": "low | medium | high | unknown",
"totalHits": 0,
"matches": [
{
"id": "string",
"name": "string",
"entityType": "person | company",
"types": ["sanction", "pep", "warning"],
"sources": ["string"],
"aka": ["string"],
"countries": ["ISO2"],
"countryIds": ["string"],
"matchTypes": ["string"],
"score": 0.0,
"isWhitelisted": false
}
]
}If the provider errors out, decision resolves to Declined with no result attached and statusReason set.
IP Analysis
POST /api/v1/steps/ip-analysis
Analyzes an IP address for fraud-risk signals — VPN, proxy, Tor and hosting detection, plus geolocation.
{
"sessionId": null,
"workflowId": "wf_xxx",
"ipAddress": "203.0.113.10"
}{
"ipAddress": "string",
"countryId": "string | null",
"country": "ISO3 | null",
"region": "string | null",
"city": "string | null",
"isp": "string | null",
"organisation": "string | null",
"asn": "string | null",
"isVpn": false,
"isProxy": false,
"isTor": false,
"isHosting": false,
"connectionType": "string | null",
"riskScore": 0
}riskScore is in the range [0, 100]. If the provider errors out, decision resolves to InReview with no result attached.
Step codes
Each endpoint reports its own stepCode in the response envelope:
| Endpoint | stepCode |
|---|---|
/id-verification |
step_id_verification |
/face-match |
step_face_match |
/liveness-check |
step_liveness_check |
/aml-screening |
step_aml_screening |
/ip-analysis |
step_ip_analysis |
Example request
A complete call against the face-match endpoint, creating a new session:
curl -X POST https://be.<your-domain>/api/v1/steps/face-match \
-H "X-API-KEY: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"workflowId": "wf_xxx",
"selfieImageBase64": "<base64>",
"refImageBase64": "<base64>",
"fileExtension": "jpg"
}'