L O R I C A / docs
API REFERENCE

POST /v1/verify

Run a step-up verification at the moment of a high-risk action. Captures fresh frames, validates them against the enrolled embedding, and returns an HMAC-SHA256 signed JWT. 292ms median.

Request

POST /v1/verify
Authorization: Bearer lorica-prod-...
Content-Type: application/json
X-Lorica-Idempotency-Key: ver_xK2mP9nL3jH

{
  "user_id": "usr_4Z9X2fK8mPq",
  "action": "withdrawal",
  "amt": "50000",
  "asset": "USDT",
  "live": "dual_frame",
  "frames": [
    "data:image/jpeg;base64,/9j/4AAQ...",
    "data:image/jpeg;base64,/9j/4AAQ..."
  ]
}

Body parameters

FieldTypeRequiredDescription
user_idstringyesMust match a previously enrolled user.
actionstringyesAction class. Free-form but recommended values: withdrawal, wire, trade, reset, beneficiary_change.
amtstringnoAction amount as a decimal string. Included in the JWT for audit. Recommended for monetary actions.
assetstringnoAsset symbol. Included in the JWT for audit.
livestringnoLiveness mode: passive (default), dual_frame, active. Higher modes require more frames.
framesarray of stringsyesFresh JPEG base64 frames. passive: 1 frame. dual_frame: 2 frames. active: 3+ frames.

Response — 200 OK

{
  "jwt": "eyJhbGciOiJIUzI1NiI...",
  "verification_id": "ver_xK2mP9nL3jH",
  "match": true,
  "score": 0.9847,
  "iat": 1720123456,
  "exp": 1720123516
}

Always validate the JWT signature locally with your signing secret before trusting match or score. The JWT itself is the contract. See JWT Structure for the full claim list.

Response — error codes

HTTPCodeMeaning
404user_not_enrolledNo embedding for this user_id
422low_confidenceVerify completed but score below threshold — surface for review or block
422liveness_failedAnti-spoof scorer triggered block — escalate to active liveness or fail
422no_face_detectedSupplied frames don't contain a detectable face
429rate_limitedPer-key, per-tenant, or per-user cap exceeded