Skip to main content

Overview

The ID verification report captures everything Didit extracted and validated from a government-issued identity document — passports, ID cards, driver’s licenses, and residence permits. It bundles the OCR’d biographical and document fields, signed URLs to the captured media, parsed and geolocated address data, per-side image quality scores, MRZ contents, multi-script (Latin / non-Latin) breakdowns, and cross-session document matches. The report is produced after the user completes the document-capture step in a workflow (or hits the standalone OCR endpoint). Didit identifies the document type, runs OCR, validates the MRZ / barcode / QR code, parses the address, screens for tampering (screen capture, printed copy, portrait manipulation), and compares the document against every other document captured in your application. Each report carries its own status — independent of the overall session status — that reflects how the ID step alone resolved:
  • Approved — document recognized, all required fields extracted, no decline-routed warning fired.
  • In Review — one or more warnings fired and your workflow routes them to review.
  • Declined — an auto-decline condition fired (unsupported document, expired document, portrait missing, blocklist hit, adaptive-age failure) or a warning whose configured action is Decline fired (minimum/maximum age default to Decline).
  • Expired — the document’s expiration_date passed after the verification. Didit’s ongoing expiration monitoring flips the report from Approved to Expired, appends a DOCUMENT_EXPIRED warning, and moves an approved session to the Kyc Expired session status.
  • Not Finished — the user never completed the capture step.

Where it appears in API responses

The ID report ships inside the id_verifications[] array — always a JSON array, never a singular id_verification object. Multiple entries appear when a workflow runs more than one document step (for example a primary ID plus a step-up).
  • Session decision APIGET /v3/session/{sessionId}/decision/ returns id_verifications[] at the top level. See Retrieve session decision.
  • Webhookssession.status.updated payloads include the same id_verifications[] array once the step has produced data. See Webhooks.
  • Standalone OCR API — direct document submission returns a singular id_verification object with the same fields. See OCR standalone API.
Read response.id_verifications[0] and iterate the array. The singular id_verification shape only exists on the standalone OCR API — it does not exist on the v3 decision endpoint.

Schema

The canonical field-by-field schema lives on the Data models reference page. The fields below come straight from IDVerificationV3Serializer, which extends IDVerificationV2Serializer and adds node_id plus the cross-session matches[] array — 40 fields in total.

Top-level fields

issuing_state is always country-level, never sub-national. For every document type, including driving licences issued by a state or province (Australia, the United States, Canada), issuing_state and issuing_state_name report the country (for example AUS / Australia), not the state. The sub-national value, when the document carries one, is available separately in parsed_address.region (falling back to extra_fields.state on some document types). The Business Console session overview shows this as a Region row underneath Issuing state when present.
Driver’s licences that carry two numbers (Australia). Australian licences print both a licence number, which identifies the holder’s driving entitlement and stays the same when a card is replaced, and a card number, which identifies the physical card and changes with every reissue. For these licences Didit always maps the numbers the same way:
  • personal_number — the licence number
  • document_number — the card number
This applies to every Australian state and territory (NSW, VIC, QLD, WA, SA, TAS, ACT, NT). On some variants the card number is printed only on the back, so it is read only when the back of the licence is captured. When no card number can be read, the licence number is reported as both document_number and personal_number, so document_number always carries an identifier once the verification finishes. personal_number is the licence number either way. On other document types document_number remains the primary OCR’d number and may itself be a holder-level identifier.

Image quality scores

front_image_quality_score and back_image_quality_score each return:
Use overall_score as a quick suitability check — scores above 70 generally indicate a capture good enough for reliable verification.

Cross-session matches

matches[] lists up to 5 other documents in your application that match this one — same date of birth, same issuing country, and a highly similar full name. Blocklisted documents additionally require an exact document-number match. Sessions belonging to the same user (same vendor_data) are excluded. Each entry includes session_id, session_number, vendor_data, verification_date, user_details (name, document_type, document_number), status, is_blocklisted (true when the document was added to your blocklist), api_service, and a signed front_image_url.

Status values

Multi-script documents (Latin / non-Latin)

Some documents — Kyrgyz, Kazakh, Russian, Japanese, Korean, Chinese, Arabic, Thai, and others — print the holder’s name, address, or place of birth in both a Latin transliteration and the local script. You choose which script powers the top-level response with the workflow (or standalone-API) setting preferred_characters: The alternate-script values live inside extra_fields under suffixed keys: first_name_non_latin, last_name_non_latin, middle_name_non_latin, full_name_non_latin, address_non_latin, place_of_birth_non_latin (or the matching _latin variants).

When alternate-script fields appear

  • Only when both scripts are actually present on the document. If an OCR field nominally labelled “Surname-Kyrgyz (Cyrillic)” is extracted as Latin-script text (homoglyphs or a Latin transliteration), it does not qualify as a non-Latin alternate and that key is omitted.
  • full_name_non_latin (and full_name_latin) are always reconstructed from the individual first-, middle-, and last-name components when both are available — the raw “Full Name” field from OCR is ignored for consistency.
  • When preferred_characters=latin but the document carries only non-Latin text (so the top-level fields end up non-Latin), Didit runs a transliteration pass and exposes first_name_latin, last_name_latin, middle_name_latin, full_name_latin, place_of_birth_latin, and address_latin as a Latin fallback.
last_name_non_latin is absent because the document’s “Surname (Cyrillic)” field came back as Latin characters on this sample — there was no genuine non-Latin surname to extract.

Examples

Approved — clean Spanish identity card (all fields)

In Review — QR not detected on a document that should have one

Abridged — a real response always carries the full field set shown above.

Security note

The signed URLs returned for document images and videos are temporary — they expire after a limited validity window. Treat them as short-lived: download what you need promptly and do not cache or surface them publicly. Typically your application only needs status, a handful of biographical fields, and the warnings — store as little as possible to minimize the surface for any future breach.