---
title: "Status codes"
description: "The seven verdicts a callback can carry, and what each one means for your user."
source: "/docs/status-codes"
updated: "2026-09-24"
---

# Status codes

The seven verdicts a callback can carry, and what each one means for your user.

## 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`.

## Reference List results

When your Space has **Reference List** enabled, every new enrollment (`voice_enrolled`) is screened against the people you added to the list in that Space and environment - whether you use it for people you have banned, for VIPs, or for both. `verifyCallback` returns the outcome as `result.referenceList`. It is absent on returning-user sessions and in Spaces without Reference List.

| `referenceList.result` | Description                                                                                                                                                          |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLEAR`                | The voice did not match anyone on your Reference List.                                                                                                               |
| `CONFIRMED_MATCH`      | The voice matched a listed person. `referenceList.matchedEnrollmentId` is the Enrollment ID you added, and `referenceList.matchedCategory` the category you gave it. |
| `UNSCOREABLE`          | Screening could not run for this enrollment. Treat it as unscreened, not as clear.                                                                                   |
| `UNRESOLVED`           | Reserved for multi-sample screening and not returned yet. Handle it like `UNSCOREABLE`, and map any value you do not recognize the same way.                         |

A match never blocks the user: the enrollment completes and `status` stays `verified`. Use `matchedCategory` to tell a banned person from a VIP; what happens next is your decision.

The `reference_list_*` params travel on the callback URL like every other callback param, so the user's browser can read them. Do not echo them back to the user.


## Sitemap

See the full [sitemap](https://helix.id/sitemap.md) for all pages.
