{"openapi":"3.1.0","info":{"title":"Bolrach Identity API","version":"1.0.0","description":"Face verification on the self-hosted auth.ng idv-ml engine (CPU/ONNX: auraface recognition, scrfd/yunet detection, MiniFASNet presentation-attack detection). v1 is stateless: images are processed in memory and never stored. Full document-verification sessions and NIN/BVN rails remain first-party for compliance.","contact":{"url":"https://docs.bolrach.com/identity"}},"servers":[{"url":"https://api.bolrach.com"}],"security":[{"bearerKey":[]},{"headerKey":[]}],"paths":{"/v1/identity/face-match":{"post":{"operationId":"identityFaceMatch","summary":"Match a reference image against a selfie","description":"Compares the face in `reference_b64` (an ID-document photo or enrolment image) against `selfie_b64`, with passive liveness on the selfie. Nothing is stored: no session, no enrolment, frames live only for the request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference_b64":{"type":"string","description":"Base64 image (JPEG/PNG), up to ~6MB. No data: prefix."},"selfie_b64":{"type":"string","description":"Base64 image (JPEG/PNG), up to ~6MB. No data: prefix."},"level":{"type":"string","enum":["nin","bvn","full"],"default":"nin","description":"Match strictness profile."}},"required":["reference_b64","selfie_b64"]}}}},"responses":{"200":{"description":"The match verdict. Scores are 0.05-binned by design.","content":{"application/json":{"schema":{"type":"object","properties":{"engine_version":{"type":"string"},"face_matched":{"type":"boolean"},"face_match_score":{"type":"number"},"reference_faces":{"type":"integer"},"selfie_faces":{"type":"integer"},"hard_reject":{"type":"boolean","description":"Clear faces on both sides but similarity below the floor."},"pad_available":{"type":"boolean","description":"Whether passive liveness could run on the selfie."},"passive_pad_score":{"type":"number"},"screen_replay_score":{"type":"number"}},"required":["engine_version","face_matched","face_match_score","reference_faces","selfie_faces","hard_reject"]}}}},"400":{"description":"Bad input or undecodable image (`invalid_image`).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"403":{"description":"Key lacks the `identity:verify` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"429":{"description":"Rate limit or daily quota exceeded.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"502":{"description":"The identity engine did not answer (`upstream_error`).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}}}}},"/v1/identity/status":{"get":{"operationId":"identityStatus","summary":"Engine health and model lineup","responses":{"200":{"description":"Engine version and the models in service.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"engine":{"type":"string"},"ml":{"type":"string"},"models":{"type":"object"}}}}}},"400":{"description":"Bad input or undecodable image (`invalid_image`).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"403":{"description":"Key lacks the `identity:verify` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"429":{"description":"Rate limit or daily quota exceeded.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}},"502":{"description":"The identity engine did not answer (`upstream_error`).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"}},"required":["code","message","status"]}},"required":["error"]}}}}}}}},"components":{"securitySchemes":{"bearerKey":{"type":"http","scheme":"bearer","description":"Authorization: Bearer bt_..."},"headerKey":{"type":"apiKey","in":"header","name":"x-api-key"}}}}