The first-level fields
Result keys are strings
Every result block is indexed by image number as JSON text:"0", "1"… The biometric matrix is body.biometric["0"]["1"], not [0][1]. In typed languages, deserialize as Map<String, …>.
"0" vs "0") is always 100: it is each face against itself. If you also sent faceVectors, the vectors continue the numbering after the images: 1 image + 1 vector ⇒ keys "0" (the image) and "1" (the vector).
Reference values measured with vu_v4 on the team’s test photos: same person ≈ 93–95 · different people ≈ 19. With the same two photos, cosine yields 78 and euclidean_l2 yields 66: never compare scores across methodologies.
inferenceConfidence changes shape
It appears for every image, always, but in two shapes:
Type
code and confidence as optional. The mapping is fixed: 200 = high, 202 = medium, 406 = low.
What degrades the verdict: face mask, closed eyes, blur, non-frontal pose, extreme makeup, and — automatically — any image under 360 px on a side.
The 16 faceFeatures attributes
Each attribute is a 0–100 score where higher = more present: blurry, eyeglasses, sunglasses, faceMask, leftEyeClosed, rightEyeClosed, mouthOpen, beard, mustache, smiling, heavyMakeup, hat, earrings, necklace, necktie, lipstick. Use them to guide the user (“please remove your sunglasses”), not as identity conditions.
headPoseEstimation carries the pose in degrees: leftRight (yaw) and upDown (pitch). Zero is perfectly frontal; a face useful for biometrics usually sits within ±15°.
The antispoofing comes nested, with its own scale
antiSpoofingFace["0"] contains the full response of the Facial Antispoofing service, nested as-is:
spoofing field (boolean). Do not decide on its inner code or confidence: they carry the antispoofing service’s semantics, not Face Analysis’s.
Deserializer particularities
- Result blocks are indexed by string (
"0","1"), not by integer. inferenceConfidencehas two shapes:codeandconfidenceare optional.antiSpoofingFace[i]can be an object ornull.confidencesduplicatesbiometric: ignore it, but do not fail when it appears.- With
faceVectors, result numbering includes the vectors after the images. - The
500s arrive with a plain-text body, not JSON — see Errors.
Next: Errors
Error codes, the plain-text 500s, the batch abort with imageNumber, and what to retry.