Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.didit.me/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Every per-feature report follows the V3 serializer shape defined in service-didit-verification. The same object appears in three places, so the schema you see here is the single source of truth across them:
  • GET /v3/session/{sessionId}/decision/ — each feature is returned as a plural array (id_verifications[], nfc_verifications[], liveness_checks[], face_matches[], poa_verifications[], phone_verifications[], email_verifications[], aml_screenings[], ip_analyses[], database_validations[], questionnaire_responses[], and the KYB equivalents registry_checks[], document_verifications[], key_people_checks[]).
  • Webhook payloads (session.status.updated, session.created, session.events.updated) — same shape inside the decision envelope.
  • Standalone APIs — single-object responses (Face Search, Age Estimation, Biometric Authentication) reuse the same field set.
V3 introduced multi-instance workflows: every feature object carries a node_id that pins the report to the workflow graph node that produced it. V2 endpoints (singular kyc, face, aml, etc.) remain backwards-compatible but only return the first instance.

Common fields

Every report object exposes the following:
FieldTypeDescription
statusstringOne of the values in Status enum. Source: common/config/choices.py:StatusChoices (lines 106-117).
node_idstring | nullWorkflow graph node identifier. Populated for V3 multi-instance workflows; null for legacy single-feature sessions.
warningsarray of warning objectsRisk signals filtered to this feature and node_id. Returned by Session.get_logs(...) (sessions/models/session.py:1603).

Warning object

Returned in every warnings[] array. Schema from logs/serializers/log.py:8-65 (LogV3Serializer).
FieldTypeNullableDescriptionExample
featurestring (enum)NoWhich feature emitted the warning. Values from LogWarningChoices (common/config/choices.py:190-204): ID_VERIFICATION, NFC, LIVENESS, FACEMATCH, PROOF_OF_ADDRESS, PHONE, EMAIL, AML, LOCATION, DATABASE_VALIDATION, QUESTIONNAIRE, KYB_REGISTRY, KYB_DOCUMENTS, KYB_KEY_PEOPLE."ID_VERIFICATION"
riskstringNoStable risk code (e.g. EXPIRED_DOCUMENT, LOW_LIVENESS_SCORE). Used as the key into description tables."EXPIRED_DOCUMENT"
additional_dataobject | nullYesRisk-specific context (e.g. score thresholds, matched fields). Shape varies by risk code.{ "score": 42.1, "threshold": 70 }
log_typestring (enum)NoOne of error, warning, information. From LogTypeChoices (common/config/choices.py:207-210)."error"
short_descriptionstringNoHuman-readable label for the risk. Translated via logs/choices.py:RISK_SHORT_DESCRIPTIONS."Expired document"
long_descriptionstringNoLonger human-readable explanation suitable for end-user-facing surfaces."The ID document presented has an expiration date in the past."
node_idstring | nullYesWorkflow graph node the warning was raised against. null for legacy V2 logs without node_id."first_id_verification"
{
  "feature": "ID_VERIFICATION",
  "risk": "EXPIRED_DOCUMENT",
  "additional_data": { "expiration_date": "2023-02-15" },
  "log_type": "error",
  "short_description": "Expired document",
  "long_description": "The ID document presented has an expiration date in the past.",
  "node_id": "first_id_verification"
}

Report objects

The remaining sections cover each per-feature report object. The H3 heading text is intentionally stable so other docs can deep-link to it.

ID verification

Returned from each KYC/ID document a user submits. Appears as id_verifications[] in the V3 decision payload and inside the kyc field of V2 responses. Source: kyc/serializers/kyc.py:372-403 (IDVerificationV3Serializer, extends IDVerificationV2Serializer at kyc/serializers/kyc.py:310-369).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
document_typestringYesHuman-readable document class (Passport, ID Card, Driver License, Residence Permit, Other)."Passport"
document_numberstringYesOCR-extracted document number."AB1234567"
personal_numberstringYesOCR-extracted personal/national identifier."99999999R"
portrait_imagestring (URL)YesPresigned URL to the face crop."https://didit-storage.s3.../portrait.jpg?..."
front_imagestring (URL)YesPresigned URL to the cleaned document front."https://didit-storage.s3.../front.jpg?..."
front_videostring (URL)YesPresigned URL to the front capture video (when available)."https://didit-storage.s3.../front.mp4?..."
back_imagestring (URL)YesPresigned URL to the cleaned document back."https://didit-storage.s3.../back.jpg?..."
back_videostring (URL)YesPresigned URL to the back capture video.null
full_front_imagestring (URL)YesUnclipped (full-frame) front capture."https://didit-storage.s3.../full_front.jpg?..."
full_back_imagestring (URL)YesUnclipped (full-frame) back capture.null
front_image_camera_frontstring (URL)YesFront-camera image taken at the same time as the document front.null
back_image_camera_frontstring (URL)YesFront-camera image taken at the same time as the document back.null
front_image_camera_front_face_match_scoreintegerYesSimilarity (0-100) between the document portrait and the front-camera capture.null
back_image_camera_front_face_match_scoreintegerYesSame as above but for the back capture.null
front_image_quality_scoreobjectYesPer-axis quality breakdown (sharpness, glare, exposure).{ "sharpness": 0.91, "glare": 0.04 }
back_image_quality_scoreobjectYesSame shape as front_image_quality_score.null
date_of_birthstring (YYYY-MM-DD)YesOCR-extracted DOB."1990-05-12"
ageintegerYesComputed age in years at extraction time.35
expiration_datestring (YYYY-MM-DD)YesDocument expiration."2032-05-11"
date_of_issuestring (YYYY-MM-DD)YesDocument issue date."2022-05-11"
issuing_statestring (ISO 3166-1 alpha-3)YesIssuing country code."ESP"
issuing_state_namestringYesLocalized issuing country name."Spain"
first_namestringYesOCR-extracted given name(s)."María"
last_namestringYesOCR-extracted surname(s)."García López"
full_namestringYesFull normalized name (vendor-supplied)."María García López"
genderstringYesM, F, or other vendor-supplied value."F"
addressstringYesRaw OCR-extracted address line."Calle Mayor 1, 28001 Madrid"
formatted_addressstringYesGeocoded/formatted address (when parseable)."Calle Mayor 1, 28001 Madrid, Spain"
parsed_addressobjectYesStructured address (street, city, postal_code, country, formatted_address, …). Vendor-dependent keys.{ "city": "Madrid", "postal_code": "28001", "country": "ES" }
place_of_birthstringYesOCR-extracted place of birth."Madrid"
marital_statusstringYesWhen extractable.null
nationalitystring (ISO 3166-1 alpha-3)YesOCR-extracted nationality."ESP"
extra_fieldsobjectYesDocument-type-specific fields not covered by the canonical schema (e.g. driver license categories).{ "DL Class": "B" }
mrzobjectYesParsed MRZ fields when present (document_number, birth_date, expiry_date, surname, given_names, …).{ "document_number": "AB1234567", "surname": "GARCIA", "given_names": "MARIA" }
extra_filesarray of strings (URL)NoPresigned URLs to any additional uploaded files.[]
matchesarray of objectsYesCross-session document matches: { session_id, vendor_data, document_number, front_image_url, … }.[]
node_idstring | nullYesWorkflow node identifier (V3)."first_id_verification"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "document_type": "Passport",
  "document_number": "AB1234567",
  "personal_number": "99999999R",
  "portrait_image": "https://didit-storage.s3.amazonaws.com/.../portrait.jpg?X-Amz-Signature=...",
  "front_image": "https://didit-storage.s3.amazonaws.com/.../front.jpg?X-Amz-Signature=...",
  "front_video": null,
  "back_image": "https://didit-storage.s3.amazonaws.com/.../back.jpg?X-Amz-Signature=...",
  "back_video": null,
  "full_front_image": "https://didit-storage.s3.amazonaws.com/.../full_front.jpg?X-Amz-Signature=...",
  "full_back_image": null,
  "front_image_camera_front": null,
  "back_image_camera_front": null,
  "front_image_camera_front_face_match_score": null,
  "back_image_camera_front_face_match_score": null,
  "front_image_quality_score": { "sharpness": 0.91, "glare": 0.04, "exposure": 0.88 },
  "back_image_quality_score": null,
  "date_of_birth": "1990-05-12",
  "age": 35,
  "expiration_date": "2032-05-11",
  "date_of_issue": "2022-05-11",
  "issuing_state": "ESP",
  "issuing_state_name": "Spain",
  "first_name": "María",
  "last_name": "García López",
  "full_name": "María García López",
  "gender": "F",
  "address": "Calle Mayor 1, 28001 Madrid",
  "formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
  "parsed_address": { "street": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" },
  "place_of_birth": "Madrid",
  "marital_status": null,
  "nationality": "ESP",
  "extra_fields": {},
  "mrz": {
    "document_number": "AB1234567",
    "surname": "GARCIA",
    "given_names": "MARIA",
    "birth_date": "900512",
    "expiry_date": "320511"
  },
  "extra_files": [],
  "matches": [],
  "node_id": "first_id_verification",
  "warnings": []
}

NFC verification

Returned for each ePassport chip read against an ID document. Appears as nfc_verifications[] in the V3 decision payload (one per parent KYC record). Source: kyc/serializers/epassport.py:121-139 (NFCV3Serializer, extends NFCV2Serializer at kyc/serializers/epassport.py:83-118).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
portrait_imagestring (URL)YesPresigned URL to the chip-extracted face image."https://didit-storage.s3.../nfc_portrait.jpg?..."
signature_imagestring (URL)YesPresigned URL to the chip-extracted signature image (when stored on the chip).null
chip_dataobjectYesParsed Data Groups read from the chip. Keys include DG1 (MRZ), DG2 (face), DG7 (signature), DG11 (additional personal details).{ "DG1": { "document_number": "AB1234567" }, "DG2": { "face_image_present": true } }
authenticityobjectNo{ sod_integrity, dg_integrity }. sod_integrity validates that the Document Security Object (SOD) signature matches the chip-issuer certificate; dg_integrity validates that each Data Group hashes match the SOD. Both true means the chip is genuine and untampered.{ "sod_integrity": true, "dg_integrity": true }
certificate_summaryobjectYesSummary of the issuing country’s signing certificate (CSCA): issuer, validity window, signature algorithm.{ "issuer": "C=ES, O=Ministry of Interior", "valid_from": "2018-01-01", "valid_to": "2028-01-01" }
node_idstring | nullYesWorkflow node identifier (V3)."first_nfc"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "portrait_image": "https://didit-storage.s3.amazonaws.com/.../nfc_portrait.jpg?X-Amz-Signature=...",
  "signature_image": null,
  "chip_data": {
    "DG1": {
      "document_number": "AB1234567",
      "surname": "GARCIA",
      "given_names": "MARIA",
      "birth_date": "1990-05-12",
      "expiry_date": "2032-05-11",
      "nationality": "ESP",
      "issuing_state": "ESP",
      "gender": "F"
    },
    "DG2": { "face_image_present": true },
    "DG11": { "place_of_birth": "Madrid" }
  },
  "authenticity": { "sod_integrity": true, "dg_integrity": true },
  "certificate_summary": {
    "issuer": "C=ES, O=Ministry of Interior",
    "subject": "C=ES, CN=Document Signer 2023",
    "valid_from": "2023-01-01",
    "valid_to": "2028-01-01",
    "signature_algorithm": "sha256WithRSAEncryption"
  },
  "node_id": "first_nfc",
  "warnings": []
}

Liveness check

Returned per liveness session. Appears as liveness_checks[] in the V3 decision payload. Source: face/serializers/face.py:301-320 (LivenessV3Serializer, extends LivenessV2Serializer at face/serializers/face.py:216-298).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
methodstringYesactive or passive. Passive runs when is_desktop_allowed is enabled and the session is performed on a desktop."passive"
scorefloat (0-100)YesLiveness confidence, rounded to 2 decimals.92.41
reference_imagestring (URL)YesPresigned URL to the user’s reference face crop."https://didit-storage.s3.../reference.jpg?..."
video_urlstring (URL)YesPresigned URL to the liveness video (active mode only)."https://didit-storage.s3.../liveness.webm?..."
age_estimationfloatYesEstimated age (in years) of the largest face in the reference image.34.2
matchesarray of objectsNoCross-session face matches: { session_id, similarity, match_image_url, vendor_data, verification_date, user_details: { name, document_type, document_number } }. match_image_url is presigned.[]
face_qualityfloat (0-100)YesPassive-liveness face-quality score (normalized to a percentage).87.50
face_luminancefloat (0-100)YesPassive-liveness face-luminance score (normalized from 0-255 to a percentage).54.12
node_idstring | nullYesWorkflow node identifier (V3)."first_liveness"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "method": "passive",
  "score": 92.41,
  "reference_image": "https://didit-storage.s3.amazonaws.com/.../reference.jpg?X-Amz-Signature=...",
  "video_url": null,
  "age_estimation": 34.2,
  "matches": [],
  "face_quality": 87.50,
  "face_luminance": 54.12,
  "node_id": "first_liveness",
  "warnings": []
}

Face match

Returned per face-match comparison (typically the user’s liveness face against the document portrait). Appears as face_matches[] in the V3 decision payload. Source: face/serializers/face.py:367-389 (FaceMatchV3Serializer, extends FaceMatchV2Serializer at face/serializers/face.py:323-364).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
scorefloat (0-100)YesSimilarity, rounded to 2 decimals. When the provider returns only an unmatched_faces[].Confidence, it’s converted to 100 - confidence.97.83
source_image_session_idstring (UUID)YesThe session that produced the source (reference) image — set when face-match runs cross-session (e.g. Face Search match confirmation).null
source_imagestring (URL)YesPresigned URL to the source (live face) image."https://didit-storage.s3.../source.jpg?..."
target_imagestring (URL)YesPresigned URL to the target (document portrait) image."https://didit-storage.s3.../target.jpg?..."
node_idstring | nullYesWorkflow node identifier (V3)."first_face_match"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "score": 97.83,
  "source_image_session_id": null,
  "source_image": "https://didit-storage.s3.amazonaws.com/.../source.jpg?X-Amz-Signature=...",
  "target_image": "https://didit-storage.s3.amazonaws.com/.../target.jpg?X-Amz-Signature=...",
  "node_id": "first_face_match",
  "warnings": []
}
Returned by the standalone Face Search API (POST /v2/face-search/). Face Search is a one-shot lookup — it does not appear as a plural array in /v3/session/{sessionId}/decision/ because it is not a session-bound feature. Source: apis/serializers/face_search.py:8-79 (FaceSearchResponseSerializer wrapping FaceSearchDetailsSerializer). Top-level response:
FieldTypeNullableDescriptionExample
request_idstring (UUID)NoStable identifier for the search request — use it for support tickets and replays."4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f"
face_searchobjectNoThe search-details payload — see fields below.
vendor_datastringYesEchoed vendor_data from the request.null
metadataobjectYesEchoed metadata from the request.null
created_atstring (ISO 8601)NoServer-side request timestamp."2026-05-17T10:22:13.514012Z"
face_search object:
FieldTypeNullableDescriptionExample
statusstringNoApproved when a confident match was found; Declined / In Review otherwise. See Status enum."Approved"
total_matchesintegerNoNumber of returned matches in matches[].1
matchesarray of face-search match objectsNoMatches sorted by descending similarity.[…]
warningsarrayNoSee Warning object.[]

Face-search match object

FieldTypeNullableDescriptionExample
session_idstring (UUID)NoThe matched verification session."a3f2a6f1-…"
similarityfloat (0-100)NoCosine similarity.96.42
vendor_datastringYesThe matched session’s vendor_data (your downstream user id)."user-12345"
verification_datestring (ISO 8601)NoWhen the matched session completed."2024-11-04T09:14:02Z"
user_detailsobjectNo{ name, document_type, document_number } extracted from the matched session’s KYC.{ "name": "María García López", "document_type": "Passport", "document_number": "AB1234567" }
match_image_urlstring (URL)NoPresigned URL to the matched user’s reference face."https://didit-storage.s3.../matched.jpg?..."
{
  "request_id": "4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f",
  "face_search": {
    "status": "Approved",
    "total_matches": 1,
    "matches": [
      {
        "session_id": "a3f2a6f1-1c1c-4eec-8b69-1c1c2f3a2c7f",
        "similarity": 96.42,
        "vendor_data": "user-12345",
        "verification_date": "2024-11-04T09:14:02Z",
        "user_details": {
          "name": "María García López",
          "document_type": "Passport",
          "document_number": "AB1234567"
        },
        "match_image_url": "https://didit-storage.s3.amazonaws.com/.../matched.jpg?X-Amz-Signature=..."
      }
    ],
    "warnings": []
  },
  "vendor_data": null,
  "metadata": null,
  "created_at": "2026-05-17T10:22:13.514012Z"
}

AML screening

Returned per screened entity. Appears as aml_screenings[] in both KYC and KYB V3 decision payloads. Source: aml/serializers/aml.py:63-85 (AMLV3Serializer, extends AMLV2Serializer at aml/serializers/aml.py:28-60).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
total_hitsintegerNoNumber of hits returned by the screening provider (always present, defaults to 0).2
entity_typestringYesperson or business."person"
hitsarray of objectsNoOne entry per hit. Each hit includes the provider-supplied identifier, names, dates of birth, sanctions/PEP/adverse-media category lists, source URLs, and a review_status (pending, confirmed, cleared) editable via the update-AML-hit-status endpoint.[…]
scorefloatYesAggregated risk score (provider-specific scale).42.7
screened_dataobjectYesSnapshot of the data sent to the screening provider (full_name, date_of_birth, nationality, gender, place_of_birth, …).{ "full_name": "María García López", "date_of_birth": "1990-05-12" }
is_ongoing_monitoring_enabledbooleanNoWhether the entity is subscribed to ongoing-monitoring re-screens.false
next_ongoing_monitoring_bill_datestring (YYYY-MM-DD)YesComputed as last_aml_bill_date + 365 days when ongoing monitoring is enabled.null
node_idstring | nullYesWorkflow node identifier (V3)."first_aml"
warningsarrayNoSee Warning object.[]
{
  "status": "In Review",
  "total_hits": 1,
  "entity_type": "person",
  "hits": [
    {
      "hit_id": "kompany_hit_a1b2c3",
      "names": ["María García López", "M. García"],
      "dates_of_birth": ["1990-05-12"],
      "categories": ["PEP-Class-2"],
      "sources": [
        { "name": "OpenSanctions PEP", "url": "https://www.opensanctions.org/entities/..." }
      ],
      "review_status": "pending"
    }
  ],
  "score": 42.7,
  "screened_data": {
    "full_name": "María García López",
    "date_of_birth": "1990-05-12",
    "nationality": "ESP",
    "gender": "F"
  },
  "is_ongoing_monitoring_enabled": false,
  "next_ongoing_monitoring_bill_date": null,
  "node_id": "first_aml",
  "warnings": []
}

IP analysis

Returned per captured network location. Appears as ip_analyses[] in both KYC and KYB V3 decision payloads. Source: kyc/serializers/location.py:196-243 (IPAnalysisSerializerV3).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
node_idstring | nullYesWorkflow node identifier (V3)."first_ip_analysis"
device_brandstringYesUser-agent-derived device brand."Apple"
device_modelstringYesDevice model."iPhone"
browser_familystringYesBrowser family."Mobile Safari"
os_familystringYesOS family."iOS"
platformstringYesHigh-level platform (mobile, desktop, tablet)."mobile"
device_fingerprintstringYesStable per-device fingerprint hash."f2a3…"
ip_countrystringYesCountry name resolved from the IP."Spain"
ip_country_codestring (ISO 3166-1 alpha-2)YesCountry code resolved from the IP."ES"
ip_statestringYesRegion / state resolved from the IP."Comunidad de Madrid"
ip_citystringYesCity resolved from the IP."Madrid"
latitudefloatYesIP-derived latitude.40.4168
longitudefloatYesIP-derived longitude.-3.7038
ip_addressstringYesThe captured IP address."203.0.113.42"
ispstringYesISP name."Telefonica de Espana"
organizationstringYesOrganization name (often equal to ISP)."Telefonica de Espana"
is_vpn_or_torbooleanYestrue when the IP belongs to a VPN, proxy, or Tor exit node.false
is_data_centerbooleanYestrue when the IP belongs to a known hosting / data-center ASN.false
time_zonestringYesIANA time-zone name."Europe/Madrid"
time_zone_offsetstringYesUTC offset."+02:00"
ipobjectNo{ location, distance_from_id_document, distance_from_poa_document }. location = { latitude, longitude }. Distances in km, null when either side is missing.{ "location": { "latitude": 40.4168, "longitude": -3.7038 }, "distance_from_id_document": 3.4, "distance_from_poa_document": 1.1 }
id_documentobjectNo{ location, distance_from_ip, distance_from_poa_document }. ID document location resolved from issuing_state and parsed address.{ "location": { "latitude": 40.4165, "longitude": -3.7026 }, "distance_from_ip": 3.4, "distance_from_poa_document": 4.0 }
poa_documentobjectNo{ location, distance_from_ip, distance_from_id_document }. POA address geocoded.{ "location": { "latitude": 40.4170, "longitude": -3.7040 }, "distance_from_ip": 1.1, "distance_from_id_document": 4.0 }
matchesarray of objectsNoCross-session IP/device matches (e.g. duplicate device_fingerprint).[]
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "node_id": "first_ip_analysis",
  "device_brand": "Apple",
  "device_model": "iPhone",
  "browser_family": "Mobile Safari",
  "os_family": "iOS",
  "platform": "mobile",
  "device_fingerprint": "f2a3c1de8b994a3f9e4cdf3a02b1a7c9",
  "ip_country": "Spain",
  "ip_country_code": "ES",
  "ip_state": "Comunidad de Madrid",
  "ip_city": "Madrid",
  "latitude": 40.4168,
  "longitude": -3.7038,
  "ip_address": "203.0.113.42",
  "isp": "Telefonica de Espana",
  "organization": "Telefonica de Espana",
  "is_vpn_or_tor": false,
  "is_data_center": false,
  "time_zone": "Europe/Madrid",
  "time_zone_offset": "+02:00",
  "ip": {
    "location": { "latitude": 40.4168, "longitude": -3.7038 },
    "distance_from_id_document": 3.4,
    "distance_from_poa_document": 1.1
  },
  "id_document": {
    "location": { "latitude": 40.4165, "longitude": -3.7026 },
    "distance_from_ip": 3.4,
    "distance_from_poa_document": 4.0
  },
  "poa_document": {
    "location": { "latitude": 40.4170, "longitude": -3.7040 },
    "distance_from_ip": 1.1,
    "distance_from_id_document": 4.0
  },
  "matches": [],
  "warnings": []
}

Proof of address

Returned per submitted address document. Appears as poa_verifications[] in the V3 decision payload. Source: poa/serializers/poa.py:212-227 (POAV3Serializer, extends POAV2Serializer at poa/serializers/poa.py:173-209).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
issuing_statestring (ISO 3166-1 alpha-3)YesCountry code of the document issuer."ESP"
document_typestringYesHigh-level type (utility_bill, bank_statement, government_correspondence, …)."utility_bill"
document_subtypestringYesProvider-specific subtype (e.g. electricity, water)."electricity"
issuerstringYesName of the issuing entity."Iberdrola"
issue_datestring (YYYY-MM-DD)YesDocument issue date."2026-04-15"
expiration_datestring (YYYY-MM-DD)YesWhen the document is no longer accepted as proof (when applicable).null
poa_addressstringYesRaw OCR-extracted address."Calle Mayor 1, 28001 Madrid"
poa_formatted_addressstringYesGeocoded/formatted address."Calle Mayor 1, 28001 Madrid, Spain"
poa_parsed_addressobjectYesStructured address (street, city, postal_code, country, …).{ "city": "Madrid", "postal_code": "28001" }
document_filestring (URL)YesPresigned URL to the cleaned document file."https://didit-storage.s3.../poa.pdf?..."
document_languagestringYesDetected document language (BCP-47)."es"
document_metadataobjectYesFiltered metadata: file_size, content_type, creation_date, modified_date, creator, producer, software, encryption, is_signed, is_tampered, signature_info, exif_original_date, exif_digitized_date, processed_by_known_editor, has_different_creation_mod_date, overlay_manipulation.{ "file_size": 184221, "content_type": "application/pdf", "is_tampered": false }
extra_fieldsobjectNoBank-account fields (bank_account_number, bank_iban, bank_sort_code, bank_routing_number, bank_swift_bic, bank_branch_name, bank_branch_address), document_phone_number, additional_names, plus any custom keys persisted on the record.{ "bank_iban": null, "additional_names": [] }
name_on_documentstringYesName as it appears on the POA."María García López"
expected_details_addressstringYesAddress the customer typed during signup (verbatim)."Calle Mayor 1, Madrid"
expected_details_formatted_addressstringYesGeocoded expected address."Calle Mayor 1, 28001 Madrid, Spain"
expected_details_parsed_addressobjectYesStructured expected address.{ "city": "Madrid", "postal_code": "28001" }
name_match_score_expected_detailsfloat (0-100)YesFuzzy match between name_on_document and the name supplied at session creation.94.0
name_match_score_id_verificationfloat (0-100)YesFuzzy match between name_on_document and the verified ID’s full_name.100.0
extra_filesarray of strings (URL)NoPresigned URLs to additional uploaded files.[]
node_idstring | nullYesWorkflow node identifier (V3)."first_poa"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "issuing_state": "ESP",
  "document_type": "utility_bill",
  "document_subtype": "electricity",
  "issuer": "Iberdrola",
  "issue_date": "2026-04-15",
  "expiration_date": null,
  "poa_address": "Calle Mayor 1, 28001 Madrid",
  "poa_formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
  "poa_parsed_address": { "street": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" },
  "document_file": "https://didit-storage.s3.amazonaws.com/.../poa.pdf?X-Amz-Signature=...",
  "document_language": "es",
  "document_metadata": {
    "file_size": 184221,
    "content_type": "application/pdf",
    "creation_date": "2026-04-15T08:11:32Z",
    "modified_date": "2026-04-15T08:11:32Z",
    "creator": "Iberdrola Billing",
    "producer": "Adobe PDF Library 15.0",
    "software": null,
    "encryption": null,
    "is_signed": true,
    "is_tampered": false,
    "signature_info": { "signer": "Iberdrola Clientes" },
    "exif_original_date": null,
    "exif_digitized_date": null,
    "processed_by_known_editor": false,
    "has_different_creation_mod_date": false,
    "overlay_manipulation": false
  },
  "extra_fields": {
    "bank_account_number": null,
    "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": null,
    "additional_names": []
  },
  "name_on_document": "María García López",
  "expected_details_address": "Calle Mayor 1, Madrid",
  "expected_details_formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
  "expected_details_parsed_address": { "city": "Madrid", "postal_code": "28001", "country": "ES" },
  "name_match_score_expected_details": 94.0,
  "name_match_score_id_verification": 100.0,
  "extra_files": [],
  "node_id": "first_poa",
  "warnings": []
}

Phone verification

Returned per phone-verification attempt. Appears as phone_verifications[] in both KYC and KYB V3 decision payloads. Source: phone/serializers/phone.py:251-266 (PhoneV3Serializer, extends PhoneV2Serializer at phone/serializers/phone.py:103-248).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
phone_number_prefixstringNoE.164 country prefix (with +)."+34"
phone_numberstringNoSubscriber number without the prefix."612345678"
full_numberstringNoThe full E.164 number (phone_number_prefix + phone_number)."+34612345678"
country_codestring (ISO 3166-1 alpha-2)YesCountry of the number."ES"
country_namestringYesLocalized country name."Spain"
carrierobjectNo{ name, type } where type is one of mobile, landline, voip, isp, vpn, toll_free, unknown (see LineTypeChoices).{ "name": "Movistar", "type": "mobile" }
is_disposablebooleanNotrue when the carrier marks the number as temporary/disposable.false
is_virtualbooleanNotrue when carrier.type is one of voip, isp, vpn.false
verification_methodstringNoChannel used to deliver the OTP (whatsapp, sms, …). Reads from the last send attempt’s actual_channel (falls back to the requested channel, then sms)."whatsapp"
verification_attemptsintegerNoTotal OTP check attempts the user made.1
verified_atstring (ISO 8601)YesTimestamp the OTP was successfully entered."2026-05-17T10:14:02Z"
lifecyclearray of objectsNoChronological events: send attempts, delivery callbacks, code checks, and the final status event. Each event is { type, timestamp, details, fee }. Event types come from PhoneEventChoices.[…]
matchesarray of objectsNoCross-session phone-number matches.[]
node_idstring | nullYesWorkflow node identifier (V3)."first_phone"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "phone_number_prefix": "+34",
  "phone_number": "612345678",
  "full_number": "+34612345678",
  "country_code": "ES",
  "country_name": "Spain",
  "carrier": { "name": "Movistar", "type": "mobile" },
  "is_disposable": false,
  "is_virtual": false,
  "verification_method": "whatsapp",
  "verification_attempts": 1,
  "verified_at": "2026-05-17T10:14:02Z",
  "lifecycle": [
    {
      "type": "PHONE_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2026-05-17T10:13:51Z",
      "details": { "status": "approved", "reason": null, "channel": "whatsapp", "actual_channel": "whatsapp" },
      "fee": 0.04
    },
    {
      "type": "PHONE_DELIVERY_DELIVERED",
      "timestamp": "2026-05-17T10:13:52Z",
      "details": { "channel": "whatsapp", "status": "delivered" },
      "fee": 0
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2026-05-17T10:14:02Z",
      "details": { "code_tried": "482917", "status": "approved" },
      "fee": 0
    },
    {
      "type": "PHONE_VERIFICATION_APPROVED",
      "timestamp": "2026-05-17T10:14:02Z",
      "details": null,
      "fee": 0
    }
  ],
  "matches": [],
  "node_id": "first_phone",
  "warnings": []
}

Email verification

Returned per email-verification attempt. Appears as email_verifications[] in both KYC and KYB V3 decision payloads. Source: email_verification/serializers/email.py:149-164 (EmailV3Serializer, extends EmailV2Serializer at email_verification/serializers/email.py:38-146).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
emailstringNoThe submitted email address."maria.garcia@example.com"
is_breachedbooleanNotrue when the email appears in a known data breach.false
breachesarray of objectsNoPer-breach detail when is_breached is true (name, date, data_classes).[]
is_disposablebooleanNotrue when the email belongs to a disposable-mail provider.false
is_undeliverablebooleanNotrue when SMTP delivery probing shows the inbox doesn’t accept mail.false
verification_attemptsintegerNoTotal OTP check attempts.1
verified_atstring (ISO 8601)YesTimestamp the OTP was successfully entered."2026-05-17T10:15:22Z"
lifecyclearray of objectsNoChronological events: send attempts, code checks, and the final status event. Each event is { type, timestamp, details, fee }. Event types come from EmailEventChoices.[…]
matchesarray of objectsNoCross-session email matches.[]
node_idstring | nullYesWorkflow node identifier (V3)."first_email"
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "email": "maria.garcia@example.com",
  "is_breached": false,
  "breaches": [],
  "is_disposable": false,
  "is_undeliverable": false,
  "verification_attempts": 1,
  "verified_at": "2026-05-17T10:15:22Z",
  "lifecycle": [
    {
      "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2026-05-17T10:15:11Z",
      "details": { "status": "approved", "reason": null },
      "fee": 0.001
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2026-05-17T10:15:22Z",
      "details": { "code_tried": "739204", "status": "approved" },
      "fee": 0
    },
    {
      "type": "EMAIL_VERIFICATION_APPROVED",
      "timestamp": "2026-05-17T10:15:22Z",
      "details": null,
      "fee": 0
    }
  ],
  "matches": [],
  "node_id": "first_email",
  "warnings": []
}

Database validation

Returned per database lookup run against the user’s submitted data. Appears as database_validations[] in the V3 decision payload. Source: database_validation/serializers/database_validation.py:118-137 (DatabaseValidationV3Serializer, extends DatabaseValidationV2Serializer at database_validation/serializers/database_validation.py:10-115).
FieldTypeNullableDescriptionExample
issuing_statestring (ISO 3166-1 alpha-3)YesCountry whose registry was queried."ESP"
validation_typestringYesWhich validation profile ran (provider-specific identifier, e.g. dni_es_policia)."dni_es_policia"
screened_dataobjectNoThe data submitted to the registry. When a selfie field is present it is presigned at read time.{ "document_number": "99999999R", "date_of_birth": "1990-05-12" }
validationsarray of objectsNoOne entry per catalog service that produced a match. Each entry can include service_id, service_name, validation (provider verdict object), outcome_code, outcome_detail, and source_data (cleaned citizen profile: full_name, gender, date_of_birth, photo (presigned URL), signature (presigned URL), …).[…]
errorsarray of objectsYesPer-service errors when a lookup failed; omitted when empty. Each entry includes service_id plus provider error fields (code, message).[]
match_typestringYesHigh-level match verdict (exact, partial, none)."exact"
statusstringNoSee Status enum."Approved"
node_idstring | nullYesWorkflow node identifier (V3)."first_db_validation"
warningsarrayNoSee Warning object.[]
{
  "issuing_state": "ESP",
  "validation_type": "dni_es_policia",
  "screened_data": {
    "document_number": "99999999R",
    "date_of_birth": "1990-05-12",
    "first_name": "María",
    "last_name": "García López"
  },
  "validations": [
    {
      "service_id": "es_policia_dni",
      "service_name": "DNI verification (Policía Nacional)",
      "validation": { "is_valid": true, "match_score": 100 },
      "outcome_code": "MATCH",
      "outcome_detail": "All identifiers match the registry record.",
      "source_data": {
        "full_name": "María García López",
        "gender": "F",
        "date_of_birth": "1990-05-12",
        "photo": "https://didit-storage.s3.amazonaws.com/.../registry_photo.jpg?X-Amz-Signature=...",
        "signature": null
      }
    }
  ],
  "match_type": "exact",
  "status": "Approved",
  "node_id": "first_db_validation",
  "warnings": []
}

Questionnaire response

Returned per questionnaire submission. Appears as questionnaire_responses[] in both KYC and KYB V3 decision payloads. Source: questionnaires/serializers/questionnaire.py:591-597 (QuestionnaireResponseV3Serializer, extends QuestionnaireResponseSerializer at questionnaires/serializers/questionnaire.py:520-588).
FieldTypeNullableDescriptionExample
questionnaire_idstring (UUID)NoStable identifier for the questionnaire template."6a0f1c2c-…"
titleobjectNoLocalized title map ({ <lang_code>: <title> }).{ "en": "Customer profile", "es": "Perfil del cliente" }
descriptionobjectYesLocalized description map.{ "en": "Short risk-profile questions." }
languagesarray of stringsNoBCP-47 language codes the questionnaire is published in.["en", "es"]
default_languagestringNoFallback language code."en"
is_activebooleanNoWhether this questionnaire version is the active one.true
is_simple_questionnairebooleanNotrue when the questionnaire has no branching (flat list).true
questionnaire_group_idstring (UUID)NoIdentifier shared across versions of the same questionnaire."a7c2c2c2-…"
versionintegerNoVersion number of the active template.3
statusstringNoSee Status enum."Approved"
published_atstring (ISO 8601)YesWhen the template was published."2026-01-12T11:00:00Z"
sectionsarray of objectsNoOrdered sections after applying graph traversal and visibility filtering. Each section is { title, description, items[] }. Each item is a form element (uuid, value (node_id), element_type, title, description, type-specific config like options, plus an answer field populated for answered, non-ignored elements). File answers contain { files: [<presigned URL>, …] }.[…]
node_idstring | nullYesWorkflow node identifier (V3)."first_questionnaire"
{
  "questionnaire_id": "6a0f1c2c-3b7d-4d2c-9eb6-fdc6c7c92ef9",
  "title": { "en": "Customer risk profile", "es": "Perfil de riesgo del cliente" },
  "description": { "en": "Short risk-profile questions." },
  "languages": ["en", "es"],
  "default_language": "en",
  "is_active": true,
  "is_simple_questionnaire": true,
  "questionnaire_group_id": "a7c2c2c2-1111-4d2c-9eb6-fdc6c7c92ef9",
  "version": 3,
  "status": "Approved",
  "published_at": "2026-01-12T11:00:00Z",
  "sections": [
    {
      "title": { "en": "Source of funds" },
      "description": null,
      "items": [
        {
          "uuid": "4f1d5e2c-aaaa-4d2c-9eb6-fdc6c7c92ef9",
          "value": "q_source_of_funds",
          "element_type": "single_choice",
          "title": { "en": "What is your main source of funds?" },
          "options": [
            { "value": "salary", "label": { "en": "Salary" } },
            { "value": "business", "label": { "en": "Business income" } },
            { "value": "investments", "label": { "en": "Investments" } }
          ],
          "answer": { "value": "salary" }
        }
      ]
    }
  ],
  "node_id": "first_questionnaire"
}

Age estimation

Returned by the standalone Age Estimation API (POST /v2/age-estimation/). The response reuses Liveness check’s shape under an age_estimation envelope (with age_estimation field populated). Source: apis/serializers/age_estimation.py:50-55 (AgeEstimationResponseSerializer) wrapping face/serializers/face.py:216-298 (LivenessV2Serializer).
FieldTypeNullableDescriptionExample
request_idstring (UUID)NoStable identifier for the request."3b1f1e2c-…"
age_estimationobjectNoFull Liveness object — see Liveness check for fields. The age_estimation field on that object carries the estimated age.{ … }
vendor_datastringYesEchoed vendor_data from the request.null
metadataobjectYesEchoed metadata from the request.null
created_atstring (ISO 8601)NoServer-side request timestamp."2026-05-17T10:22:13Z"
{
  "request_id": "3b1f1e2c-7777-4d2c-9eb6-fdc6c7c92ef9",
  "age_estimation": {
    "status": "Approved",
    "method": "passive",
    "score": 94.10,
    "reference_image": "https://didit-storage.s3.amazonaws.com/.../reference.jpg?X-Amz-Signature=...",
    "video_url": null,
    "age_estimation": 28.7,
    "matches": [],
    "warnings": [],
    "face_quality": 89.22,
    "face_luminance": 51.40
  },
  "vendor_data": null,
  "metadata": null,
  "created_at": "2026-05-17T10:22:13Z"
}

Biometric authentication

Biometric authentication runs the same Liveness + Face Match pipeline used in standard KYC, but configured to compare the captured face against an existing user’s reference image instead of a freshly-OCR’d document portrait. There is no dedicated serializer — the decision payload returns the standard Liveness check and Face match objects under liveness_checks[] and face_matches[]. The session is identified as biometric-auth via workflow_type = "BIOMETRIC_AUTHENTICATION" (see sessions/serializers/session.py:574).
FieldTypeNullableDescriptionExample
liveness_checksarray of Liveness checkNoLiveness result for the authentication attempt.[ { "status": "Approved", … } ]
face_matchesarray of Face matchNoMatch result against the enrolled reference. source_image_session_id points at the session that supplied the reference.[ { "status": "Approved", "source_image_session_id": "…", … } ]
statusstringNoTop-level session status (see Status enum)."Approved"
{
  "session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
  "status": "Approved",
  "workflow_type": "BIOMETRIC_AUTHENTICATION",
  "liveness_checks": [
    {
      "status": "Approved",
      "method": "passive",
      "score": 95.10,
      "reference_image": "https://didit-storage.s3.amazonaws.com/.../reference.jpg?X-Amz-Signature=...",
      "video_url": null,
      "age_estimation": null,
      "matches": [],
      "face_quality": 91.20,
      "face_luminance": 53.10,
      "node_id": "biometric_auth_liveness",
      "warnings": []
    }
  ],
  "face_matches": [
    {
      "status": "Approved",
      "score": 98.42,
      "source_image_session_id": "a3f2a6f1-1c1c-4eec-8b69-1c1c2f3a2c7f",
      "source_image": "https://didit-storage.s3.amazonaws.com/.../source.jpg?X-Amz-Signature=...",
      "target_image": "https://didit-storage.s3.amazonaws.com/.../target.jpg?X-Amz-Signature=...",
      "node_id": "biometric_auth_face_match",
      "warnings": []
    }
  ]
}

KYB registry

Returned per registry-confirmed company in a KYB workflow. Appears as registry_checks[] in the V3 business-session decision payload. Source: kyb/serializers/kyb.py:939-964 (RegistryCheckV3Serializer).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
node_idstring | nullYesWorkflow node identifier (V3)."first_registry"
data_resolvedbooleanNotrue when the registry fetch has completed (or is_from_registry is false, meaning the data was entered manually).true
companyobjectNoFull company payload — see Company object below.{ … }
ownership_structureobjectYesProvider-supplied ownership graph (nodes, edges, percentages). Free-form JSON.{ "nodes": [...], "edges": [...] }
warningsarrayNoSee Warning object.[]

Company object

From kyb/serializers/kyb.py:220-321 (KYBCompanyResponseSerializer).
FieldTypeNullableDescription
uuidstring (UUID)NoInternal company identifier.
node_idstring | nullYesWorkflow node identifier.
statusstringNoFeature status (FeatureStatusChoices).
registry_statusstringYesCompany status from the registry (active, dissolved, …).
data_resolvedbooleanNoSame definition as on the parent object.
company_namestringYesRegistered company name.
registration_numberstringYesRegistry identifier.
country_codestring (ISO 3166-1 alpha-2)YesCountry of incorporation.
regionstringYesISO 3166-2 subdivision when applicable (e.g. US-CA).
company_typestringYesLegal form (LLC, SL, …).
incorporation_datestring (YYYY-MM-DD)YesDate of incorporation.
registered_addressstringYesRegistered legal address.
tax_numberstringYesTax / VAT identifier.
risk_levelstringYesProvider-supplied risk rating.
verification_statusstringYesInternal verification status enum.
is_from_registrybooleanNotrue when sourced from the registry (vs. manual entry).
fetch_statusstringYespending, resolved, failed.
alternative_namesstringYesComma-separated alternative trade names.
nature_of_businessstringYesFree-text business activity description.
registered_capitalstringYesRegistered capital as a human-readable string.
registered_capital_amountstring (decimal)YesParsed registered capital amount.
registered_capital_currencystring (ISO 4217)YesCurrency code.
websitestring (URL)YesCompany website.
emailstringYesPublic contact email.
phonestringYesPublic contact phone.
legal_entity_identifierstringYesLEI when available.
location_of_registrationstringYesRegistry office / region.
financial_summaryobjectYesSnapshot of latest financial highlights when supplied by the registry.
officersarray of objectsNoB2C-safe officer list: { uuid, name, designation, role, nationality, is_active, kyc_status, kyc_session_url }.
beneficial_ownersarray of objectsNoB2C-safe UBO list: { uuid, name, first_name, last_name, entity_type, roles, ownership_min_shares, ownership_max_shares, is_active, kyc_status, kyc_session_url, effective_ownership_percent }.
addressesarray of objectsYesPer-address detail from the registry.
industriesarray of objectsYesSIC/NAICS-style classifications.
accountsarray of objectsYesFiled accounts metadata.
registry_dataobjectYesRaw registry payload (vendor-specific).
user_provided_dataobjectYesSnapshot of user-edited fields.
confirmed_by_user_atstring (ISO 8601)YesTimestamp the user confirmed the extracted data.
last_console_edit_atstring (ISO 8601)YesTimestamp of the last console edit.
is_editablebooleanNotrue while registry-sourced data can still be edited by the end user.
{
  "status": "Approved",
  "node_id": "first_registry",
  "data_resolved": true,
  "company": {
    "uuid": "b1f1e2c2-9999-4d2c-9eb6-fdc6c7c92ef9",
    "node_id": "first_registry",
    "status": "Approved",
    "registry_status": "active",
    "data_resolved": true,
    "company_name": "Sante Clinics SL",
    "registration_number": "B12345678",
    "country_code": "ES",
    "region": null,
    "company_type": "SL",
    "incorporation_date": "2018-03-22",
    "registered_address": "Calle Mayor 1, 28001 Madrid, Spain",
    "tax_number": "B12345678",
    "risk_level": "low",
    "verification_status": "verified",
    "is_from_registry": true,
    "fetch_status": "resolved",
    "alternative_names": "Sante Clinics",
    "nature_of_business": "Medical clinic operations",
    "registered_capital": "EUR 50,000",
    "registered_capital_amount": "50000.00",
    "registered_capital_currency": "EUR",
    "website": "https://santeclinics.com",
    "email": "info@santeclinics.com",
    "phone": "+34911223344",
    "legal_entity_identifier": null,
    "location_of_registration": "Registro Mercantil de Madrid",
    "financial_summary": null,
    "officers": [
      {
        "uuid": "c1f1e2c2-aaaa-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "designation": "Administrador único",
        "role": "Director",
        "nationality": "ESP",
        "is_active": true,
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…"
      }
    ],
    "beneficial_owners": [
      {
        "uuid": "d1f1e2c2-bbbb-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "first_name": "María",
        "last_name": "García López",
        "entity_type": "person",
        "roles": ["UBO"],
        "ownership_min_shares": "75.00",
        "ownership_max_shares": "75.00",
        "is_active": true,
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…",
        "effective_ownership_percent": 75.0
      }
    ],
    "addresses": [],
    "industries": [],
    "accounts": [],
    "registry_data": {},
    "user_provided_data": {},
    "confirmed_by_user_at": "2026-05-17T10:11:02Z",
    "last_console_edit_at": null,
    "is_editable": false
  },
  "ownership_structure": null,
  "warnings": []
}

KYB document

Returned per node that collects KYB supporting documents. Appears as document_verifications[] in the V3 business-session decision payload — one entry per node_id, with items[] listing each uploaded document. Source: kyb/serializers/kyb.py:1053-1068 (DocumentVerificationV3Serializer); each item follows kyb/serializers/kyb.py:811-851 (KYBDocumentResponseSerializer).
FieldTypeNullableDescriptionExample
statusstringNoAggregate status across this node’s documents (approved only when every pipeline document is approved; declined if any is declined; in_review otherwise; not_finished while pending). See Status enum."Approved"
node_idstring | nullYesWorkflow node identifier (V3)."first_kyb_documents"
itemsarray of KYB document item objectsNoOne entry per uploaded or requested document.[…]
groupsobjectNoPer-document-group counts: { <group_name>: { total, approved, pending, declined, in_review, other, missing } }.{ "incorporation_certificate": { "total": 1, "approved": 1, "pending": 0, "declined": 0, "in_review": 0, "other": 0, "missing": 0 } }
required_groupsarray of stringsNoDocument groups required by the workflow configuration.["incorporation_certificate", "shareholder_register"]
warningsarrayNoSee Warning object.[]

KYB document item object

FieldTypeNullableDescription
uuidstring (UUID)NoInternal document identifier.
document_typestringYesHigh-level group (incorporation_certificate, shareholder_register, …).
document_subtypestringYesProvider-specific subtype.
document_groupstringYesMirror of document_type (alias kept for clarity).
file_urlstring (URL)YesPresigned URL to the cleaned file.
original_filenamestringYesFilename as uploaded.
file_sizeintegerYesFile size in bytes.
statusstringNoPer-document status (FeatureStatusChoices).
created_atstring (ISO 8601)NoUpload timestamp.
cross_check_resultobjectYesCross-check verdict against registry / other docs.
document_metadataobjectYesSame filtered metadata shape as POA’s document_metadata.
descriptionstringYesReviewer- or system-supplied description.
is_requestedbooleanNotrue when the workflow expected this document.
ocr_dataobjectYesOCR-extracted fields when available.
is_console_uploadbooleanNotrue when the document was uploaded by a console reviewer (excluded from the aggregate verdict).
is_confirmedbooleanNotrue when the reviewer has explicitly confirmed the document.
{
  "status": "Approved",
  "node_id": "first_kyb_documents",
  "items": [
    {
      "uuid": "e1f1e2c2-cccc-4d2c-9eb6-fdc6c7c92ef9",
      "document_type": "incorporation_certificate",
      "document_subtype": "registro_mercantil_extract",
      "document_group": "incorporation_certificate",
      "file_url": "https://didit-storage.s3.amazonaws.com/.../incorporation.pdf?X-Amz-Signature=...",
      "original_filename": "incorporation_certificate.pdf",
      "file_size": 256412,
      "status": "Approved",
      "created_at": "2026-05-17T10:08:00Z",
      "cross_check_result": { "matches_registry_name": true, "matches_registration_number": true },
      "document_metadata": {
        "file_size": 256412,
        "content_type": "application/pdf",
        "is_signed": true,
        "is_tampered": false
      },
      "description": null,
      "is_requested": true,
      "ocr_data": { "company_name": "Sante Clinics SL", "registration_number": "B12345678" },
      "is_console_upload": false,
      "is_confirmed": true
    }
  ],
  "groups": {
    "incorporation_certificate": { "total": 1, "approved": 1, "pending": 0, "declined": 0, "in_review": 0, "other": 0, "missing": 0 }
  },
  "required_groups": ["incorporation_certificate", "shareholder_register"],
  "warnings": []
}

KYB key person

Returned per Key People node in a KYB workflow. Appears as key_people_checks[] in the V3 business-session decision payload. Source: kyb/serializers/kyb.py:967-1050 (KeyPeopleCheckV3Serializer).
FieldTypeNullableDescriptionExample
statusstringNoSee Status enum."Approved"
node_idstring | nullYesWorkflow node identifier (V3)."first_key_people"
registryobjectNo{ officers[], beneficial_owners[] } extracted from the registry. Officers follow KYBPersonResponseSerializer (kyb/serializers/kyb.py:533-645); beneficial owners follow KYBBeneficialOwnerResponseSerializer (kyb/serializers/kyb.py:648-788). Both include per-party KYC enrichment (kyc_status, kyc_session_url, kyc_session_id, verification_workflow_type, verification_workflow_id, verification_workflow_label, verification_workflow_features, didit_internal_id, kyc_document_type, kyc_nationality, kyc_liveness_passed, kyc_verified_at, kyc_aml_categories, kyc_notification_sent_at).{ "officers": [...], "beneficial_owners": [...] }
submittedobjectNo{ parties[] } — entries the business confirmed / submitted via the key-people flow (BusinessParty rows with source=USER). Each party serialized via BusinessPartySubmissionResponseSerializer.{ "parties": [...] }
ubo_kyc_summaryobjectYesCounts across active UBOs with linked KYC: { total, approved, flagged, pending }. null when no active UBOs have KYC linked.{ "total": 2, "approved": 2, "flagged": 0, "pending": 0 }
warningsarrayNoSee Warning object.[]
{
  "status": "Approved",
  "node_id": "first_key_people",
  "registry": {
    "officers": [
      {
        "uuid": "c1f1e2c2-aaaa-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "designation": "Administrador único",
        "role": "Director",
        "nationality": "ESP",
        "appointment_date": "2018-03-22",
        "termination_date": null,
        "is_active": true,
        "address": "Calle Mayor 1, 28001 Madrid",
        "aml_status": "Approved",
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…",
        "kyc_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
        "verification_workflow_type": "STANDARD_KYC",
        "verification_workflow_id": "11111111-1111-1111-1111-111111111111",
        "verification_workflow_label": "KYB officer KYC",
        "verification_workflow_features": [
          { "feature": "ID_VERIFICATION", "status": "Approved" },
          { "feature": "LIVENESS", "status": "Approved" },
          { "feature": "FACE_MATCH", "status": "Approved" }
        ],
        "didit_internal_id": "user-12345",
        "kyc_document_type": "Passport",
        "kyc_nationality": "ESP",
        "kyc_liveness_passed": true,
        "kyc_verified_at": "2026-05-17T10:10:11Z",
        "kyc_aml_categories": [],
        "kyc_notification_sent_at": "2026-05-15T08:00:00Z"
      }
    ],
    "beneficial_owners": []
  },
  "submitted": {
    "parties": [
      {
        "uuid": "d1f1e2c2-bbbb-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "roles": ["UBO"],
        "ownership_percent": 75.0,
        "source": "USER",
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…"
      }
    ]
  },
  "ubo_kyc_summary": { "total": 1, "approved": 1, "flagged": 0, "pending": 0 },
  "warnings": []
}

Status enum reference

Every report object’s status field is one of these values. Source: common/config/choices.py:106-117 (StatusChoices).
ValueMeaning
Not StartedThe feature has been provisioned for the session but the user has not begun it.
In ProgressThe user has started the feature; result not yet finalized.
ApprovedThe feature passed all checks.
DeclinedThe feature failed at least one hard check (see warnings[] with log_type: "error").
In ReviewThe feature triggered soft-fail signals and is awaiting manual review (see warnings[] with log_type: "warning").
ExpiredThe session expired before the feature could be completed.
AbandonedThe user left the flow without completing the feature.
Kyc ExpiredThe KYC’s validity window elapsed (used in re-verification flows).
ResubmittedThe user resubmitted after a prior decline; this record is superseded by a newer one.
Awaiting UserThe system is waiting on a user-side action (e.g. OTP entry).
The status value space is shared across every per-feature report and across the parent session. Workflow-level outcomes can use a subset (FeatureStatusChoices) but every value above is valid here.