Verdicts
status_code | Numeric | status | Description |
|---|---|---|---|
voice_verified | 200 | verified | Voice matched the enrolled profile successfully. |
voice_enrolled | 201 | verified | First-time user — voice profile created during this session. |
voice_mismatch | 401 | failed | Voice biometrics did not match the enrolled profile. |
synthetic_voice_detected | 403 | failed | Audio was flagged as AI-generated, replayed, or otherwise spoofed. |
challenge_mismatch | 422 | failed | Spoken digits did not match the displayed challenge. |
age_requirement_not_met | 451 | failed | Predicted speaker age is below the space's minimum. Age-gated spaces only — see note below. |
age_inconclusive | 452 | failed | The age model could not commit to an answer. Age-gated spaces only — see note below. |
Age-gated codes
Both age codes only ever appear for spaces with age prediction enabled. Spaces without age prediction never load the model and never see either.
age_requirement_not_met is a positive answer: the predicted age bucket is below your configured minimum. A model error also returns this code, because we fail closed when the check cannot run.
age_inconclusive is the absence of an answer — the audio was silent or the model's confidence too low to commit. It is handed back to you unresolved, on purpose. Whether an inconclusive voice should be blocked, allowed, or routed to another age-verification method is a compliance decision that belongs to you, not to us, so we do not fold it into age_requirement_not_met. Note that 452 is a Helix convention, not an IANA-registered HTTP code.
String and numeric forms
Your callback always receives the string form — result.statusCode is what you branch on. The numeric column is the equivalent code used elsewhere in the Helix API; both mappings are exported as STATUS_CODE_NUMBERS and STATUS_CODE_STRINGS.