TrustWixDocs
Handle results

Reason codes

Stable machine codes explaining why a check did not approve

A reason code says why a check produced something other than approve. They are stable, upper snake case strings, they appear on the check that produced them and on the verification as a whole, and they are the right thing to branch on when you decide what to tell a user.

They are additive. New codes can appear at any time, so always have a default branch that shows generic guidance rather than throwing on an unrecognised code.

Selfie and liveness

CodeMeaning
BAD_VIDEO_SELFIEThe recorded selfie could not be used. Too dark, too blurred, or the face left the frame.
BAD_SELFIEThe still selfie could not be used, for the same kinds of reason.
CAMERA_OR_LIGHTING_ISSUESThe capture conditions defeated the check rather than the person.
LIVENESS_GESTURE_FAILEDThe person did not complete the movement they were asked to perform.
FACE_NOT_DETECTEDToo few of the captured frames contained a face to judge.
FRAUDULENT_LIVENESSThe capture evidenced a presentation attack rather than a live person.
VIDEO_FILTERS_OR_MASKSA filter or a mask was altering the face during capture.

Face match

CodeMeaning
BAD_FACE_MATCHINGThe selfie did not match the portrait on the document that was presented.
FACE_MATCH_LOW_CONFIDENCEInconclusive. The comparison came close to the line without passing it.
SELFIE_MISMATCHThe selfie appears to be a different person from the document.
PERSON_MISMATCHThe person in front of the camera is not the person on the document.

Document

CodeMeaning
EXPIRATION_DATEThe document is past its expiry date.
EXPIRY_UNREADABLENo expiry date could be read, so the document cannot be confirmed as in date.
PROPOSED_NOT_SETTLEDWe re-checked this session as maintenance. The result is waiting on a reviewer rather than settled.
DOCUMENT_EXPIRY_EXTENDEDPast its printed expiry, but carrying an official extension.
MRZ_CHECKSUM_INVALIDThe machine-readable zone failed its own integrity check.
ID_INVALIDThe document failed a structural validation: a number failed its check, or the printed page disagrees with the machine-readable zone.
INCOMPLETE_DOCUMENTA field genuine documents of this kind always carry is missing or fails its own check, for instance a masked national number. Learned per country and document type from reviewed documents.
OCR_LOW_CONFIDENCEReadable enough to process, not clean enough to be sure.
UNKNOWN_DOCUMENT_LAYOUTThe layout is one we have no specific reader for, so fields were read generically.
DATE_ORDER_SUSPECTThe printed dates cannot all be right, for instance issued after expiry.
NOT_DOCUMENTWhat was submitted is not a document we recognise.
DOCUMENT_MISSINGA required document was not supplied.
LOW_QUALITYThe image is too poor to read reliably.
OUTDATED_DOCUMENT_VERSIONA version of the document the issuer no longer produces.

Re-presentation and tampering

CodeMeaning
SCREENSHOTSThe file is a screenshot rather than a photograph taken with a camera.
SCREEN_RECAPTUREA photograph of a screen showing the document, rather than of the document.
GRAPHIC_EDITORThe file carries the signature of image-editing software.
TAMPERING_TRACECompression analysis found traces consistent with editing.
DIGITAL_DOCUMENTA digital rendering rather than a photograph of a physical document.
DOCUMENT_TEMPLATEThe image matches a specimen document the issuer publishes.
FORGERYThe document is not genuine.

One person, more than once

These say the verification is a repeat rather than that anything is wrong with the document. All three ask for a human and none of them rejects anybody on its own.

CodeMeaning
FRAUD_NETWORK_LINKThis person is linked to another applicant record.
DUPLICATE_DOCUMENT_IMAGEThe same image file was submitted under two different applicants.
DUPLICATE_DOCUMENT_IN_FLIGHTThe same document is on another verification of yours that is still open, under a different reference_id.
SHARED_DEVICESeveral applicants used the same browser profile.

DUPLICATE_DOCUMENT_IN_FLIGHT is worth knowing about, because it fills a window nothing else can see. If someone has already been approved, a second attempt is refused outright and you get ALREADY_VERIFIED. But two verifications started at the same time are both undecided, so neither can refuse the other, and both reach your queue looking like unrelated applicants. This code is what says they are not.

It only appears when the two carry different reference_id values. One person retrying their own verification is ordinary and never flagged.

Two more codes close a verification outright instead of asking for a human. Both appear on a session with status: "expired", and neither is a judgement about the person: they mean this session produced no new verification.

CodeMeaning
ALREADY_VERIFIEDYou already hold an approval for this person. Either the attempt was refused, or it was an open review case that another approval took off the queue.
REVIEW_IN_PROGRESSThis person already has a verification waiting on manual review, and this attempt was refused until that case is decided.

When a review case is closed by another approval, ALREADY_VERIFIED is added to the codes it already carried rather than replacing them, so you can still see why it went to review. The whole behaviour is described in Check existing applicants.

Applicant details

CodeMeaning
REQUESTED_DATA_MISMATCHThe details you sent do not match what the document says.
PROBLEMATIC_APPLICANT_DATAThe supplied details are internally inconsistent or implausible.
DB_DATA_MISMATCHThe details did not match the registry that was checked.
DB_DATA_NOT_FOUNDThe registry that was checked holds no record for these details.
INCORRECT_SOCIAL_NUMBERThe national number does not match the rest of the identity.

Compliance

CodeMeaning
AGE_REQUIREMENT_MISMATCHThe person's age falls in a range the flow refuses, at either end.
AGE_OUTSIDE_ACCEPTED_RANGEThe person's age falls in a range the flow sends to a reviewer.
AGE_NOT_DETERMINEDThe flow states an age requirement and no date of birth could be read.
SANCTIONSThe identity matched sanctions or watchlist data.
PEPThe identity matched politically exposed person data.
ADVERSE_MEDIAThe identity matched adverse media data.
CRIMINALThe identity matched criminal record data.
RESTRICTED_PERSONThe person may not be onboarded.
WRONG_USER_REGIONThe person is not somewhere the flow serves.

Nothing concluded

These do not say anything about the person. They say a check could not reach an answer, which is why they never appear alone on an approval.

CodeMeaning
CHECK_UNAVAILABLEThe check could not run.
CAPTURE_MISSINGThe capture the check needed was not there.
CHECK_SKIPPEDThe check was not run for this verification.

When your own policy decided

CodeMeaning
POLICY_WAIVEDThe verdict was softened by an acceptance rule you configured.

POLICY_WAIVED is added, never substituted. The findings that were waived stay on the check and on the verification, so a record always says both what was found and what you decided about it. If you see an approval carrying reason codes, this is why.

Turning codes into copy

Codes fall into two groups, and the distinction matters more than the individual code.

Some describe a capture problem, where the person is probably fine but the submission was not. BAD_VIDEO_SELFIE, OCR_LOW_CONFIDENCE and FACE_MATCH_LOW_CONFIDENCE are all in this group. Invite the user to try again with specific guidance, better light, a flat surface, no glare.

Others describe a substantive failure, where retrying will not help. AGE_REQUIREMENT_MISMATCH and SANCTIONS are in this group. Do not invite a retry, and be careful about how much detail you reveal, since telling someone precisely which screening list they matched is rarely appropriate.

Do not echo raw codes to users

Reason codes are machine strings for your logic, not user-facing copy. Map them to your own wording, in your own tone, in the user's language.

On this page