openapi: 3.0.0 info: version: 3.0.0 title: Didit Verification Billing Session API description: Identity verification API. Authenticate with x-api-key header. servers: - url: https://verification.didit.me tags: - name: Session paths: /v3/session/{sessionId}/decision/: get: summary: Retrieve the full decision for a verification session description: 'Retrieve the complete decision report for a verification session — the rolled-up session `status` plus one report per verification feature the workflow executed. This is the canonical read endpoint for both User Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level `session_kind` discriminator tells you which shape you received (`"user"` or `"business"`). **Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` — never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. **When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to fetch the full report. Polling also works — the endpoint can be called at any point in the session lifecycle and returns the data produced so far — but webhook-then-fetch is cheaper and faster. Media URLs in the response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request the decision to get fresh ones, and do not persist them as long-term references. **Statuses.** The top-level `status` is the session lifecycle status (`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Each feature item additionally carries its own feature-level `status` (`Not Finished`, `Approved`, `Declined`, `In Review`, ...). A session can be `Approved` overall while an individual feature is `In Review`, depending on the workflow''s decision rules. **Authentication and visibility.** Authenticate with the application API key in the `x-api-key` header (a console user Bearer token with the `read:sessions` permission also works). Only sessions owned by the authenticated application are visible. If your workflow restricts response attributes, non-allowed fields inside feature items are returned as `null` while `status`, `warnings`, and `node_id` are always preserved. **Rate limits.** GET requests are limited to 600 per minute per API key. Exceeding the limit returns `429` with `Retry-After` and `X-RateLimit-*` headers.' operationId: get_v3_session_decision responses: '200': description: 'Full decision report. `session_kind` discriminates the two shapes: `user` sessions carry the KYC feature arrays shown below; `business` sessions instead carry `registry_checks`, `document_verifications` and `key_people_checks` alongside the shared arrays. Feature arrays are `null` until the workflow has run that feature; media URLs are short-lived presigned links.' content: application/json: examples: Example: summary: Full Example value: session_id: 11111111-2222-3333-4444-555555555555 session_kind: user session_number: 43762 session_url: https://verify.didit.me/session/11111111-2222-3333-4444-555555555555 status: In Review environment: live workflow_id: 11111111-2222-3333-4444-555555555555 features: - ID_VERIFICATION - NFC - LIVENESS - FACE_MATCH - POA - PHONE - DATABASE_VALIDATION - AML - IP_ANALYSIS vendor_data: 11111111-1111-1111-1111-111111111111 metadata: user_type: premium account_id: ABC123 expected_details: first_name: Carmen last_name: Española Española contact_details: email: carmen@example.com email_lang: es send_notification_emails: false phone: null callback: https://verify.didit.me/ id_verifications: - node_id: feature_ocr_1 status: Approved document_type: Identity Card document_subtype: ID_CARD_GENERIC document_number: CAA000000 personal_number: 99999999R portrait_image: https:///portrait.jpg front_image: https:///front.jpg front_video: https:///front.mp4 back_image: https:///back.jpg back_video: https:///back.mp4 full_front_image: https:///full_front.jpg full_back_image: https:///full_back.jpg front_image_camera_front: https:///front_camera_front.jpg back_image_camera_front: https:///back_camera_front.jpg date_of_birth: '1980-01-01' age: 45 expiration_date: '2031-06-02' date_of_issue: '2021-06-02' issuing_state: ESP issuing_state_name: Spain first_name: Carmen last_name: Española Española full_name: Carmen Española Española gender: F address: Avda de Madrid 34, Madrid, Madrid formatted_address: Avda de Madrid 34, Madrid, Madrid 28822, Spain place_of_birth: Madrid marital_status: Single nationality: ESP extra_fields: dl_categories: [] blood_group: null mrz: surname: ESPANOLA ESPANOLA name: CARMEN country: ESP nationality: ESP birth_date: '800101' expiry_date: '310602' sex: F document_type: ID document_number: CAA000000 optional_data: 99999999R optional_data_2: '' birth_date_hash: '4' expiry_date_hash: '8' document_number_hash: '4' final_hash: '1' personal_number: 99999999R warnings: [] errors: [] mrz_type: TD1 mrz_string: 'IDESPCAA000000499999999R<<<<<< 8001014F3106028ESP<<<<<<<<<<<1 ESPANOLA/extra_id_verification.jpg matches: - session_id: 7d4f1f60-9c2e-4b8a-8f3d-2a1b5c6d7e8f session_number: 1234 vendor_data: user_ref_001 verification_date: '2024-06-15T10:30:00Z' user_details: name: John Smith document_type: ID document_number: CLM148418 status: Approved is_blocklisted: false api_service: null front_image_url: https:///document_front.jpg - session_id: b2c8e4d1-6a3f-4e7b-95c0-1d8f2a6b4c9e session_number: 1235 vendor_data: null verification_date: '2024-05-20T14:45:00Z' user_details: name: John Smith document_type: ID document_number: CLM148418 status: Declined is_blocklisted: true api_service: ID_VERIFICATION front_image_url: https:///document_front_2.jpg warnings: - feature: ID_VERIFICATION risk: QR_NOT_DETECTED additional_data: null log_type: information short_description: QR not detected long_description: The system couldn't find or read the QR code on the document, which is necessary for document verification. This could be due to poor image quality or an unsupported document type. node_id: feature_ocr_1 nfc_verifications: - node_id: feature_nfc_1 status: In Review portrait_image: https:///portrait.jpg signature_image: https:///signature.jpg chip_data: document_type: ID issuing_country: ESP document_number: '123456789' expiration_date: '2030-01-01' first_name: John last_name: Smith birth_date: '1990-05-15' gender: M nationality: ESP address: CALLE MAYOR 123 4B, MADRID, MADRID place_of_birth: MADRID, MADRID authenticity: sod_integrity: true dg_integrity: true certificate_summary: issuer: 'Common Name: CSCA SPAIN, Serial Number: 3, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES' subject: 'Common Name: DS n-eID SPAIN 2, Organizational Unit: PASSPORT, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES' serial_number: '118120836164494130086420187336801405660' not_valid_after: '2031-02-18 10:21:11' not_valid_before: '2020-11-18 10:21:11' warnings: - feature: NFC risk: DATA_INCONSISTENT additional_data: null log_type: warning short_description: OCR and NFC mrz code extracted are not the same long_description: The Optical Character Recognition (OCR) data and the NFC chip data don't match, indicating potential document tampering or data inconsistency. node_id: feature_nfc_1 liveness_checks: - node_id: feature_liveness_1 status: Approved method: ACTIVE_3D score: 89.92 reference_image: https:///reference.jpg video_url: https:///video.mp4 age_estimation: 24.3 matches: - session_id: 7d4f1f60-9c2e-4b8a-8f3d-2a1b5c6d7e8f session_number: 1234 vendor_data: user_ref_001 verification_date: '2024-06-15T10:30:00Z' user_details: full_name: John Smith document_type: ID document_number: CLM148418 status: Approved is_blocklisted: false is_allowlisted: false api_service: null source: session match_image_url: https:///face_match.jpg similarity_percentage: 98.5 - session_id: 3e9a7c21-5b48-4f0e-9c6a-8d2f4b1e0a35 session_number: 1100 vendor_data: customer_xyz verification_date: '2024-04-10T09:15:00Z' user_details: full_name: John Smith document_type: P document_number: DZ8375806 status: Approved is_blocklisted: false is_allowlisted: false api_service: PASSIVE_LIVENESS source: session match_image_url: https:///face_match_2.jpg similarity_percentage: 95.2 warnings: - feature: LIVENESS risk: LOW_LIVENESS_SCORE additional_data: null log_type: information short_description: Low liveness score long_description: The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data. node_id: feature_liveness_1 face_quality: null face_luminance: null face_matches: - node_id: feature_face_match_1 status: In Review score: 65.43 source_image_session_id: null source_image: https:///source-image.jpg target_image: https:///target-image.jpg warnings: - feature: FACEMATCH risk: LOW_FACE_MATCH_SIMILARITY additional_data: null log_type: warning short_description: Low face match similarity long_description: The facial features of the provided image don't closely match the reference image, suggesting a potential identity mismatch. node_id: feature_face_match_1 phone_verifications: - node_id: feature_phone_1 status: Approved phone_number_prefix: '+34' phone_number: '600600600' full_number: '+34600600600' country_code: ES country_name: Spain carrier: name: Orange type: mobile is_disposable: false is_virtual: false verification_method: sms verification_attempts: 1 verified_at: '2024-07-28T06:47:35.654321Z' lifecycle: - type: PHONE_VERIFICATION_MESSAGE_SENT timestamp: '2025-08-24T09:12:39.580554+00:00' details: status: Success reason: null channel: sms actual_channel: sms fee: 0.1 - type: VALID_CODE_ENTERED timestamp: '2025-08-24T09:12:39.662157+00:00' details: code_tried: '123456' status: Approved fee: 0 - type: PHONE_VERIFICATION_APPROVED timestamp: '2025-08-24T09:12:39.684292+00:00' details: null fee: 0 warnings: [] matches: - session_id: null session_number: null vendor_data: null verification_date: null phone_number: '+34600000000' status: null is_blocklisted: true api_service: null source: list_entry email_verifications: - node_id: feature_email_1 status: Approved email: test@example.com is_breached: true breaches: - name: TAPAirPortugal domain: flytap.com logo_path: https://logos.haveibeenpwned.com/TAPAirPortugal.png breach_date: '2022-08-25' description: In August 2022, the Portuguese airline TAP Air Portugal was the target of a ransomware attack perpetrated by the Ragnar Locker gang who later leaked the compromised data via a public dark web site. Over 5M unique email addresses were exposed alongside other personal data including names, genders, DoBs, phone numbers and physical addresses. is_verified: true data_classes: - dates_of_birth - email_addresses - genders - names - nationalities - phone_numbers - physical_addresses - salutations - spoken_languages breach_emails_count: 6083479 is_disposable: false is_undeliverable: false verification_attempts: 1 verified_at: '2025-09-15T17:36:19.963451Z' warnings: - feature: EMAIL risk: BREACHED_EMAIL_DETECTED additional_data: null log_type: information short_description: Breached email detected long_description: This email address was found in one or more known data breaches. node_id: feature_email_1 lifecycle: - type: EMAIL_VERIFICATION_MESSAGE_SENT timestamp: '2025-09-15T17:36:19.792684+00:00' details: status: Success reason: null fee: 0.03 - type: VALID_CODE_ENTERED timestamp: '2025-09-15T17:36:19.963427+00:00' details: code_tried: '123456' status: Approved fee: 0 - type: EMAIL_VERIFICATION_DECLINED timestamp: '2025-09-15T17:36:20.081471+00:00' details: reason: BREACHED_EMAIL_DETECTED fee: 0 matches: - session_id: null session_number: null vendor_data: null verification_date: null email: test@example.com status: null is_blocklisted: true api_service: null source: list_entry poa_verifications: - node_id: feature_poa_1 status: Declined document_file: https:///poa_document.pdf issuing_state: AR document_type: UTILITY_BILL document_subtype: null document_language: es document_metadata: file_size: 1000 content_type: application/pdf creation_date: '2021-01-01' modified_date: '2021-01-01' overlay_manipulation: null creator: null producer: PDF Generator software: null encryption: null is_signed: false is_tampered: false signature_info: null exif_original_date: null exif_digitized_date: null processed_by_known_editor: false has_different_creation_mod_date: true issuer: Aguas del Norte issue_date: '2021-02-01' expiration_date: null poa_address: AVDA. MONSEÑOR TAVELLA N° 3396, SALTA poa_formatted_address: Av. Monseñor Tavella 3396, A4400 Salta, Argentina poa_parsed_address: address_type: Avenida street_1: Avenida Monseñor Tavella 3396 street_2: null city: Salta region: Salta country: AR postal_code: A4400 document_location: latitude: -24.8208664 longitude: -65.4131 name_on_document: Fernando De Lima name_match_score_expected_details: null name_match_score_id_verification: 38.5 expected_details_address: null expected_details_formatted_address: null expected_details_parsed_address: {} extra_fields: bank_account_number: '1234567890' bank_iban: null bank_sort_code: null bank_routing_number: null bank_swift_bic: null bank_branch_name: null bank_branch_address: null document_phone_number: '+5491112345678' additional_names: [] extra_files: - https:///extra_poa.pdf warnings: [] document_ai_documents: - status: Approved node_id: feature_document_ai_1 items: - uuid: c1a2b3c4-d5e6-7f80-9a1b-2c3d4e5f6071 node_id: feature_document_ai_1 document_key: proof_of_funds original_filename: bank_statement.pdf file_size: 184320 file_url: https:///document_ai/proof_of_funds.pdf status: Approved extracted_data: account_holder: John Doe balance: 15230.55 currency: EUR statement_date: '2026-05-31' fields: - key: account_holder name: Account holder instruction: Extract the full name of the account holder. type: text required: true - key: balance name: Closing balance instruction: Extract the closing balance amount. type: number required: true document_metadata: is_tampered: false cross_check_result: null created_at: '2026-06-01T12:34:56Z' warnings: [] questionnaire_responses: - node_id: feature_questionnaire_1 questionnaire_id: 9f7485e0-b00b-4d56-9d3e-7859b68d1213 title: Source of Funds description: Reply to this questionnaire to help us understand the source of funds. languages: - en default_language: en is_active: true is_simple_questionnaire: true questionnaire_group_id: 2b6a9d40-13a8-4b1e-9a6c-3f1d2e4b5a60 version: 1 published_at: '2025-11-02T09:14:55.000000Z' sections: - title: null description: null items: - uuid: 618636d9-7d5c-41ce-b8d0-1ab2a4be20db value: question_1 element_type: DROPDOWN is_required: true title: What is your primary source of funds? description: null placeholder: null choices: - label: Salary value: salary - label: Business Income value: business_income - label: Savings value: savings - label: Investments value: investments - label: Sale of Asset value: sale_of_asset - label: Inheritance/Gift value: inheritance_gift - label: Pension value: pension - label: Crypto Proceeds value: crypto_proceeds - label: Other value: other requires_text_input: true max_files: 1 answer: value: salary required_if: null repeatable_config: null - uuid: 2d16b527-72be-42e0-8e96-b164b818386c value: question_2 element_type: LONG_TEXT is_required: true title: Provide details of the primary source. description: null placeholder: null choices: null max_files: 1 answer: value: Test answer required_if: null repeatable_config: null - uuid: a9239b7c-fbfb-4ea7-b7e4-c835cd4016e0 value: question_3 element_type: DROPDOWN is_required: true title: What is your annual income range (pre-tax)? description: null placeholder: null choices: - label: Less than $25,000 value: <25k - label: $25,000 - $50,000 value: 25k-50k - label: $50,001 - $100,000 value: 50k-100k - label: $100,001 - $250,000 value: 100k-250k - label: More than $250,000 value: '>250k' max_files: 1 answer: value: <25k required_if: null repeatable_config: null - uuid: 93dede62-6d0c-4a7f-934d-42175eb94011 value: question_4 element_type: DROPDOWN is_required: true title: What is your approximate net worth (range)? description: null placeholder: null choices: - label: Less than $50,000 value: <50k - label: $50,000 - $250,000 value: 50k-250k - label: $250,001 - $1,000,000 value: 250k-1m - label: $1,000,001 - $5,000,000 value: 1m-5m - label: More than $5,000,000 value: '>5m' max_files: 1 answer: value: <50k required_if: null repeatable_config: null - uuid: 2af60d6f-6961-4692-9ee7-24b3033610a6 value: question_5 element_type: LONG_TEXT is_required: true title: For your initial deposit/funding, indicate the exact source and amount. description: null placeholder: null choices: null max_files: 1 answer: value: Test answer required_if: null repeatable_config: null - uuid: 0ad9d1aa-736f-46cf-947b-9e1241b53e40 value: question_6 element_type: LONG_TEXT is_required: true title: Breakdown of sources by percentage. description: null placeholder: null choices: null max_files: 1 answer: value: Test answer required_if: null repeatable_config: null - uuid: 1bf8a2a3-14ee-48a8-bb3d-175481aae4aa value: question_7 element_type: SINGLE_CHOICE is_required: true title: Will any funds originate from third parties? If yes, please provide details. description: null placeholder: null choices: - label: 'Yes' value: 'yes' requires_text_input: true - label: 'No' value: 'no' max_files: 1 answer: text: Additional details value: 'yes' required_if: null repeatable_config: null - uuid: e18d4dd3-b7bf-4883-ba18-d6046adbe313 value: question_8 element_type: SINGLE_CHOICE is_required: true title: Do you hold or plan to use virtual assets (e.g., crypto) to fund this account? If yes, please provide details. description: null placeholder: null choices: - label: 'Yes' value: 'yes' requires_text_input: true - label: 'No' value: 'no' max_files: 1 answer: text: Additional details value: 'yes' required_if: null repeatable_config: null - uuid: a90a073d-e098-404c-bbce-5130d8b12a13 value: question_9 element_type: FILE_UPLOAD is_required: true title: Upload a proof of funds document description: You can upload your three (3) most recent bank statements, three (3) most recent payslips, your most recent tax return, proof of company ownership, trading exchange statement, sale of property, or proof of inheritance. placeholder: null choices: null max_files: 3 answer: files: - /media/ocr/ - /media/ocr/ required_if: null repeatable_config: null - uuid: 9503b486-7cb8-4c3b-a97d-4b64926a5a47 value: question_10 element_type: LONG_TEXT is_required: false title: Would you like to add any details to help us expedite our review of the documents you submitted? description: null placeholder: null choices: null max_files: 1 answer: value: Test answer required_if: null repeatable_config: null status: Approved aml_screenings: - node_id: feature_aml_1 status: In Review total_hits: 1 entity_type: person hits: - id: cPtTGRKkyddAcAC4xgsLCm url: https://news.example.org/articles/sample match: false score: 0.73 target: null caption: Javier Ejemplo Modelo datasets: - PEP features: null rca_name: '' last_seen: '2025-06-13T00:00:00' risk_view: crimes: score: 0 weightage: 20 risk_level: Low risk_scores: {} countries: score: 0 weightage: 30 risk_level: Low risk_scores: {} categories: score: 100 weightage: 50 risk_level: High risk_scores: PEP: 100 custom_list: {} first_seen: '2025-01-18T00:00:00' properties: name: - Javier Ejemplo Modelo alias: - Javier Ejemplo Modelo - David Azagra notes: - Spanish orchestra conductor title: null gender: - male height: null topics: null weight: null address: null country: null website: null eyeColor: null keywords: null lastName: - Ejemplo - Modelo position: null religion: null birthDate: - '1974' education: - Tokyo Arts and Space (2012-2012) - Saint Petersburg Conservatory (-2010) - Comillas Pontifical University ethnicity: null firstName: - David hairColor: null weakAlias: null birthPlace: - Madrid modifiedAt: null wikidataId: null citizenship: null nationality: null match_score: 98 risk_score: 73 review_status: Unreviewed score_breakdown: name_score: 95 name_weight: 60 name_weight_normalized: 70.59 name_contribution: 67.06 dob_score: 100 dob_weight: 25 dob_weight_normalized: 29.41 dob_contribution: 29.41 country_score: 0 country_weight: 15 country_weight_normalized: 0 country_contribution: 0 document_number_match_type: NEUTRAL document_number_effect: No document number provided for screening total_score: 98 pep_matches: - aliases: - Javier Ejemplo Modelo - David Azagra education: - Tokyo Arts and Space (2012-2012) - Saint Petersburg Conservatory (-2010) - Comillas Pontifical University list_name: Wikidata publisher: Wikidata source_url: https://news.example.org/articles/sample description: Wikidata is the structured data project of the Wikipedia community, providing fact-based information edited by humans and machines matched_name: Javier Ejemplo Modelo pep_position: '' date_of_birth: '1974' other_sources: [] place_of_birth: Madrid linked_entities: - name: - Antonio Ejemplo active: [] status: [] details: [] relation: [] warning_matches: [] sanction_matches: [] adverse_media_details: sentiment: Moderately Negative entity_type: person sentiment_score: -2 adverse_keywords: fraud: 3 juicio: 1 delitos: 2 imputado: 1 impunidad: 1 corruption: 2 favoritism: 2 privilegio: 1 corrupción: 1 persecution: 2 desconfianza: 1 desprestigio: 1 fraude de ley: 2 manipulación: 1 investigación: 3 prevaricación: 8 trato de favor: 1 irregularidades: 2 crisis de confianza: 1 tráfico de influencias: 8 adverse_media_matches: - country: spain summary: Javier Ejemplo is implicated in legal violations related to favoritism and influence trafficking, leading to a negative portrayal in the article. headline: La Diputación de Villaejemplo consolida la plaza a medida para el ex asesor de Moncloa amigo del "hermanito" de Ejemplo sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - fraud - prevaricación - tráfico de influencias - irregularidades - imputado sentiment_score: -2 publication_date: '2025-06-10T20:46:38' - country: spain summary: Javier Ejemplo is implicated in legal issues regarding favoritism and corruption, leading to a negative portrayal in the article. headline: La Diputación de Villaejemplo consolida la plaza a medida para el ex asesor de Moncloa amigo del "hermanito" de Ejemplo sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - fraud - prevaricación - tráfico de influencias - irregularidades - trato de favor sentiment_score: -2 publication_date: '2025-06-10T20:46:38' - country: spain summary: Javier Ejemplo Modelo is mentioned in connection with Carlos Ficticio's corruption case, indicating his involvement in alleged influence peddling. headline: España, paraíso del aforado sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - prevaricación - tráfico de influencias - corrupción - impunidad - privilegio - desconfianza - manipulación - fraude de ley sentiment_score: -2 publication_date: '2025-06-10T05:05:34' - country: spain summary: Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, which raises questions about his conduct and political ethics. headline: 'Aforamientos: esa figura incómoda' sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - prevaricación - tráfico de influencias - investigación - juicio - fraude de ley - desprestigio - crisis de confianza - delitos sentiment_score: -2 publication_date: '2025-06-08T06:01:00' - country: spain summary: Javier Ejemplo is implicated in a legal investigation regarding irregularities in his hiring, which raises serious concerns about his conduct. headline: La jueza del 'caso Javier Ejemplo' denuncia un «fraude de ley» en el aforamiento de Ficticio (Partido Ejemplo) sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - fraud - irregularities - prevaricación - tráfico de influencias sentiment_score: -2 publication_date: '2025-06-09T10:19:10' - country: spain summary: Javier Ejemplo Modelo is mentioned in connection with legal allegations of corruption, contributing to a negative perception. headline: '''Caso aforamiento'': la letrada mayor de la Asamblea certifica a la juez que Ficticio es diputado desde antes de prometer su cargo en el Pleno' sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - prevaricación - tráfico de influencias sentiment_score: -2 publication_date: '2025-06-09T08:08:30' - country: spain summary: Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, raising concerns about political corruption and influence. headline: 'Aforamientos: esa figura incómoda' sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - prevaricación - tráfico de influencias - investigación sentiment_score: -2 publication_date: '2025-06-08T06:01:00' - country: spain summary: Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, which raises concerns about political misconduct. headline: 'Aforamientos: esa figura incómoda' sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - prevaricación - tráfico de influencias - investigación - delitos sentiment_score: -2 publication_date: '2025-06-08T06:00:59' - country: spain summary: Javier Ejemplo is implicated in a case of favoritism and corruption, which casts a negative light on his character and actions. headline: '''Caso Javier Ejemplo'': las asociaciones judiciales salen en defensa de la juez Luisa Inventada ante las "presiones externas" que sufre' sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - favoritism - corruption - persecution sentiment_score: -2 publication_date: '2025-06-06T10:08:15' - country: spain summary: Javier Ejemplo is implicated in a case of alleged favoritism and corruption, which casts a negative light on his character and actions. headline: '''Caso Javier Ejemplo'': las asociaciones judiciales salen en defensa de la juez Luisa Inventada ante las "presiones externas" que sufre' sentiment: moderately negative thumbnail: https://news.example.org/articles/sample source_url: https://news.example.org/articles/sample author_name: null other_sources: [] adverse_keywords: - favoritism - corruption - persecution sentiment_score: -2 publication_date: '2025-06-06T08:08:15' additional_information: {} score: 80 screened_data: full_name: Javier Ejemplo Modelo nationality: ES date_of_birth: '1974-01-01' document_number: null is_ongoing_monitoring_enabled: true next_ongoing_monitoring_bill_date: '2026-07-24' warnings: - feature: AML risk: POSSIBLE_MATCH_FOUND additional_data: null log_type: warning short_description: Possible match found in AML screening long_description: The Anti-Money Laundering (AML) screening process identified potential matches with watchlists or high-risk databases, requiring further review. node_id: feature_aml_1 ip_analyses: - node_id: feature_ip_1 status: Approved device_brand: Apple device_model: iPhone browser_family: Mobile Safari os_family: iOS platform: mobile device_fingerprint: didit-fp-a1b2c3d4e5f6g7h8 ip_country: Spain ip_country_code: ES ip_state: Barcelona ip_city: Barcelona latitude: 41.4022 longitude: 2.1407 ip_address: 83.50.226.71 isp: null organization: null is_vpn_or_tor: false is_data_center: false time_zone: Europe/Madrid time_zone_offset: '+0100' ip: location: latitude: 40.2206327 longitude: 1.5770097 distance_from_id_document: 23.4 distance_from_poa_document: 12.3 id_document: location: latitude: 41.2706327 longitude: 1.9770097 distance_from_ip: 23.4 distance_from_poa_document: 18.7 poa_document: location: latitude: 41.2706327 longitude: 1.9770097 distance_from_ip: 12.3 distance_from_id_document: 18.7 warnings: [] matches: - session_id: 99999999-8888-7777-6666-555555555555 session_number: 41205 vendor_data: 22222222-2222-2222-2222-222222222222 verification_date: '2024-07-20T10:15:30Z' match_type: ip_address match_source: ip_address matched_value: 83.50.226.71 status: Approved is_blocklisted: false api_service: null source: session device_info: device_brand: Apple device_model: iPhone browser_family: Mobile Safari os_family: iOS platform: mobile device_fingerprint: didit-fp-f9e8d7c6b5a40312 location_info: ip_address: 83.50.226.71 ip_country: Spain ip_country_code: ES ip_state: Barcelona ip_city: Barcelona is_vpn_or_tor: false is_data_center: false confidence: 0 match_mode: co_occurrence - session_id: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee session_number: 42830 vendor_data: 33333333-3333-3333-3333-333333333333 verification_date: '2024-06-30T18:22:05Z' match_type: device_fingerprint match_source: recovered_high matched_value: f47ac10b-58cc-4372-a567-0e02b2c3d479 status: Declined is_blocklisted: false api_service: null source: session device_info: device_brand: Samsung device_model: SM-G991B browser_family: Chrome Mobile os_family: Android platform: mobile device_fingerprint: null location_info: ip_address: 83.50.231.18 ip_country: Spain ip_country_code: ES ip_state: Madrid ip_city: Madrid is_vpn_or_tor: false is_data_center: false confidence: 1 match_mode: deterministic recovery_similarity: 0.9874 tls_ja4_corroborated: true recovery_gate_reason: hardware_root_match database_validations: - node_id: feature_db_validation_1 issuing_state: BRA validation_type: one_by_one screened_data: last_name: De Lima first_name: Fernando tax_number: 01234567890 date_of_birth: '1980-01-01' document_type: ID expiration_date: '2030-01-01' validations: - service_id: bra_cpf service_name: Brazil - CPF status check outcome_code: MATCH validation: full_name: full_match date_of_birth: full_match identification_number: full_match source_data: identification_number: 01234567890 first_name: FERNANDO last_name: DE LIMA date_of_birth: '1980-01-01' gender: M nationality: BRA match_type: full_match status: Approved warnings: [] reviews: - user: compliance@example.com new_status: Declined comment: Possible match found in AML screening created_at: '2024-07-18T13:29:00.366811Z' created_at: '2024-07-24T08:54:25.443172Z' expires_at: '2025-07-24T08:54:25.443172Z' BusinessExample: summary: Business (KYB) session example description: 'A `session_kind = "business"` decision: KYB sessions replace the KYC feature arrays with `registry_checks`, `document_verifications` and `key_people_checks`, while sharing `aml_screenings`, `phone_verifications`, `email_verifications`, `questionnaire_responses`, `ip_analyses`, `reviews` and the session envelope.' value: session_id: 66666666-7777-8888-9999-000000000000 session_kind: business session_number: 31415 session_url: https://verify.didit.me/session/business123 status: In Review environment: live workflow_id: abababab-cdcd-efef-0101-232323232323 features: - KYB_REGISTRY - KYB_DOCUMENTS - KYB_KEY_PEOPLE vendor_data: merchant-001234 metadata: null callback: https://example.com/verification/callback registry_checks: - status: Approved node_id: feature_kyb_registry_1 data_resolved: true company: uuid: dddd4444-eeee-5555-ffff-666677778888 node_id: feature_kyb_registry_1 status: Approved registry_status: active data_resolved: true company_name: ACME HOLDINGS LTD registration_number: '12345678' country_code: GB region: null company_type: Private Limited Company incorporation_date: '2015-03-12' registered_address: 1 Example Street, London, EC1A 1AA tax_number: null risk_level: null verification_status: null is_from_registry: true fetch_status: resolved alternative_names: [] nature_of_business: 62012 - Business and domestic software development registered_capital: 100 GBP registered_capital_amount: '100.00' registered_capital_currency: GBP website: null email: null phone: null legal_entity_identifier: null location_of_registration: England and Wales financial_summary: null officers: - uuid: aaaa1111-bbbb-2222-cccc-333344445555 name: Jane Smith designation: Director role: director nationality: British is_active: true kyc_status: Approved kyc_session_url: https://verify.didit.me/session/abc123def456 beneficial_owners: - uuid: bbbb2222-cccc-3333-dddd-444455556666 name: John Doe first_name: John last_name: Doe entity_type: person roles: - ubo - shareholder ownership_min_shares: '50' ownership_max_shares: '75' is_active: true kyc_status: Pending kyc_session_url: https://verify.didit.me/session/def456ghi789 effective_ownership_percent: 75 addresses: - type: registered address: 1 Example Street, London, EC1A 1AA country: GB industries: - code: '62012' description: Business and domestic software development accounts: null registry_data: addresses_detail: - type: registered address: 1 Example Street, London, EC1A 1AA country: GB industries: - code: '62012' description: Business and domestic software development user_provided_data: company_name: ACME HOLDINGS registration_number: '12345678' confirmed_by_user_at: '2026-06-10T12:01:30.000000Z' last_console_edit_at: null is_editable: false ownership_structure: nodes: - id: company name: ACME HOLDINGS LTD type: company - id: ubo-1 name: John Doe type: person ownership_percent: 75 warnings: [] aml_screenings: null document_verifications: - status: In Review node_id: feature_kyb_documents_1 items: - uuid: eeee5555-ffff-6666-0000-777788889999 document_type: LEGAL_PRESENCE document_subtype: CERTIFICATE_OF_INCORPORATION document_group: LEGAL_PRESENCE file_url: https:///kyb/certificate-of-incorporation.pdf original_filename: certificate_of_incorporation.pdf file_size: 482133 status: Approved created_at: '2026-06-10T12:03:11.000000Z' cross_check_result: critical: company_name: document: ACME HOLDINGS LTD registry: ACME HOLDINGS LTD score: 1 match: true registration_number: document: '12345678' registry: '12345678' match: true non_critical: {} people: {} document_metadata: file_size: 482133 content_type: application/pdf creation_date: '2015-03-12T09:00:00' modified_date: '2015-03-12T09:00:00' creator: null producer: null software: null encryption: null is_signed: true is_tampered: false signature_info: null exif_original_date: null exif_digitized_date: null processed_by_known_editor: false has_different_creation_mod_date: false overlay_manipulation: null description: null is_requested: false ocr_data: company_name: ACME HOLDINGS LTD registration_number: '12345678' incorporation_date: '2015-03-12' is_console_upload: false is_confirmed: true - uuid: ffff6666-0000-7777-1111-888899990000 document_type: OWNERSHIP_STRUCTURE document_subtype: null document_group: OWNERSHIP_STRUCTURE file_url: null original_filename: null file_size: null status: Not Finished created_at: '2026-06-10T15:40:02.000000Z' cross_check_result: null document_metadata: null description: Please upload an up-to-date shareholder registry is_requested: true ocr_data: null is_console_upload: false is_confirmed: true groups: LEGAL_PRESENCE: total: 1 approved: 1 pending: 0 declined: 0 in_review: 0 other: 0 missing: 0 OWNERSHIP_STRUCTURE: total: 1 approved: 0 pending: 0 declined: 0 in_review: 0 other: 0 missing: 1 required_groups: - LEGAL_PRESENCE - OWNERSHIP_STRUCTURE warnings: [] key_people_checks: - status: In Review node_id: feature_kyb_key_people_1 registry: officers: - uuid: aaaa1111-bbbb-2222-cccc-333344445555 name: Jane Smith designation: Director role: director nationality: British appointment_date: '2015-03-12' termination_date: null is_active: true address: 1 Example Street, London, EC1A 1AA aml_status: Approved kyc_status: Approved kyc_session_url: https://verify.didit.me/session/abc123def456 kyc_session_id: 77777777-8888-9999-aaaa-bbbbbbbbbbbb verification_workflow_type: kyc verification_workflow_id: 12121212-3434-5656-7878-909090909090 verification_workflow_label: Key People KYC verification_workflow_features: - feature: ID_VERIFICATION status: Approved - feature: LIVENESS status: Approved - feature: AML status: Approved didit_internal_id: 99999999-0000-1111-2222-333333333333 kyc_document_type: P kyc_nationality: GBR kyc_liveness_passed: true kyc_verified_at: '2026-06-10T14:22:31.123456Z' kyc_aml_categories: sanctions: clear pep: clear adverse_media: clear warnings: clear kyc_notification_sent_at: '2026-06-09T09:00:00.000000Z' beneficial_owners: - uuid: bbbb2222-cccc-3333-dddd-444455556666 name: John Doe first_name: John last_name: Doe date_of_birth: '1980-05-04' country_of_birth: null email: null company_name: null registration_number: null entity_type: person nationality: British designation: null roles: - ubo - shareholder ownership_min_shares: '50' ownership_max_shares: '75' is_active: true aml_status: null kyc_status: In Progress kyc_session_url: https://verify.didit.me/session/def456ghi789 kyc_session_id: 88888888-9999-aaaa-bbbb-cccccccccccc verification_workflow_type: kyc verification_workflow_id: 12121212-3434-5656-7878-909090909090 verification_workflow_label: Key People KYC verification_workflow_features: - feature: ID_VERIFICATION status: Not Finished - feature: LIVENESS status: Not Finished - feature: AML status: Not Finished didit_internal_id: null kyc_document_type: null kyc_nationality: null kyc_liveness_passed: null kyc_verified_at: null kyc_aml_categories: null kyc_notification_sent_at: null child_beneficial_owners: [] effective_ownership_percent: 75 submitted: parties: - uuid: cccc3333-dddd-4444-eeee-555566667777 entity_type: person source: USER name: John Doe first_name: John last_name: Doe company_name: null registration_number: null email: john.doe@example.com nationality: GBR phone_number: '+447700900123' date_of_birth: '1980-05-04' position: Chief Executive Officer custom_fields: {} is_active: true is_skipped: false requires_verification: true roles: - role: ubo ownership_percent: 75 voting_percent: 75 - role: director ownership_percent: null voting_percent: null kyc_session_id: 88888888-9999-aaaa-bbbb-cccccccccccc kyc_session_status: In Progress kyc_session_url: https://verify.didit.me/session/def456ghi789 kyb_sub_session_id: null kyb_sub_session_status: null kyb_sub_session_url: null verification_workflow_type: kyc verification_workflow_id: 12121212-3434-5656-7878-909090909090 verification_workflow_label: Key People KYC verification_workflow_features: - feature: ID_VERIFICATION status: Not Finished - feature: LIVENESS status: Not Finished - feature: AML status: Not Finished didit_internal_id: null ubo_kyc_summary: total: 1 approved: 0 flagged: 0 pending: 1 warnings: [] phone_verifications: null email_verifications: null questionnaire_responses: null ip_analyses: null reviews: [] contact_details: null expected_details: company_name: Tesco PLC registry_country: GB registration_number: 00445790 created_at: '2026-06-10T11:58:04.000000Z' expires_at: '2026-06-24T11:58:04.000000Z' schema: type: object properties: session_id: type: string format: uuid description: The unique identifier of the session for which to retrieve verification results. session_kind: type: string enum: - user - business description: Discriminator indicating whether this is a User Verification (KYC) or Business Verification (KYB) session. When `user`, the KYC feature arrays (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `database_validations`, ...) apply and the business arrays are absent. When `business`, the payload instead carries `registry_checks`, `document_verifications`, `key_people_checks` plus the shared arrays (`aml_screenings`, `phone_verifications`, `email_verifications`, `ip_analyses`, `questionnaire_responses`). **Omitted when `include=events` is passed** — the events shape only exists for user sessions, so the discriminator is dropped from that variant. session_number: type: integer description: The number of the session. nullable: true session_url: type: string format: uri description: The URL of the session. nullable: true status: type: string enum: - Not Started - In Progress - Awaiting User - In Review - Approved - Declined - Resubmitted - Expired - Kyc Expired - Abandoned description: Overall lifecycle status of the session — the rolled-up workflow result. Terminal values are `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired`, and `Abandoned`; `Not Started`, `In Progress`, `Awaiting User`, and `Resubmitted` indicate the session is still moving through the workflow. workflow_id: type: string format: uuid description: Stable identifier of the workflow group that produced this session. Workflows are versioned — this value identifies the workflow itself, not the specific version. nullable: true features: type: array items: type: string description: The feature of the session. description: 'List of verification features configured for this session, as display names: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH` (Business Verification sessions use the KYB feature set: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). With `include=events` each entry becomes an object `{feature, node_id}` instead of a plain string, and the email feature is renamed: it appears as `EMAIL` in events mode instead of the `EMAIL_VERIFICATION` used here.' vendor_data: type: string description: The vendor data of the session. nullable: true metadata: type: object description: The metadata of the session. nullable: true expected_details: type: object description: Expected details supplied at session creation — used for cross-validation against extracted data (KYC) or to pre-fill the company registry search (KYB). Echoes back exactly the keys that were provided; `null` when none were supplied. KYC sessions carry the person fields; Business (KYB) sessions carry `company_name`, `registry_country` and `registration_number`. properties: first_name: type: string description: User's first name. For example, `John`. last_name: type: string description: User's last name. For example, `Doe`. date_of_birth: type: string format: date description: 'User''s date of birth with format: YYYY-MM-DD. For example, `1990-05-15`.' gender: type: string nullable: true enum: - M - F default: null description: User's gender. Must be either 'M', 'F', or null. nationality: type: string description: ISO 3166-1 alpha-3 country code representing the applicant's country of origin. For example, `USA`. country: type: string description: ISO 3166-1 alpha-3 country code representing the country of the Proof of Address document, or the country of the applicant's ID document, which may differ from nationality. For example, `GBR`. address: type: string description: The address in a human readable format, including as much information as possible. For example, `123 Main St, San Francisco, CA 94105, USA`. identification_number: type: string description: The user's document number, personal number, or tax number. For example, `123456789`. ip_address: type: string format: ipv4 description: Expected IP address for the session. If the actual IP address differs from this value, a warning will be logged. For example, `192.168.1.100`. expected_document_types: type: array description: 'Document types the ID verification step was restricted to at session creation. Empty/unset means no restriction. Codes: `P` (passport), `ID` (national ID), `DL` (driver''s license), `RP` (residence permit), `HIC` (health insurance card), `TC` (tax card), `SSC` (social security card).' items: type: string enum: - P - ID - DL - RP - HIC - TC - SSC id_country: type: string nullable: true description: Expected ID-document issuing country (ISO 3166-1 alpha-3), when restricted at creation time. example: ESP poa_country: type: string nullable: true description: Expected Proof of Address document country (ISO 3166-1 alpha-3), when restricted at creation time. example: ESP company_name: type: string description: Expected legal name of the business. Business (KYB) sessions only. registry_country: type: string description: Expected registry country as `XX` or `XX-YY` (ISO 3166-1 alpha-2, optionally with an ISO 3166-2 subdivision for state-level registries, e.g. `US-CA`). Business (KYB) sessions only. registration_number: type: string description: Expected company registration number. Business (KYB) sessions only. nullable: true contact_details: type: object description: Contact details supplied when the session was created (used for notification emails, prefilled phone/email verification, and communication language). `null` when neither an email nor a phone number was provided. properties: email: type: string description: Email address of the user (e.g., "john.doe@example.com") that will be used during the Email Verification step. If not provided, the user must provide it during the verification flow. email_lang: type: string description: Language code (ISO 639-1) for email notifications. Controls the language of all email communications (e.g., "en", "es", "fr"). send_notification_emails: type: boolean default: false description: If true and an email is provided, Didit sends the initial "Verify your identity" email asynchronously when the User Verification (KYC) or Business Verification (KYB) session is created. Didit also sends verification status notifications for sessions requiring manual review to the provided email address. phone: type: string nullable: true description: 'Phone number of the user in E.164 format if available (e.g., +14155552671). `null` when only an email was supplied at session creation. Note: This field returns the original phone number provided during session creation. If the number was invalid, it may not be in E.164 format.' nullable: true callback: type: string format: uri description: The callback URL of the session. nullable: true id_verifications: type: array nullable: true description: '**Array of ID verification (OCR) reports** produced by ID-document steps in the workflow graph. Always a JSON array — read `id_verifications[0]` and iterate if your workflow can run more than one ID check (for example a primary check plus a step-up). `null` until at least one ID step has produced data. Each item is the full report, including `node_id`, feature-level `status`, extracted document fields, image URLs, quality scores, MRZ, address parsing, cross-session matches, and `warnings[]`.' items: type: object description: One ID verification report — the full report for a single OCR pass. properties: node_id: type: string description: Workflow graph node id of the OCR step that produced this report. status: type: string enum: - Not Finished - Approved - Declined - In Review - Expired description: Feature-level status of this ID verification step. Independent of the top-level session `status` — a session can reach its overall decision while an individual feature stays `In Review`. document_type: type: string description: Type of identity document document_subtype: type: string nullable: true description: 'Accepted document subtype code from the workflow document settings, including the document region when applicable. Examples: `ID_CARD_GENERIC`, `QUEENSLAND_DRIVER_LICENSE_GENERIC`.' document_number: type: string description: Document identification number personal_number: type: string description: Personal identification number portrait_image: type: string format: uri description: URL of the portrait image front_image: type: string format: uri description: URL of the front document image front_video: type: string format: uri description: URL of the front document video back_image: type: string format: uri description: URL of the back document image back_video: type: string format: uri description: URL of the back document video full_front_image: type: string format: uri description: URL of the full front document image full_back_image: type: string format: uri description: URL of the full back document image front_image_camera_front: type: string format: uri description: URL of the front document image captured from the front-facing camera back_image_camera_front: type: string format: uri description: URL of the back document image captured from the front-facing camera date_of_birth: type: string format: date description: Date of birth from document age: type: integer description: Calculated age from date of birth expiration_date: type: string format: date description: Document expiration date date_of_issue: type: string format: date description: Document issue date issuing_state: type: string description: ISO code of issuing state issuing_state_name: type: string description: Full name of issuing state first_name: type: string description: First name from document last_name: type: string description: Last name from document full_name: type: string description: Full name from document gender: type: string description: Gender from document address: type: string description: Raw address from document formatted_address: type: string description: Formatted full address place_of_birth: type: string description: Place of birth from document marital_status: type: string description: Marital status from document nationality: type: string description: ISO nationality code extra_fields: type: object description: Additional document fields. Includes document-specific attributes (e.g. `dl_categories`, `blood_group`, `sponsor`, `employer`, `dl_class_code_b_from`, `dl_class_code_b_to`). Driver license class validity dates are returned as `dl_class_code__from` and `dl_class_code__to`, and per-class restriction/information codes (e.g. column 12 of UK licences) as `dl_class_code__notes`. When the document carries names, address, or place of birth in multiple scripts, this object also includes alternate-script versions of those fields. The workflow setting `preferred_characters` (`latin` or `non_latin`) controls which script populates the top-level fields (`first_name`, `last_name`, `full_name`, `address`, `place_of_birth`); the opposite script lands here as `first_name_non_latin` / `last_name_non_latin` / `full_name_non_latin` / `middle_name_non_latin` / `address_non_latin` / `place_of_birth_non_latin` (when `preferred_characters` is `latin`) or with a `_latin` suffix (when `preferred_characters` is `non_latin`). Keys appear only when the OCR actually extracts a real alternate-script value — a field whose alternate value is in the same script as the preferred set (for example, a Cyrillic-labelled field whose OCR value came back in Latin homoglyphs) is skipped. When `preferred_characters` is `latin` but the document only carries non-Latin text, Didit transliterates the extracted values and exposes `first_name_latin` / `last_name_latin` / etc. as a fallback. additionalProperties: true properties: dl_categories: type: array items: type: string blood_group: type: string nullable: true first_name_non_latin: type: string description: First name in the non-Latin script when `preferred_characters=latin` and a non-Latin version is present on the document (e.g. `Айна` for a Kyrgyz ID). last_name_non_latin: type: string description: Surname in the non-Latin script when `preferred_characters=latin` and a non-Latin version is present on the document. middle_name_non_latin: type: string description: Middle name / patronymic in the non-Latin script when `preferred_characters=latin` and a non-Latin version is present on the document. full_name_non_latin: type: string description: Composed full name in the non-Latin script. Reconstructed from the individual components when both first and last names are available. address_non_latin: type: string description: Address in the non-Latin script when `preferred_characters=latin` and a non-Latin version is present on the document. place_of_birth_non_latin: type: string description: Place of birth in the non-Latin script when `preferred_characters=latin` and a non-Latin version is present on the document. first_name_latin: type: string description: First name in Latin script. Populated when `preferred_characters=non_latin` and a Latin version is present on the document, or — as a transliteration fallback — when `preferred_characters=latin` but the document only carries non-Latin text. last_name_latin: type: string description: Surname in Latin script. Same rules as `first_name_latin`. middle_name_latin: type: string description: Middle name / patronymic in Latin script. Same rules as `first_name_latin`. full_name_latin: type: string description: Composed full name in Latin script. Always reconstructed from the individual components when both first and last names are available. address_latin: type: string description: Address in Latin script. Same rules as `first_name_latin`. place_of_birth_latin: type: string description: Place of birth in Latin script. Same rules as `first_name_latin`. mrz: type: object nullable: true description: Parsed Machine-Readable Zone (MRZ) fields extracted from the document. `null` if no MRZ was detected. properties: surname: type: string example: MARTINEZ_families` / `very_high_similarity_plus__families`. Present only when `match_source` is `recovered_high`.' database_validations: type: array nullable: true description: '**Array of Database Validation reports** — always a JSON array, never a singular `database_validation` object. `null` until at least one DB validation step has produced data. Each item is the full report, including `node_id`, feature-level `status`, `screened_data`, the per-service `validations[]` (each with its registry `source_data`), and `warnings[]`. The `screened_data` and `source_data` fields vary by country: **ARG (Argentina)**: screened_data: {document_number, selfie, gender, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, date_of_death, tax_id, tax_id_type, face_match_score, sit_1_since, banks, last_position, highest_position, rejected_checks}. Uses RENAPER biometric face-match validation. Gender is auto-inferred from face analysis or given name when not present in the document (e.g., driver licenses) **BOL (Bolivia)**: screened_data: {document_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, gender} **BRA (Brazil)**: screened_data: {tax_number, first_name, last_name, date_of_birth}. source_data always includes {identification_number, first_name, last_name, date_of_birth, lgpd_minor, minor_under_18, minor_under_16} for successful CPF matches. Successful adult lookups set those flags to false. The Receita Federal Consulta CPF service may return HTTP 422 (minor under 18) or 451 (under 16) with LGPD-withheld data; in those cases source_data sets the minor flags to true as appropriate, includes the upstream HTTP status, and field-level validation is no_match. See the Brazil section of the Database Validation Outcome Codes reference for the full code list. **CHL (Chile)**: screened_data: {personal_number, first_name, last_name, date_of_birth}. source_data: {identification_number, first_name, last_name, date_of_birth, gender} **COL (Colombia)**: screened_data: {document_number, document_type, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, document_type} **CRI (Costa Rica)**: screened_data: {personal_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name} **DOM (Dominican Republic)**: screened_data: {personal_number}. source_data: {identification_number} (returns valid/invalid only) **ECU (Ecuador)**: screened_data: {personal_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, street, formatted_address, gender, nationality, education, marital_status, spouse, mother_name, father_name, profession} **ESP (Spain)**: screened_data: {personal_number, document_type, expiration_date, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, document_type, expiration_date} **GTM (Guatemala)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name} **HND (Honduras)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name} **MEX (Mexico)**: screened_data: {personal_number (CURP), first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, gender, nationality, curp_status, state_of_birth, doc_probatorio, registration_year, registration_state, registration_municipality, num_acta, crip, issuing_state_code, foreign_registry_number, folio_carta, folio_certificado}. Uses the RENAPO civil registry. A separate INE validity-check service is also available for MEX as an additional one-by-one validation. **PAN (Panama)**: screened_data: {personal_number, selfie}. source_data: {identification_number}. Uses SIB biometric validation **PER (Peru)**: screened_data: {personal_number (DNI), first_name, last_name}. source_data: {identification_number, first_name, last_name, paternal_name, maternal_name, verification_number, verification_letter} **PRY (Paraguay)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name} **SLV (El Salvador)**: screened_data: {document_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name} **URY (Uruguay)**: screened_data: {personal_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name} **VEN (Venezuela)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, gender, date_of_birth, document_type}' items: type: object properties: node_id: type: string description: Unique identifier for this database validation step in the workflow graph. issuing_state: type: string description: ISO 3166-1 alpha-3 code of the country whose government/registry sources were queried (e.g. `BRA`, `MEX`, `ESP`, `NGA`, `IDN`). Database Validation covers 60+ countries across the Americas, Europe, Africa, the Middle East and Asia-Pacific, plus global multi-country sources — coverage expands regularly, so treat the value as an open set rather than a fixed enum. validation_type: type: string enum: - one_by_one - two_by_two - not_enabled description: 'How the result was corroborated: `one_by_one` (single-service outcome), `two_by_two` (two or more distinct services independently full-matched the identification number), or `not_enabled` (persisted when no service produced a usable match). The value is never `null`. Dedicated biometric 2x2 validation modes are currently available for `ECU` and `PER`.' screened_data: type: object description: The input data used for validation. Fields vary by country — see the Database Validation docs (`/core-technology/database-validation/overview`) for country-specific formats. properties: last_name: type: string first_name: type: string tax_number: type: string description: 'Brazil: CPF (11 digits)' personal_number: type: string description: 'Chile: RUT, DOM: Cédula (11 digits), ECU: Cédula (10 digits), ESP: DNI/NIE, MEX: CURP (18 chars), PER: DNI (8 digits), URY: CI' document_number: type: string description: 'ARG: DNI, BOL: CI, COL: Cédula, GTM: DPI, HND: DNI, PAN: Cédula, PRY: CI, SLV: DUI, VEN: Cédula' date_of_birth: type: string format: date document_type: type: string description: 'COL: CC/CE/TI/NIT, ESP: ID/PASSPORT' expiration_date: type: string format: date description: Required for ESP validations: type: array description: One entry per registry service that returned a validation payload. Each entry identifies the service (`service_id`, `service_name`) and carries the per-field `validation` comparison, the service `outcome_code` / `outcome_detail` when reported, and the normalised registry record in `source_data`. items: type: object properties: service_id: type: string description: Identifier of the registry service that produced this validation result. example: bra_cpf service_name: type: string description: Human-readable name of the registry service. example: Brazil - CPF status check validation: type: object description: The results of the field validations. properties: full_name: type: string description: Match result for full name (e.g., 'full_match', 'partial_match', 'no_match'). date_of_birth: type: string description: Match result for date of birth. identification_number: type: string description: Match result for identification number. outcome_code: type: string nullable: true description: Machine-readable outcome of the registry lookup (e.g. `MATCH`, `NO_MATCH`, `PARTIAL_MATCH`, `INCONCLUSIVE`, source-specific codes). Present when the service reports one. outcome_detail: type: string nullable: true description: Human-readable explanation of `outcome_code`, when provided by the service. source_data: type: object description: 'The data returned from the government database. Common fields: identification_number, first_name, last_name, full_name, date_of_birth, gender. Additional fields by country: BRA always includes lgpd_minor, minor_under_18, and minor_under_16 on successful CPF matches; it also includes the upstream HTTP status when CPF data is withheld under LGPD (HTTP 422/451). ECU adds street, formatted_address, nationality, education, marital_status, spouse, mother_name, father_name, profession. PER adds paternal_name, maternal_name, verification_number, verification_letter. ESP adds document_type, expiration_date. VEN/COL add document_type.' additionalProperties: true errors: type: array description: Errors returned by registry services while validating, each tagged with the `service_id` that produced it. **This key is omitted entirely when there are no errors.** items: type: object description: The upstream service's error object spread as-is — its keys vary by service (commonly a message/code and any provider-specific details) — plus `service_id` identifying the service that errored. properties: service_id: type: string nullable: true description: Identifier of the registry service that errored. additionalProperties: true match_type: type: string enum: - no_match - partial_match - full_match nullable: true description: The aggregate match outcome across the queried services. `null` until the validation has been evaluated. status: type: string description: Feature-level status of this database validation. Independent of the top-level session `status` — a session can reach its overall decision while an individual feature stays `In Review`. enum: - Not Finished - Approved - Declined - In Review - Resub Requested warnings: type: array items: type: object properties: feature: type: string enum: - ID_VERIFICATION - NFC - LIVENESS - FACEMATCH - PROOF_OF_ADDRESS - PHONE - EMAIL - AML - LOCATION - DATABASE_VALIDATION - QUESTIONNAIRE - DOCUMENT_AI - KYB_REGISTRY - KYB_DOCUMENTS - KYB_KEY_PEOPLE description: The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload. risk: type: string additional_data: type: object nullable: true log_type: type: string short_description: type: string long_description: type: string node_id: type: string description: The workflow graph node ID that generated this warning description: Warnings related to the database validation. reviews: type: array items: type: object properties: user: type: string description: Who performed the review. Usually the console reviewer's identifier (their email), but the value is `"API Client"` for status updates made with an API key and `"Unknown"` when no actor could be resolved — so do not parse this field as an email address. new_status: type: string comment: type: string created_at: type: string format: date-time created_at: type: string format: date-time description: Timestamp at which the session was created (ISO 8601, UTC). expires_at: type: string format: date-time nullable: true description: Timestamp at which this session is scheduled to expire. Set on User Verification (KYC) sessions when an expiration was configured at creation time (or once `Approved` status triggers KYC expiry computation). `null` for sessions without a configured expiration, and for kinds that do not use expiry (e.g. Business Verification (KYB) sessions that never received an `expires_at`). registry_checks: type: array nullable: true description: Company registry checks. Present only when `session_kind = business`. Each item wraps the full company-registry payload. items: type: object description: One company registry check — the full company-registry payload enriched with ownership structure and warnings. Present only when `session_kind = business`. properties: status: type: string description: Feature lifecycle status. node_id: type: string nullable: true data_resolved: type: boolean company: type: object description: Full registry payload for the company (registry record merged with any user-provided or console-edited data). properties: uuid: type: string format: uuid node_id: type: string nullable: true status: type: string registry_status: type: string nullable: true data_resolved: type: boolean company_name: type: string registration_number: type: string nullable: true country_code: type: string description: Country of incorporation (ISO 3166-1 alpha-2, e.g. `GB`, `DE`, `US`). region: type: string nullable: true description: ISO 3166-2 subdivision code when applicable (e.g. `CA`, `NY` for US states). company_type: type: string nullable: true incorporation_date: type: string format: date nullable: true registered_address: type: string nullable: true tax_number: type: string nullable: true risk_level: type: string enum: - LOW - MEDIUM - HIGH nullable: true verification_status: type: string nullable: true is_from_registry: type: boolean fetch_status: type: string nullable: true alternative_names: type: array items: type: string nature_of_business: type: string nullable: true registered_capital: type: string nullable: true registered_capital_amount: type: string format: decimal nullable: true description: Registered/share capital amount as a decimal string (e.g. `"100.00"`), parsed from the registry filing. `null` when not available. registered_capital_currency: type: string nullable: true description: ISO 4217 currency code of `registered_capital_amount` (e.g. `"GBP"`). `null` when not available. website: type: string nullable: true email: type: string format: email nullable: true phone: type: string nullable: true legal_entity_identifier: type: string nullable: true location_of_registration: type: string nullable: true vat_number: type: string nullable: true description: EU VAT number, when collected during the hosted registry step or edited afterwards. vat_validation_status: type: string enum: - valid - invalid - could_not_validate - not_applicable description: Result of the EU VIES check run at registry submit. `not_applicable` when no VAT number was provided or the company is outside the EU VAT area (EU-27 plus Northern Ireland). vat_validated_name: type: string nullable: true description: Trader name registered with VIES, when the member state discloses it. Only set when the VAT number is `valid`. vat_validated_address: type: string nullable: true description: Trader address registered with VIES, when the member state discloses it. Only set when the VAT number is `valid`. vat_checked_at: type: string format: date-time nullable: true description: Timestamp of the VIES check. `null` when no check ran. financial_summary: type: object nullable: true officers: type: array items: type: object properties: uuid: type: string format: uuid name: type: string designation: type: string nullable: true role: type: string nullable: true nationality: type: string nullable: true is_active: type: boolean kyc_status: type: string enum: - Approved - Declined - Pending nullable: true kyc_session_url: type: string format: uri nullable: true beneficial_owners: type: array items: type: object properties: uuid: type: string format: uuid name: type: string first_name: type: string nullable: true last_name: type: string nullable: true entity_type: type: string enum: - person - company roles: type: array items: type: string ownership_min_shares: type: string nullable: true description: Lower bound of the ownership percentage as reported by the registry. Free-form string (e.g. `"25.00"`, `"50"`); use `effective_ownership_percent` for a parsed numeric value. ownership_max_shares: type: string nullable: true description: Upper bound of the ownership percentage as reported by the registry. Free-form string; use `effective_ownership_percent` for a parsed numeric value. is_active: type: boolean kyc_status: type: string enum: - Approved - Declined - Pending nullable: true kyc_session_url: type: string format: uri nullable: true effective_ownership_percent: type: number nullable: true addresses: type: array nullable: true items: type: object industries: type: array nullable: true items: type: object accounts: type: array nullable: true items: type: object registry_data: type: object description: Raw payload returned by the registry provider. user_provided_data: type: object description: Data confirmed or edited by the end user. confirmed_by_user_at: type: string format: date-time nullable: true last_console_edit_at: type: string format: date-time nullable: true is_editable: type: boolean ownership_structure: type: object description: Raw ownership-chain JSON as returned by the registry provider. warnings: type: array items: type: object key_people_checks: type: array nullable: true description: Aggregate key-people checks. Present only when `session_kind = business`. Each item uses the two-bucket shape (`registry`, `submitted`, `ubo_kyc_summary`). items: type: object description: Aggregate check over the company's officers + UBOs. Uses the `registry` / `submitted` shape. Present only when session_kind = business. properties: status: type: string node_id: type: string nullable: true registry: type: object description: Parties discovered via the registry check. properties: officers: type: array description: Officers discovered via the registry check, each enriched with the status of any child KYC session and AML screening spawned for them. items: type: object properties: uuid: type: string format: uuid name: type: string description: Officer's full name as recorded in the registry. designation: type: string nullable: true description: Free-text designation from the registry (e.g. `Director`, `Company Secretary`). role: type: string enum: - director - non_executive_director - secretary - chairman - ubo - shareholder - representative - founder - legal_advisor - authorized_signatory - trustee - beneficiary - settlor - protector - company_officer - investor - other description: Normalized officer role. nationality: type: string nullable: true appointment_date: type: string format: date nullable: true description: Date the officer was appointed, when the registry provides it. termination_date: type: string format: date nullable: true description: Date the appointment ended. `null` for active officers. is_active: type: boolean address: type: string nullable: true description: Officer's address as recorded in the registry. aml_status: type: string enum: - Not Finished - Approved - Declined - In Review - Resub Requested nullable: true description: Status of the AML screening run for this officer. `null` when no AML screening was run. kyc_status: type: string enum: - Not Started - In Progress - Approved - Declined - In Review - Expired - Abandoned - Kyc Expired - Resubmitted - Awaiting User nullable: true description: Raw lifecycle status of the child KYC session spawned for this officer. This is the full session status enum (not a reduced Approved/Declined/Pending set). `null` when no child KYC session exists. kyc_session_url: type: string format: uri nullable: true description: Shareable URL of the child KYC session. `null` when no child session exists. kyc_session_id: type: string format: uuid nullable: true description: Session id of the child KYC session. Pass it to this same decision endpoint to fetch the person's full KYC report. `null` when no child session exists. verification_workflow_type: type: string nullable: true description: Base workflow type of the child session's workflow (e.g. `kyc`). `null` for graph-based workflows or when no child session exists. verification_workflow_id: type: string format: uuid nullable: true description: Workflow id used by the child session. `null` when no child session exists. verification_workflow_label: type: string nullable: true description: Human-readable label of the child session's workflow. `null` when unset. verification_workflow_features: type: array nullable: true description: 'Per-feature progress of the child verification session, e.g. `[{"feature": "ID_VERIFICATION", "status": "Approved"}]`. `null` when the child session has no resolvable feature list.' items: type: object properties: feature: type: string description: Feature display name (e.g. `ID_VERIFICATION`, `LIVENESS`, `AML`). status: type: string enum: - Not Finished - Approved - Declined - In Review - Resub Requested description: Feature-level status inside the child session. didit_internal_id: type: string nullable: true description: Stable internal identifier of the verified individual behind the child session — useful for cross-session linking. `null` when no child session exists or the user has not been resolved yet. kyc_document_type: type: string nullable: true description: Document type presented in the child KYC session (e.g. `P`, `ID`, `DL`). `null` until the child session has an ID verification result. kyc_nationality: type: string nullable: true description: Nationality extracted from the document in the child KYC session. `null` until available. kyc_liveness_passed: type: boolean nullable: true description: Whether the child KYC session's liveness check passed. `null` when no liveness check has run. kyc_verified_at: type: string format: date-time nullable: true description: When the child KYC session reached `Approved`. `null` while the child session has any other status. kyc_aml_categories: type: object nullable: true description: Per-category summary derived from the person's AML hits. `null` when there are no hits. properties: sanctions: type: string enum: - match - clear pep: type: string enum: - match - clear adverse_media: type: string enum: - match - clear warnings: type: string enum: - match - clear kyc_notification_sent_at: type: string nullable: true description: ISO 8601 timestamp of the last verification-invite notification sent for this person's child session. `null` when none was sent. beneficial_owners: type: array description: Beneficial owners discovered via the registry check, each enriched with the status of any child KYC session and AML screening spawned for them. items: type: object properties: uuid: type: string format: uuid name: type: string description: Beneficial owner's full name (or company name for corporate UBOs). first_name: type: string nullable: true last_name: type: string nullable: true date_of_birth: type: string format: date nullable: true country_of_birth: type: string nullable: true email: type: string format: email nullable: true company_name: type: string nullable: true description: 'For corporate UBOs (`entity_type = company`): the owning company''s name.' registration_number: type: string nullable: true description: 'For corporate UBOs: the owning company''s registration number.' entity_type: type: string enum: - person - company nationality: type: string nullable: true designation: type: string nullable: true roles: type: array description: Role names held by this owner, e.g. `["ubo", "shareholder"]`. items: type: string ownership_min_shares: type: string nullable: true description: Lower bound of the ownership percentage as reported by the registry. Free-form string (e.g. `"25"`, `"25-50%"`); use `effective_ownership_percent` for a parsed numeric value. ownership_max_shares: type: string nullable: true description: Upper bound of the ownership percentage as reported by the registry. Free-form string; use `effective_ownership_percent` for a parsed numeric value. is_active: type: boolean aml_status: type: string enum: - Not Finished - Approved - Declined - In Review - Resub Requested nullable: true description: Status of the AML screening run for this beneficial owner. `null` when no AML screening was run. kyc_status: type: string enum: - Not Started - In Progress - Approved - Declined - In Review - Expired - Abandoned - Kyc Expired - Resubmitted - Awaiting User nullable: true description: Raw lifecycle status of the child KYC session spawned for this beneficial owner. This is the full session status enum (not a reduced Approved/Declined/Pending set). `null` when no child KYC session exists. kyc_session_url: type: string format: uri nullable: true description: Shareable URL of the child KYC session. `null` when no child session exists. kyc_session_id: type: string format: uuid nullable: true description: Session id of the child KYC session. Pass it to this same decision endpoint to fetch the person's full KYC report. `null` when no child session exists. verification_workflow_type: type: string nullable: true description: Base workflow type of the child session's workflow (e.g. `kyc`). `null` for graph-based workflows or when no child session exists. verification_workflow_id: type: string format: uuid nullable: true description: Workflow id used by the child session. `null` when no child session exists. verification_workflow_label: type: string nullable: true description: Human-readable label of the child session's workflow. `null` when unset. verification_workflow_features: type: array nullable: true description: 'Per-feature progress of the child verification session, e.g. `[{"feature": "ID_VERIFICATION", "status": "Approved"}]`. `null` when the child session has no resolvable feature list.' items: type: object properties: feature: type: string description: Feature display name (e.g. `ID_VERIFICATION`, `LIVENESS`, `AML`). status: type: string enum: - Not Finished - Approved - Declined - In Review - Resub Requested description: Feature-level status inside the child session. didit_internal_id: type: string nullable: true description: Stable internal identifier of the verified individual behind the child session — useful for cross-session linking. `null` when no child session exists or the user has not been resolved yet. kyc_document_type: type: string nullable: true description: Document type presented in the child KYC session (e.g. `P`, `ID`, `DL`). `null` until the child session has an ID verification result. kyc_nationality: type: string nullable: true description: Nationality extracted from the document in the child KYC session. `null` until available. kyc_liveness_passed: type: boolean nullable: true description: Whether the child KYC session's liveness check passed. `null` when no liveness check has run. kyc_verified_at: type: string format: date-time nullable: true description: When the child KYC session reached `Approved`. `null` while the child session has any other status. kyc_aml_categories: type: object nullable: true description: Per-category summary derived from the person's AML hits. `null` when there are no hits. properties: sanctions: type: string enum: - match - clear pep: type: string enum: - match - clear adverse_media: type: string enum: - match - clear warnings: type: string enum: - match - clear kyc_notification_sent_at: type: string nullable: true description: ISO 8601 timestamp of the last verification-invite notification sent for this person's child session. `null` when none was sent. child_beneficial_owners: type: array description: 'For corporate UBOs: the owning entity''s own beneficial owners, as raw objects extracted from the registry. Empty array when not applicable.' items: type: object effective_ownership_percent: type: number nullable: true description: Parsed numeric ownership percentage — the max bound when available, otherwise the min bound. `null` when neither bound could be parsed. submitted: type: object description: Parties submitted by the business admin during the Key People flow (BusinessParty rows where source=USER). properties: parties: type: array items: type: object description: Party submitted by the business admin via the Key People flow (source=USER). properties: uuid: type: string format: uuid entity_type: type: string enum: - person - company source: type: string enum: - USER description: Always `USER` here — this bucket only contains parties entered or confirmed by the end user in the Key People flow (registry-discovered people appear under `registry`). name: type: string first_name: type: string nullable: true last_name: type: string nullable: true company_name: type: string nullable: true registration_number: type: string nullable: true email: type: string format: email nullable: true nationality: type: string nullable: true description: Nationality for persons; country of incorporation for company parties. phone_number: type: string nullable: true date_of_birth: type: string format: date nullable: true position: type: string nullable: true description: Free-text job title / position (persons only). custom_fields: type: object description: Workflow-defined custom fields collected for this party; keys are defined by the workflow's key-people field descriptors. is_active: type: boolean is_skipped: type: boolean description: True when the end user skipped verification for this party (only possible when the role allows skipping). requires_verification: type: boolean description: True when a child KYC / KYB sub-session is required for this party based on role settings and ownership thresholds. roles: type: array description: All roles held by this party, each with its own ownership and voting percentages. There is no scalar `role`/`ownership_percent` on the party itself. items: type: object properties: role: type: string enum: - director - non_executive_director - secretary - chairman - ubo - shareholder - representative - founder - legal_advisor - authorized_signatory - trustee - beneficiary - settlor - protector - company_officer - investor - other ownership_percent: type: number nullable: true voting_percent: type: number nullable: true kyc_session_id: type: string format: uuid nullable: true description: Child KYC session id for person parties requiring verification. `null` otherwise. kyc_session_status: type: string enum: - Not Started - In Progress - Approved - Declined - In Review - Expired - Abandoned - Kyc Expired - Resubmitted - Awaiting User nullable: true description: Lifecycle status of the child KYC session. `null` when no child KYC session exists. kyc_session_url: type: string format: uri nullable: true kyb_sub_session_id: type: string format: uuid nullable: true description: Child KYB sub-session id for corporate parties requiring verification. `null` otherwise. kyb_sub_session_status: type: string enum: - Not Started - In Progress - Approved - Declined - In Review - Expired - Abandoned - Kyc Expired - Resubmitted - Awaiting User nullable: true description: Lifecycle status of the child KYB sub-session. `null` when no sub-session exists. kyb_sub_session_url: type: string format: uri nullable: true description: Shareable URL of the child KYB sub-session. `null` when no sub-session exists. verification_workflow_type: type: string nullable: true description: Base workflow type of the child session's workflow (KYC session preferred, falling back to the KYB sub-session). `null` for graph-based workflows or when no child session exists. verification_workflow_id: type: string format: uuid nullable: true description: Workflow id used by the child session. `null` when no child session exists. verification_workflow_label: type: string nullable: true description: Human-readable label of the child session's workflow. `null` when unset. verification_workflow_features: type: array nullable: true description: 'Per-feature progress of the child verification session, e.g. `[{"feature": "ID_VERIFICATION", "status": "Approved"}]`. `null` when the child session has no resolvable feature list.' items: type: object properties: feature: type: string description: Feature display name (e.g. `ID_VERIFICATION`, `LIVENESS`, `AML`). status: type: string enum: - Not Finished - Approved - Declined - In Review - Resub Requested description: Feature-level status inside the child session. didit_internal_id: type: string nullable: true description: Stable internal identifier of the verified individual behind the child session. `null` when not resolved. ubo_kyc_summary: type: object nullable: true description: Aggregate UBO KYC progress, or null when no UBOs have linked KYC sessions. properties: total: type: integer approved: type: integer flagged: type: integer description: UBOs whose KYC is Declined or In Review. pending: type: integer warnings: type: array items: type: object document_verifications: type: array nullable: true description: Document verification checks grouped by workflow node. Present only when `session_kind = business`. items: type: object description: Documents grouped by workflow node. Present only when session_kind = business. properties: status: type: string node_id: type: string nullable: true items: type: array items: type: object properties: uuid: type: string format: uuid document_type: type: string enum: - LEGAL_PRESENCE - COMPANY_DETAILS - OWNERSHIP_STRUCTURE - REPRESENTATIVES_AUTHORIZATION - OTHER nullable: true description: High-level KYB document group the file was classified into. `null` while unclassified. document_subtype: type: string nullable: true description: Specific OCR-detected subtype (e.g. `CERTIFICATE_OF_INCORPORATION`, `SHAREHOLDER_REGISTRY`); `UNKNOWN` when the OCR could not confidently classify the document. document_group: type: string enum: - LEGAL_PRESENCE - COMPANY_DETAILS - OWNERSHIP_STRUCTURE - REPRESENTATIVES_AUTHORIZATION - OTHER nullable: true description: Alias of `document_type` — the group name used by `groups` and `required_groups`. file_url: type: string format: uri nullable: true description: Short-lived presigned link to the uploaded file. `null` for analyst-created document request placeholders (`is_requested = true`) that have not been fulfilled yet. original_filename: type: string nullable: true description: Filename as uploaded by the user or analyst. file_size: type: integer nullable: true description: File size in bytes. status: type: string enum: - Not Finished - Approved - Declined - In Review - Resub Requested description: Per-document verification status. created_at: type: string format: date-time cross_check_result: type: object nullable: true description: 'Cross-reference of the OCR-extracted document fields against the registry company profile. An object with `critical`, `non_critical` and `people` sections, each mapping a field name (e.g. `company_name`, `registration_number`, `incorporation_date`, `registered_address`) to a comparison record like `{"document": "...", "registry": "...", "match": true, "score": 0.97}`. `null` when the document had no OCR data or there was no registry company to compare against.' document_metadata: type: object nullable: true description: Metadata extracted from the uploaded corporate document. When metadata extraction succeeded, all 16 keys are always present (individual values are `null` when not applicable to the file type); the whole object is `null` when nothing could be extracted. For PDFs, `overlay_manipulation` carries forensic overlay-text analysis. properties: file_size: type: integer nullable: true description: Size of the document. content_type: type: string nullable: true description: Content type of the document. creation_date: type: string nullable: true description: Date when the document was created. modified_date: type: string nullable: true description: Date when the document was modified. creator: type: string nullable: true description: Authoring tool/user recorded in the file metadata (PDF `Creator`). producer: type: string nullable: true description: Software that produced the file (PDF `Producer`). software: type: string nullable: true description: Editing software recorded in the file metadata. encryption: type: string nullable: true description: Encryption scheme of the file, when encrypted. is_signed: type: boolean nullable: true description: Whether the document carries a digital signature. is_tampered: type: boolean nullable: true description: Whether the digital signature failed validation (post-signing modification). signature_info: type: object nullable: true description: Details of the digital signature(s), when present. exif_original_date: type: string nullable: true description: EXIF original capture date, for image uploads. exif_digitized_date: type: string nullable: true description: EXIF digitization date, for image uploads. processed_by_known_editor: type: boolean nullable: true description: Whether metadata indicates the file passed through a known image/PDF editor. has_different_creation_mod_date: type: boolean nullable: true description: Whether creation and modification dates differ — a possible (but not conclusive) editing signal. overlay_manipulation: type: object nullable: true description: PDF forensic analysis for suspected overlay-text manipulation. Null when no overlay manipulation evidence was found or the document was not a PDF. properties: detected: type: boolean description: Whether overlay-text manipulation evidence was detected. analyzed: type: boolean description: Whether the PDF could be analyzed. signals: type: array items: type: string description: Forensic signals that fired, such as duplicate_font_subset or glyph_fragmentation. manipulated_regions: type: array description: Suspected manipulated areas in PDF page coordinates. items: type: object properties: page: type: integer x: type: number y: type: number width: type: number height: type: number page_width: type: number page_height: type: number description: type: string nullable: true description: Analyst-provided label or reason for a document request. `null` for regular uploads. is_requested: type: boolean description: True for analyst-created document request placeholders awaiting an upload. ocr_data: type: object nullable: true is_console_upload: type: boolean description: True for documents uploaded from the console rather than the end-user flow. Console uploads never change the feature-level aggregate status. is_confirmed: type: boolean description: Console uploads start `false` and flip `true` once the admin confirms them; end-user uploads are always `true`. groups: type: object description: Per-group progress counters keyed by group name (e.g. legal_presence, ownership_structure). additionalProperties: type: object properties: total: type: integer approved: type: integer pending: type: integer declined: type: integer in_review: type: integer other: type: integer missing: type: integer description: Requested placeholders with no file uploaded yet. required_groups: type: array items: type: string warnings: type: array items: type: object environment: type: string enum: - live - sandbox description: Whether the session was created by a live application (`live`) or a sandbox application (`sandbox`). Sandbox sessions are free, fully simulated, and never bill credits. '403': description: 'Authentication or authorization failed. **This endpoint never returns `401`** — Didit''s API-key authentication does not emit a `WWW-Authenticate` challenge, so missing or invalid credentials also surface as `403`. Two `detail` strings distinguish the failure modes: - `"Authentication credentials were not provided or are invalid."` — no `x-api-key` header (and no `Authorization: Bearer` token), or the supplied credential failed introspection (revoked, expired, or malformed). - `"You do not have permission to perform this action."` — the credential is valid but not allowed to read this session: a console-user Bearer token lacks the `read:sessions` permission or cannot access the owning application, or an API key belongs to a different organization than the session. Note that for a completely unknown `sessionId` the endpoint resolves the owning application before validating credentials, so a missing session returns `404` even when the credential is missing or invalid.' content: application/json: schema: type: object properties: detail: type: string example: Authentication credentials were not provided or are invalid. examples: Missing or invalid credentials: summary: No x-api-key header, or the key failed introspection value: detail: Authentication credentials were not provided or are invalid. Insufficient permissions: summary: Valid credential lacking read:sessions or access to the owning application value: detail: You do not have permission to perform this action. '404': description: 'Session not found. Returned when no live session matches the supplied `sessionId` in either the User Verification (KYC) or Business Verification (KYB) table — including soft-deleted sessions. Body is the standard `{"detail": ...}` envelope. **Two distinct `detail` strings.** If the `sessionId` does not exist in either table, the pre-auth owner lookup fails and you receive `{"detail": "Not found."}` — this happens before credential validation, so it is returned even for unauthenticated calls. If the session exists but cannot be retrieved under the authenticated application (for example a stale or just-deleted record), the view returns `{"detail": "Session not found."}`. Both indicate the same outcome — the session is not accessible — so match on the `404` status code rather than the string.' content: application/json: schema: type: object properties: detail: type: string example: Not found. examples: Unknown session id: summary: sessionId does not exist in either session table value: detail: Not found. Session not retrievable: summary: Session exists but is not retrievable for this application value: detail: Session not found. '429': description: Rate limit exceeded. GET requests are limited to **600 per minute per credential** (API key, Bearer token, or source IP when unauthenticated). Inspect `Retry-After` / `X-RateLimit-Reset` and back off before retrying. If you hit this limit while polling for decisions, switch to the `status.updated` webhook and fetch the decision once per status change instead. headers: Retry-After: description: Seconds to wait before retrying the request. schema: type: integer minimum: 1 example: 30 X-RateLimit-Limit: description: Maximum number of requests allowed in the current window (600 for GET requests). schema: type: integer example: 600 X-RateLimit-Remaining: description: Requests remaining in the current window. schema: type: integer example: 0 X-RateLimit-Reset: description: Unix timestamp (seconds) at which the current window resets. schema: type: integer example: 1750000000 content: application/json: schema: type: object properties: detail: type: string description: Human-readable explanation of the rate-limit breach. example: GET request rate limit exceeded. You can make up to 600 requests per minute. examples: Throttled: summary: More than 600 GET requests in one minute from the same credential value: detail: GET request rate limit exceeded. You can make up to 600 requests per minute. parameters: - name: sessionId in: path required: true description: 'UUID of the verification session whose decision you want to retrieve. This is the `session_id` returned by `POST /v3/session/`. The same path works for both User Verification (KYC) and Business Verification (KYB) sessions — the server looks the id up in both tables. **Must be a valid UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router before any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}` envelope shown below. Validate the UUID format client-side so you can distinguish an input error from a genuine missing-session `404`.' schema: type: string format: uuid example: 11111111-2222-3333-4444-555555555555 - name: include in: query required: false description: 'Comma-separated list of extra payload sections. The only supported value is `events`. When `include=events` is passed, the response additionally contains the session event timeline (`events`), the full activity log (`activity_reviews`), blocklist flags (`blocklisted`), a per-session `cost_breakdown`, workflow metadata (`workflow_type`, `workflow_version`, `workflow_version_id`), and session metadata (`api_service` — string or `null`, set only for standalone-API sessions; `session_type` — `API`, `HOSTED`, or `MIGRATED`; `has_device_nfc_support` — boolean). Two fields change relative to the plain shape: the top-level `session_kind` discriminator is **omitted** (the events shape only exists for user sessions), and the `features` array switches from plain strings to `{feature, node_id}` objects — where the email feature is reported as `EMAIL` instead of `EMAIL_VERIFICATION`. This expanded shape is primarily used by the Didit Console; most API integrations should omit the parameter. **KYB limitation:** `include=events` only applies to user (KYC) sessions. Business sessions (`session_kind = "business"`) always return the standard business decision shape — `events`, `activity_reviews`, `blocklisted`, `cost_breakdown` and the extra `workflow_*`/session metadata are never returned for business sessions, and their `features` array stays a plain string array.' schema: type: string enum: - events example: events security: - ApiKeyAuth: [] x-codeSamples: - lang: curl label: cURL source: "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/decision/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Accept: application/json'" - lang: python label: Python source: "import requests\n\nsession_id = \"11111111-2222-3333-4444-555555555555\"\nurl = f\"https://verification.didit.me/v3/session/{session_id}/decision/\"\nheaders = {\n 'x-api-key': 'YOUR_API_KEY',\n \"Accept\": \"application/json\",\n}\n\nresponse = requests.get(url, headers=headers, timeout=15)\nresponse.raise_for_status()\ndecision = response.json()\n\nprint(\"session_kind:\", decision[\"session_kind\"])\nprint(\"top-level status:\", decision[\"status\"])\n\n# nfc_verifications is ALWAYS an array — never a singular `nfc` field.\nfor nfc in decision.get(\"nfc_verifications\") or []:\n print(\"nfc node_id:\", nfc[\"node_id\"], \"status:\", nfc[\"status\"])\n\nfor id_check in decision.get(\"id_verifications\") or []:\n print(\"id node_id:\", id_check[\"node_id\"], \"status:\", id_check[\"status\"])" - lang: javascript label: JavaScript source: "const sessionId = '11111111-2222-3333-4444-555555555555';\nconst response = await fetch(\n `https://verification.didit.me/v3/session/${sessionId}/decision/`,\n {\n method: 'GET',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n Accept: 'application/json',\n },\n }\n);\n\nif (!response.ok) {\n throw new Error(`Decision fetch failed: ${response.status}`);\n}\nconst decision = await response.json();\n\nconsole.log('session_kind:', decision.session_kind);\nconsole.log('top-level status:', decision.status);\n\n// nfc_verifications is ALWAYS an array — never a singular `nfc` field.\nfor (const nfc of decision.nfc_verifications ?? []) {\n console.log('nfc node_id:', nfc.node_id, 'status:', nfc.status);\n}\n\nfor (const idCheck of decision.id_verifications ?? []) {\n console.log('id node_id:', idCheck.node_id, 'status:', idCheck.status);\n}" tags: - Session components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key TransactionTokenAuth: type: apiKey in: header name: X-Transaction-Token description: Short-lived scoped token minted by your backend via POST /v3/transactions/sdk-token/. Used by the Didit SDKs on the device-facing /v1/transactions/ endpoints. SessionTokenAuth: type: apiKey in: header name: Session-Token description: Short-lived token returned in the `session_token` field of POST /v3/session/. Used by the hosted verification flow (and custom sandbox UIs) to call session-scoped endpoints on behalf of the verifying user, without your server-side API key.