Scoring Systems
Each biometric service returns its own score. A scoring system is the rule
set that combines those scores into one verdict — pass, refer or fail —
which you get back as scoring_result on v1 and as decision.status on
v2.
Every API token is bound to a scoring system. If you never create one, the project default applies.
The model
A scoring system is a list of scoring blocks (one per service) plus a scoring range:
| Block property | Meaning |
|---|---|
service | Which service this block scores, e.g. Face Liveness Detection. |
weight | Contribution to the weighted average, 0–1. |
fail_value | The block fails when the service score is at or below this value (0–100). |
is_critical | A failing critical block forces the whole verdict to fail, whatever the average is. |
active | Inactive blocks are skipped entirely. |
| Range property | Meaning |
|---|---|
pass_value | Weighted average at or above this → pass. |
fail_value | Weighted average at or below this → fail. |
Anything between the two is refer — the transaction needs a human look.
How a verdict is computed
For one request, in order:
- Inactive blocks are skipped.
- Blocks whose service never ran are skipped, with a reason recorded
(
… skipped: service not enabled on this API key). A mismatch between your scoring system and your token’s service list does not penalise the transaction. - Blocks whose service ran but produced no usable result are excluded from
the average — the service errored, or the user has no enrolled face or voice
yet. They are not scored zero, because a zero reads as a confident
biometric rejection. Their presence does force the outcome to at least
refer. - Each remaining block fails if its score is
<= fail_value(or is exactly0). A failing critical block sets the fail flag. - The weighted average of the remaining block scores is computed:
Σ(weight × score) / Σ(weight). - The verdict is decided:
| Condition | Verdict |
|---|---|
| A critical block failed | fail |
Average <= range.fail_value | fail |
| Some active service could not be evaluated | refer |
Average >= range.pass_value | pass |
| Otherwise (between the thresholds) | refer |
Two edge cases: if no block is active at all, the verdict is pass (nothing was
asked of the engine); if every active block was skipped or unevaluable, the
verdict is refer with no score — the response carries no score rather
than a misleading 0.
Every step that mattered is recorded in decision_reasons (v1) /
decision.reasons (v2), including which service failed against which
threshold, so you can show or log why a verification was rejected.
The default scoring system
Used when the project has no scoring system of its own:
| Block | Weight | Fail value | Critical | Active |
|---|---|---|---|---|
| Active Speaker Detection | 0.5 | 90 | yes | yes |
| Face Liveness Detection | 0.5 | 49 | yes | yes |
| Face Recognition | 0.5 | 49 | yes | no |
| Visual Speech Recognition | 0.5 | 49 | yes | no |
| Voice Recognition | 0.5 | 49 | yes | no |
Range: pass_value 80, fail_value 50.
So out of the box a transaction passes on liveness plus active-speaker agreement, and identity checks are not part of the verdict until you activate them.
Beyond the weighted average
Two service families do not fit the score-and-average model and have their own condition lists on the same scoring system:
- Face match conditions (
facematch_conditions) — field-path conditions evaluated against the/match-facesresult. Their outcome is what Face Match returns asscoring_result.status, withfailed_conditionsandfailed_refer_conditionslisting what tripped. - DocAuth conditions (
docauth_conditions) — checks applied to the document result:expiry_date(a date must be present and in the future) andvalidity.
Managing scoring systems
Scoring systems are configuration, so the endpoints require a Console user session, not a project API token, and creating or changing one needs the project owner or admin role. The normal path is the Console under Configurations → Scoring System.
| Operation | Endpoint |
|---|---|
| List | GET /api-gateway/v2/scoring-systems |
| List all versions | GET /api-gateway/v2/scoring-systems/all |
| Create | POST /api-gateway/v2/scoring-systems |
| Read | GET /api-gateway/v2/scoring-systems/{id} |
| Read a past version | GET /api-gateway/v2/scoring-systems/{id}/versions/{version} |
| Batch lookup | POST /api-gateway/v2/scoring-systems/info |
| Update | PATCH /api-gateway/v2/scoring-systems/{id} |
| Delete | DELETE /api-gateway/v2/scoring-systems/{id} |
| Project default | GET /api-gateway/v2/scoring-systems/default |
| Create from the default preset | POST /api-gateway/v2/scoring-systems/presets/default |
| Dry-run against a payload | POST /api-gateway/v2/scoring-systems/{id}/test |
presets/default is the only preset that exists; any other name returns 404.
Which system a request uses
- The scoring system bound to the API token (
scores_idin the key). - Otherwise the project’s scoring system.
- Otherwise the platform default above.
That resolution happens per request, so moving a token onto a different scoring system takes effect immediately — no redeploy on your side. Different tokens can carry different strictness: a lenient system for low-risk logins, a strict one for payments.