Verification Link
Overview
Verification Link lets you start the verification flow without embedding UI. Your backend creates a session and receives a one-time url
. You then either redirect the user to this url
or render a QR code with that link. After the user completes the flow, the final session payload is sent to your callbackUrl
(if provided) and is also available via Get Status.
Authentication
To access the API, you need to include the following headers in your request:
APP-ID: Your application's unique identifier.
APP-KEY: Your application's authentication key.
Session lifecycle
Statuses:
CREATED
,CAPTCHA_OK
,IN_PROGRESS
,DONE
,FAILED
,EXPIRED
,CANCELED
.nextStep:
LIVENESS
,DEEPFAKE
,ENROLL
,SEARCH
— the next operation to be performed;null
when finished.Expiration (TTL): 86400 s.
1) Create Link
Endpoint
POST https://cloud.ooto-ai.com/api/v1.0/flow/sessions
Headers
APP-ID
, APP-KEY
Content-Type: application/json
Body
scopes: string[]
required — allowed values:liveness
,deepfake
,search
,enroll
.metadata: object
optional — any JSON you need to carry along.callbackUrl: string
optional — your HTTPS endpoint that will receive the final session payload via POST.returnUrl: string
optional — where to redirect the user after flow completion.ttlSec: number
optional — requested TTL in seconds; bounded as per the formula above.
Response (200)
{
"sessionId": "<UUID>",
"token": "<opaque>",
"url": "https://cloud.ooto-ai.com/flow/<token>"
}
Usage
Redirect the user with HTTP 302/303 to
url
, orRender QR containing
url
for mobile handoff.
Callback contract
If
callbackUrl
is provided, OOTO‑AI sends a POST with the same structure as Get Status at completion time (see below). If you need retries/signature, implement them on your side.
2) Get Status
Endpoint
GET https://cloud.ooto-ai.com/api/v1.0/flow/sessions/<TOKEN>
Response (example)
{
"status": "DONE",
"scopes": [
"liveness",
"deepfake",
"search"
],
"nextStep": null,
"expiresAt": "2025-09-23T13:43:31.114Z",
"uiHints": {
"needCaptcha": false
},
"returnUrl": null,
"result": {
"box": {
"h": 451,
"w": 351,
"x": 182,
"y": 420
},
"search": {
"similarity": 0.8926131725311279,
"templateId": "16de28ea-dd15-4005-9a42-539e911db2d3"
},
"quality": {
"yaw": 2.1518145874142647,
"blur": {
"fine": true,
"score": 0.0002416080969851464
},
"roll": -0.10165892774239182,
"flare": {
"fine": false,
"score": 0.7195543646812439
},
"pitch": -2.330978773534298,
"crfiqa": {
"fine": true,
"score": 0.5868616104125977
},
"emotion": {
"fine": true,
"score": 0.010030289180576801
},
"contrast": {
"fine": true,
"value": 0.542739260497907
},
"exposure": {
"fine": true,
"value": 0.4497541851888898
},
"occlusion": {
"fine": true,
"score": 0.07414574921131134
},
"distortion": {
"fine": true,
"score": 0.8153706789016724
},
"uniformity": {
"fine": true,
"value": 0.7228297966860057
},
"macroblocks": {
"fine": true,
"score": 0.000059822112234542146
},
"leftEyeClosed": {
"fine": true,
"score": 0.0000013113021850585938
},
"rightEyeClosed": {
"fine": true,
"score": 2.384185791015625e-7
}
},
"deepfake": {
"fine": true,
"score": 0.9524966776371002
},
"liveness": {
"fine": true,
"score": 0.9612892089352414
},
"landmarks": [
[
288,
604
],
[
435,
604
],
[
367,
685
],
[
303,
762
],
[
422,
763
]
],
"demography": {
"age": 31,
"race": "white",
"gender": "male"
}
}
}
Notes
status
reflects lifecycle;nextStep
isnull
when finished.result
shape depends on selectedscopes
and contains the aggregated outputs.
Last updated