> ## 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.

# Datenmodelle in der Didit API-Referenz

> Didit JSON-Schemas für alle Berichtsobjekte: NFC, ID, Liveness, Gesichtsabgleich, AML, IP, Adresse, Telefon, E-Mail, KYB, Dokumente.

## Übersicht

Jedes Berichtsobjekt pro Funktion folgt der V3-Serializer-Struktur, die in `service-didit-verification` definiert ist. Dasselbe Objekt erscheint an drei Stellen, daher ist das Schema hier die einzige maßgebliche Quelle für alle drei:

* `GET /v3/session/{sessionId}/decision/`: Jede Funktion wird als Array mit einem Pluralnamen zurückgegeben (`id_verifications[]`, `nfc_verifications[]`, `liveness_checks[]`, `face_matches[]`, `poa_verifications[]`, `phone_verifications[]`, `email_verifications[]`, `aml_screenings[]`, `ip_analyses[]`, `database_validations[]`, `questionnaire_responses[]`, `signatures[]`, `bank_verifications[]` (siehe [Bankverifizierungsmethoden](https://docs.didit.me/de/core-technology/bank-verification/verification-methods.md#methode-im-ergebnis-auslesen)) sowie die entsprechenden KYB-Arrays `registry_checks[]`, `document_verifications[]`, `key_people_checks[]`).
* Webhook-Payloads (`status.updated`, `data.updated`): gleiche Struktur innerhalb der `decision`-Hülle.
* Eigenständige APIs: Antworten mit einem einzelnen Objekt (Gesichtssuche, Altersschätzung, biometrische Authentifizierung) verwenden dieselben Felder.

> [!NOTE]
>
> V3 hat Multi-Instance-Workflows eingeführt: Jedes Funktionsobjekt enthält eine `node_id`, die den Bericht dem Workflow-Graph-Knoten zuordnet, der ihn erzeugt hat. V2-Endpoints (im Singular `kyc`, `face`, `aml` usw.) bleiben abwärtskompatibel, geben aber nur die erste Instanz zurück.

## Gemeinsame Felder

Jedes Berichtsobjekt enthält die folgenden Felder:

| Feld | Typ | Beschreibung |
| - | - | - |
| `status` | string | Lebenszyklus-Status auf Funktionsebene, einer der Werte aus dem [Status-Enum](#status-aufzählung). Quelle: `common/config/choices.py:FeatureStatusChoices` (Zeilen 343-348). Der `status` der übergeordneten Sitzung auf oberster Ebene verwendet das umfassendere Sitzungs-Enum (`StatusChoices`, Zeilen 106-117). |
| `node_id` | string \| null | Kennung des Workflow-Graph-Knotens. Wird für Multi-Instance-Workflows in V3 befüllt; `null` bei Legacy-Sitzungen mit einer einzelnen Funktion. |
| `warnings` | Array aus [Warnungsobjekten](#warnungsobjekt) | Risikosignale, die auf diese Funktion und `node_id` gefiltert sind. Zurückgegeben von `Session.get_logs(...)` (`sessions/models/session.py:1611`). |

Medienfelder (`portrait_image`, `front_image`, `document_file`, …) sind vorsignierte URLs mit begrenzter Gültigkeitsdauer. Laden Sie diese zeitnah herunter, statt die URL dauerhaft zu speichern. Beispiele zeigen sie als `https://<media-host>/...`.

## Warnungsobjekt

Wird in jedem `warnings[]`-Array zurückgegeben. Schema aus `logs/serializers/log.py:8-65` (`LogV3Serializer`).

| Feld | Typ | Nullbar | Beschreibung | Beispiel |
| - | - | - | - | - |
| `feature` | string (Enum) | Nein | Welche Funktion die Warnung ausgelöst hat. Werte aus `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"` |
| `risk` | string | Nein | Stabiler Risikocode (z. B. `DOCUMENT_EXPIRED`, `LOW_LIVENESS_SCORE`). Werte aus `logs/choices.py:RiskChoices`. Dient als Schlüssel in den Beschreibungstabellen. | `"DOCUMENT_EXPIRED"` |
| `additional_data` | object \| null | Ja | Risikospezifischer Kontext (z. B. Score-Schwellenwerte, übereinstimmende Felder). Die Struktur variiert je nach Risikocode. | `{ "score": 42.1, "threshold": 70 }` |
| `log_type` | string (Enum) | Nein | Einer von `error`, `warning`, `information`. Aus `LogTypeChoices` (`common/config/choices.py:207-210`). | `"error"` |
| `short_description` | string | Nein | Lesbare Bezeichnung des Risikos. Aus `logs/choices.py:RISK_SHORT_DESCRIPTIONS`. | `"Document expired"` |
| `long_description` | string | Nein | Längere, lesbare Erklärung, geeignet für Oberflächen, die Endbenutzern angezeigt werden. Aus `logs/choices.py:RISK_LONG_DESCRIPTIONS`. | `"The document's expiration date has passed, rendering it no longer valid for use."` |
| `node_id` | string \| null | Ja | Workflow-Graph-Knoten, dem die Warnung zugeordnet wurde. `null` bei Legacy-V2-Logs ohne `node_id`. | `"first_id_verification"` |

```json theme={null}
{
  "feature": "ID_VERIFICATION",
  "risk": "DOCUMENT_EXPIRED",
  "additional_data": null,
  "log_type": "error",
  "short_description": "Document expired",
  "long_description": "The document's expiration date has passed, rendering it no longer valid for use.",
  "node_id": "first_id_verification"
}
```

## Berichtsobjekte

Die übrigen Abschnitte behandeln jedes funktionsspezifische Berichtsobjekt. Die Überschriften der dritten Ebene (H3) sind bewusst stabil gehalten, damit andere Dokumente direkt darauf verlinken können.

### Ausweisverifizierung

Wird für jedes KYC-/Ausweisdokument zurückgegeben, das ein Benutzer einreicht. Erscheint als `id_verifications[]` in `GET /v3/session/{sessionId}/decision/` und innerhalb des Felds `kyc` bei V2-Antworten. Quelle: `kyc/serializers/kyc.py:383-414` (`IDVerificationV3Serializer`, erweitert `IDVerificationV2Serializer` aus `kyc/serializers/kyc.py:320-380`).

| Feld | Typ | Nullwert zulässig | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `document_type` | string | Ja | Für Menschen lesbare Dokumentklasse (`Passport`, `Identity Card`, `Driver's License`, `Residence Permit`, `Health Insurance Card`, `Tax Card`, `Social Security Card`, `Work Permit`, `Visa`, `Public Service Card`, `Birth Certificate`, `Firearm License`, `Other`). Quelle: `DOC_TYPE_MAPPING` (`common/config/choices.py:1275-1289`). | `"Passport"` |
| `document_subtype` | string | Ja | Code des Dokumentuntertyps aus der Dokumentenregistrierung von Didit, gefiltert auf das, was die Dokumenteneinstellungen des Workflows zulassen. Regionsspezifische Dokumente enthalten die Region. Vollständige Codeliste: [Dokumentuntertypen](https://docs.didit.me/de/core-technology/id-verification/document-subtypes-id-verification.md). | `"QUEENSLAND_DRIVER_LICENSE_GENERIC"` |
| `document_number` | string | Ja | Per OCR ausgelesene Dokumentnummer. | `"AB1234567"` |
| `personal_number` | string | Ja | Per OCR ausgelesene persönliche bzw. nationale Kennung. | `"99999999R"` |
| `portrait_image` | string (URL) | Ja | Vorsignierte URL zum Gesichtsausschnitt. | `"https://<media-host>/.../portrait.jpg?..."` |
| `front_image` | string (URL) | Ja | Vorsignierte URL zur bereinigten Vorderseite des Dokuments. | `"https://<media-host>/.../front.jpg?..."` |
| `front_video` | string (URL) | Ja | Vorsignierte URL zum Video der Vorderseitenaufnahme (sofern verfügbar). | `"https://<media-host>/.../front.mp4?..."` |
| `back_image` | string (URL) | Ja | Vorsignierte URL zur bereinigten Rückseite des Dokuments. | `"https://<media-host>/.../back.jpg?..."` |
| `back_video` | string (URL) | Ja | Vorsignierte URL zum Video der Rückseitenaufnahme. | `null` |
| `full_front_image` | string (URL) | Ja | Nicht zugeschnittene (Vollbild-)Aufnahme der Vorderseite. | `"https://<media-host>/.../full_front.jpg?..."` |
| `full_back_image` | string (URL) | Ja | Nicht zugeschnittene (Vollbild-)Aufnahme der Rückseite. | `null` |
| `front_image_camera_front` | string (URL) | Ja | Aufnahme der Frontkamera, die zur gleichen Zeit wie die Vorderseite des Dokuments entstanden ist. | `null` |
| `back_image_camera_front` | string (URL) | Ja | Aufnahme der Frontkamera, die zur gleichen Zeit wie die Rückseite des Dokuments entstanden ist. | `null` |
| `front_image_camera_front_face_match_score` | float (0-100) | Ja | Ähnlichkeit zwischen dem Dokumentporträt und der Aufnahme der Frontkamera. | `null` |
| `back_image_camera_front_face_match_score` | float (0-100) | Ja | Wie oben, jedoch für die Aufnahme der Rückseite. | `null` |
| `document_selfie_face_matches` | array | Ja | Frühere Sitzungen oder Einträge der Gesichts-Sperrliste, die zum Selfie passen, das während der Dokumentaufnahme entstanden ist. Gleiches Eintragsformat wie `liveness_checks[].matches`. `null`, wenn die Suche nicht ausgeführt wurde, `[]`, wenn nichts übereinstimmte. | `null` |
| `front_image_quality_score` | object | Ja | Qualitätsmetriken für das Vorderseitenbild: Werte von 0-100 (`focus_score`, `brightness_score`, `resolution_score`, `overall_score`), außerdem `brightness_issue` (`ok`, `too_dark`, `too_bright`) und `is_document_fully_visible` (Boolean). | `{ "focus_score": 91.0, "overall_score": 88.5 }` |
| `back_image_quality_score` | object | Ja | Gleiche Struktur wie `front_image_quality_score`. | `null` |
| `date_of_birth` | string (YYYY-MM-DD) | Ja | Per OCR ausgelesenes Geburtsdatum. | `"1990-05-12"` |
| `age` | integer | Ja | Berechnetes Alter in Jahren zum Zeitpunkt der Auslesung. | `35` |
| `expiration_date` | string (YYYY-MM-DD) | Ja | Ablaufdatum des Dokuments. | `"2032-05-11"` |
| `date_of_issue` | string (YYYY-MM-DD) | Ja | Ausstellungsdatum des Dokuments. | `"2022-05-11"` |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Ja | Ländercode des Ausstellungslands. | `"ESP"` |
| `issuing_state_name` | string | Ja | Lokalisierter Name des Ausstellungslands. | `"Spain"` |
| `first_name` | string | Ja | Per OCR ausgelesene Vornamen. | `"María"` |
| `last_name` | string | Ja | Per OCR ausgelesene Nachnamen. | `"García López"` |
| `full_name` | string | Ja | Vollständiger normalisierter Name (vom Anbieter bereitgestellt). | `"María García López"` |
| `gender` | string | Ja | `M`, `F` oder ein anderer vom Anbieter bereitgestellter Wert. | `"F"` |
| `address` | string | Ja | Unverarbeitete, per OCR ausgelesene Adresszeile. | `"Calle Mayor 1, 28001 Madrid"` |
| `formatted_address` | string | Ja | Geokodierte bzw. formatierte Adresse (sofern auswertbar). | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `parsed_address` | object | Ja | Strukturierte, geokodierte Adresse: `street_1`, `street_2`, `city`, `region`, `country`, `postal_code`, `address_type`, `formatted_address`, `document_location` (`{latitude, longitude}`), `raw_results`, `is_best_match`. Quelle: `kyc/utils/address.py:147-197`. | `{ "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" }` |
| `place_of_birth` | string | Ja | Per OCR ausgelesener Geburtsort. | `"Madrid"` |
| `marital_status` | string | Ja | Sofern auslesbar. | `null` |
| `nationality` | string (ISO 3166-1 alpha-3) | Ja | Per OCR ausgelesene Staatsangehörigkeit. | `"ESP"` |
| `extra_fields` | object | Ja | Dokumenttypspezifische Felder, die vom kanonischen Schema nicht abgedeckt werden (z. B. Führerscheinklassen). | `{ "DL Class": "B" }` |
| `mrz` | object | Ja | Geparste MRZ-Felder, sofern vorhanden (`document_number`, `birth_date`, `expiry_date`, `surname`, `given_names`, …). | `{ "document_number": "AB1234567", "surname": "GARCIA", "given_names": "MARIA" }` |
| `extra_files` | array of strings (URL) | Nein | Vorsignierte URLs zu allen zusätzlich hochgeladenen Dateien. | `[]` |
| `matches` | array of objects | Nein | Dokumentübereinstimmungen über Sitzungen hinweg. Jedes Element: `{ session_id, session_number, vendor_data, verification_date, user_details: { name, document_type, document_number }, status, is_blocklisted, api_service, front_image_url }`. `front_image_url` ist vorsigniert. | `[]` |
| `verification_method` | string | Nein | Welche [Ausweisverifizierungsmethode](https://docs.didit.me/de/core-technology/id-verification/verification-methods.md) diese Zeile erzeugt hat: `document`, `id_lookup` oder `wallet`. Immer `document` bei einem fotografierten Dokument, einschließlich aller Sitzungen, die vor der Einführung der anderen Methoden erstellt wurden. | `"id_lookup"` |
| `assurance` | string | Nein | Aus `verification_method` abgeleitete Assurance-Stufe: `documentary`, `data_match` oder `cryptographic`. | `"data_match"` |
| `wallet_provider` | string \| null | Ja | Katalog-Wallet-ID, wenn eine Wallet diese Zeile erzeugt hat (`mitid`, `bankid_se`, `itsme`, ...). Andernfalls `null`. | `"mitid"` |
| `fallback_from` | object \| null | Ja | Grund, warum eine Nicht-Dokument-Methode den ID-Schritt beendet hat: `{ method, reason, action }`. Wird gesetzt, wenn eine Suche oder eine Wallet-Anmeldung fehlgeschlagen ist: in der abgelehnten Zeile, wenn der Schalter des Landes auf `decline` stand (`action: "decline"`), und bei der Dokumentenverifizierung, mit der der Benutzer fortfährt, wenn der Schalter des Landes auf `fallback_to_document` stand (`action: "fallback_to_document"`). `null`, wenn kein früherer Fehler einer Nicht-Dokument-Methode erfasst ist. | `{ "method": "id_lookup", "reason": "no_match", "action": "decline" }` |
| `id_lookup` | object \| null | Ja | Quellennachweis, nur vorhanden, wenn `verification_method` `id_lookup` ist: `source` (die exakt abgefragte Quelle, in den meisten Ländern ein staatliches Register, in einigen eine Auskunftei- oder Melderegisterdatei), `checked_at`, `attempts`, `max_attempts`, `outcome` (`match`, `partial_match`, `no_match`, `provider_error`, `format_rejected`), `comparison[]` (`{ field, label, provided, record, result }`; `field` ist einer von `identification_number`, `full_name`, `date_of_birth`, `address`, und `result` ist `match`, `partial` oder `no_match`; frühere Versionen können eine Zeile `provider` mit `error` enthalten), `source_errors[]` (aktuelles Staging: separate Quelldiagnosen; Ausrollung in der Produktion bestätigen), `registry_portrait` (vorsignierte URL, nur für Quellen, die eine solche liefern) und `face_match_score`. | siehe unten |
| `wallet_verification` | object \| null | Ja | Credential-Nachweis, nur vorhanden, wenn `verification_method` `wallet` ist: `provider`, `provider_name`, `issuing_authority`, `issuing_country`, `credential_type`, `level_of_assurance` (`low`, `substantial`, `high`), `verified_at`, `signature_valid`, `attributes` (was die Wallet geteilt hat), `portrait` (vorsignierte URL, wenn die Wallet ein Porträt teilt) und `face_match_score`. | siehe unten |
| `document_liveness` | object \| null | Ja | Dokument-Liveness-Werte je Betrugstyp (`portrait_replace`, `printed_copy`, `screen_replay`), unabhängig davon, ob eine Warnung ausgelöst wurde. Je Eintrag: `score` (0-100, höher = wahrscheinlicher echt; der niedrigste Wert, also der von der Entscheidung verwendete Wert), `front`, `back`, `decline_threshold`, `review_threshold`, `bucket` (`approve`, `review`, `decline` oder `null`). Schwellenwerte und Bucket werden zum Zeitpunkt der Bewertung gespeichert. Alle drei sind `null`, wenn historische Bewertungsnachweise nicht verfügbar sind, während gespeicherte Werte sichtbar bleiben. `null`, wenn die Prüfung nicht ausgeführt wurde. Siehe [Dokument-Liveness-Werte](https://docs.didit.me/de/core-technology/id-verification/report-id-verification.md#dokument-liveness-scores). Nur V3. | `{ "portrait_replace": { "score": 96.46, "bucket": "approve" } }` |
| `node_id` | string \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_id_verification"` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |
| `region` | string | Ja | Region oder Bundesstaat des Ausstellungslandes, sofern das Dokument eine solche angibt. | `"CA"` |
| `extracted_data` | object | Ja | Momentaufnahme der aus dem Dokument extrahierten Daten, die der Person zur Prüfung angezeigt wurde, neben den bestätigten Werten, damit Sie beide vergleichen können. `null`, wenn die Person nicht zur Prüfung aufgefordert wurde. | |
| `barcodes` | Array von Objekten | Nein | Aus den Barcodes des Dokuments gelesene Daten, ein Eintrag je Barcode mit `type`, `position`, `data`, `data_raw` und `side`. `[]`, wenn keine vorhanden sind. | `[]` |

```json theme={null}
{
  "status": "Approved",
  "document_type": "Passport",
  "document_subtype": "PASSPORT_GENERIC",
  "document_number": "AB1234567",
  "personal_number": "99999999R",
  "portrait_image": "https://<media-host>/.../portrait.jpg?signature=...",
  "front_image": "https://<media-host>/.../front.jpg?signature=...",
  "front_video": null,
  "back_image": "https://<media-host>/.../back.jpg?signature=...",
  "back_video": null,
  "full_front_image": "https://<media-host>/.../full_front.jpg?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": {
    "focus_score": 91.0,
    "brightness_score": 88.0,
    "brightness_issue": "ok",
    "is_document_fully_visible": true,
    "resolution_score": 95.0,
    "overall_score": 88.5
  },
  "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_1": "Calle Mayor 1", "street_2": null, "city": "Madrid", "region": "Madrid", "postal_code": "28001", "country": "ES", "address_type": "Calle" },
  "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",
  "verification_method": "document",
  "assurance": "documentary",
  "wallet_provider": null,
  "fallback_from": null,
  "id_lookup": null,
  "wallet_verification": null,
  "document_liveness": {
    "portrait_replace": {
      "score": 96.46,
      "front": 96.46,
      "back": 98.2,
      "decline_threshold": 35,
      "review_threshold": 70,
      "bucket": "approve"
    },
    "printed_copy": {
      "score": 91.2,
      "front": 91.2,
      "back": 93.7,
      "decline_threshold": 35,
      "review_threshold": 77,
      "bucket": "approve"
    },
    "screen_replay": {
      "score": 99.9,
      "front": 99.9,
      "back": 99.5,
      "decline_threshold": 30,
      "review_threshold": 70,
      "bucket": "approve"
    }
  },
  "warnings": []
}
```

Dasselbe Objekt bei einer Nicht-Dokument-Methode. Nur die methodenspezifischen Schlüssel ändern sich: Alles, was ein Dokumentenlesevorgang ausfüllt, wird stattdessen aus dem Registereintrag oder den Wallet-Attributen befüllt, und die nicht zutreffenden Schlüssel sind `null`.

```json theme={null}
{
  "status": "Approved",
  "issuing_state": "ZAF",
  "first_name": "Thabo",
  "last_name": "Mokoena",
  "full_name": "Thabo Mokoena",
  "date_of_birth": "1991-06-15",
  "personal_number": "9106155043088",
  "node_id": "first_id_verification",
  "verification_method": "id_lookup",
  "assurance": "data_match",
  "wallet_provider": null,
  "fallback_from": null,
  "id_lookup": {
    "source": "Department of Home Affairs",
    "checked_at": "2026-09-04T09:12:44Z",
    "attempts": 1,
    "max_attempts": 2,
    "outcome": "match",
    "comparison": [
      { "field": "identification_number", "label": "ID number", "provided": "9106155043088", "record": "9106155043088", "result": "match" },
      { "field": "full_name", "label": "Full name", "provided": "Thabo Mokoena", "record": "Thabo Mokoena", "result": "match" },
      { "field": "date_of_birth", "label": "Date of birth", "provided": "1991-06-15", "record": "1991-06-15", "result": "match" }
    ],
    "registry_portrait": "https://<media-host>/.../registry_portrait.jpg?signature=...",
    "face_match_score": 96.4
  },
  "wallet_verification": null,
  "warnings": []
}
```

```json theme={null}
{
  "status": "Approved",
  "issuing_state": "DNK",
  "first_name": "Freja",
  "last_name": "Nielsen",
  "full_name": "Freja Nielsen",
  "date_of_birth": "1988-03-02",
  "node_id": "first_id_verification",
  "verification_method": "wallet",
  "assurance": "cryptographic",
  "wallet_provider": "mitid",
  "fallback_from": null,
  "id_lookup": null,
  "wallet_verification": {
    "provider": "mitid",
    "provider_name": "MitID",
    "issuing_authority": "Danish Agency for Digital Government",
    "issuing_country": "DNK",
    "credential_type": "person_identification",
    "level_of_assurance": "substantial",
    "verified_at": "2026-09-04T09:12:44Z",
    "signature_valid": true,
    "attributes": {
      "full_name": "Freja Nielsen",
      "date_of_birth": "1988-03-02",
      "cpr_alias": "b0f1c2d3-e4f5-4678-9abc-def012345678"
    },
    "portrait": null,
    "face_match_score": null
  },
  "warnings": []
}
```

### NFC-Verifizierung

Wird für jeden Chip-Lesevorgang gegen ein Ausweisdokument zurückgegeben: ein ICAO-9303-ePassport- oder eID-Chip oder eine über JPKI gelesene Japan My Number Card (`chip_protocol: "jpki"`). Erscheint als `nfc_verifications[]` in `GET /v3/session/{sessionId}/decision/` (eine je übergeordnetem KYC-Datensatz). Quelle: `kyc/serializers/epassport.py:121-139` (`NFCV3Serializer`, erweitert `NFCV2Serializer` bei `kyc/serializers/epassport.py:83-118`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `portrait_image` | string (URL) | Ja | Vorsignierte URL zum aus dem Chip extrahierten Gesichtsbild. | `"https://<media-host>/.../nfc_portrait.jpg?..."` |
| `signature_image` | string (URL) | Ja | Vorsignierte URL zum aus dem Chip extrahierten Unterschriftsbild (sofern auf dem Chip gespeichert). | `null` |
| `chip_data` | object | Ja | Aus den Datengruppen des Chips ausgelesene persönliche Daten, flach dargestellt (`kyc/utils/epassport.py:165-212`): `dgs` (gelesene Datengruppen), `surname`, `name`, `country`, `nationality`, `birth_date` (`YYYY-MM-DD`), `expiry_date` (`YYYY-MM-DD`), `sex` (`M`/`F`), `document_type` (MRZ-Dokumentcode), `document_number`, `optional_data`, MRZ-Prüfziffern (`birth_date_hash`, `expiry_date_hash`, `document_number_hash`, `optional_data_hash`, `final_hash`), `mrz_string`, `mrz_type` (`TD1`/`TD2`/`TD3`); außerdem `place_of_birth` und `address` (sowie `full_name` / `full_name_non_latin` bei nicht lateinischen Namen), wenn der Chip DG11 enthält. Diese Schlüssel fehlen sonst. `null`, wenn der NFC-Schritt übersprungen wurde. | `{ "document_number": "AB1234567", "name": "MARIA" }` |
| `authenticity` | object | Ja | `{ sod_integrity, dg_integrity }`; `null` bei einem JPKI-Lesevorgang. `sod_integrity` prüft, ob sich die Signatur des Document Security Object (SOD) auf eine gültige CSCA des Ausstellungslandes zurückführen lässt (und ob die DSC weder widerrufen noch abgelaufen ist). `dg_integrity` prüft, ob die Hashes jeder Datengruppe mit dem SOD übereinstimmen. Beide Werte `true` bedeuten, dass der Chip echt und unverändert ist. | `{ "sod_integrity": true, "dg_integrity": true }` |
| `certificate_summary` | object | Ja | Zusammenfassung des Zertifikats des Dokumentensignierers (`kyc/utils/epassport.py:338-348`): `issuer`, `subject`, `serial_number` (Ganzzahl), `not_valid_before`, `not_valid_after` (`YYYY-MM-DD HH:MM:SS`), außerdem ein `validation`-Objekt `{ csca_verified, dsc_revoked, dsc_expired, csca_expired }` (`kyc/views/epassport.py:86`). | `{ "issuer": "Common Name: CSCA SPAIN, Country: ES", "not_valid_after": "2031-02-18 10:21:11" }` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Identifikator (V3). | `"first_nfc"` |
| `is_nfc_skipped` | boolean | Nein | `true`, wenn dieser NFC-Schritt explizit übersprungen statt gelesen wurde; `skip_reason` nennt den Grund. | `false` |
| `skip_reason` | string | Ja | Grund für das Überspringen des Schritts, nur gesetzt, wenn `is_nfc_skipped` den Wert `true` hat. Einer von `USER_SKIPPED`, `DOCUMENT_WITHOUT_CHIP`, `CHIP_CERTIFICATE_UNAVAILABLE`, `DEVICE_WITHOUT_NFC`, `INTEGRATION_WITHOUT_NFC_ACCESS`, `MRZ_KEY_UNAVAILABLE`, `JPKI_UNAVAILABLE`; siehe [Gründe für das Überspringen](https://docs.didit.me/de/core-technology/nfc-verification/warnings-nfc-verification.md#gründe-für-das-überspringen). Das Entscheidungs-Payload enthält außerdem ein sitzungsbezogenes `nfc_skip_reason` mit derselben Taxonomie, das NFC-Schritte abdeckt, die umgangen wurden, bevor ein Bericht erstellt wurde. | `null` |
| `chip_protocol` | string | Nein | Wie der Chip gelesen wird: `icao` (ICAO-9303-ePassport- oder eID-Chip) oder `jpki` (japanische My-Number-Karte). Bei `jpki` sind `portrait_image`, `signature_image`, `chip_data`, `authenticity` und `certificate_summary` `null`. Auch bei übersprungenen Schritten gesetzt. | `"icao"` |
| `jpki` | object | Ja | Was ein Lesevorgang der My-Number-Karte belegt: `certificate_types`, `chain_valid`, `signature_valid`, `revocation_status` (`good`, `revoked` oder `unchecked`), `ca_generation`, `certificate_expires_at`, `certificates[]`, `attributes` (Name, Geburtsdatum, Geschlecht und Adresse aus dem Signaturzertifikat), `attributes_match_ocr` und `mismatched_attributes`. Enthält niemals die Zertifikate, deren Seriennummern oder die Signaturen. `null` bei ICAO-Chips, bei übersprungenen Schritten und wenn der Schritt ohne Kartenlesung abgeschlossen wurde. Siehe [JPKI-Felder](https://docs.didit.me/de/core-technology/nfc-verification/report-nfc-verification.md#jpki-felder). | `null` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "portrait_image": "https://<media-host>/.../nfc_portrait.jpg?signature=...",
  "signature_image": null,
  "chip_data": {
    "dgs": ["DG1", "DG2", "DG11"],
    "surname": "GARCIA LOPEZ",
    "name": "MARIA",
    "country": "ESP",
    "nationality": "ESP",
    "birth_date": "1990-05-12",
    "expiry_date": "2032-05-11",
    "sex": "F",
    "document_type": "P",
    "document_number": "AB1234567",
    "optional_data": "",
    "birth_date_hash": "4",
    "expiry_date_hash": "7",
    "document_number_hash": "3",
    "optional_data_hash": "",
    "final_hash": "8",
    "mrz_string": "P<ESPGARCIA<LOPEZ<<MARIA<<<<<<<<<<<<<<<<<<<<AB1234567ESP9005124F3205117<<<<<<<<<<<<<<08",
    "mrz_type": "TD3",
    "place_of_birth": "MADRID",
    "address": "CALLE MAYOR 1, MADRID"
  },
  "authenticity": { "sod_integrity": true, "dg_integrity": true },
  "certificate_summary": {
    "issuer": "Common Name: CSCA SPAIN, 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_before": "2020-11-18 10:21:11",
    "not_valid_after": "2031-02-18 10:21:11",
    "validation": {
      "csca_verified": true,
      "dsc_revoked": false,
      "dsc_expired": false,
      "csca_expired": false
    }
  },
  "node_id": "first_nfc",
  "is_nfc_skipped": false,
  "skip_reason": null,
  "chip_protocol": "icao",
  "jpki": null,
  "warnings": []
}
```

### Liveness-Prüfung

Wird pro Liveness-Sitzung zurückgegeben. Erscheint als `liveness_checks[]` in `GET /v3/session/{sessionId}/decision/`. Quelle: `face/serializers/face.py:301-320` (`LivenessV3Serializer`, erweitert `LivenessV2Serializer` unter `face/serializers/face.py:216-298`).

| Feld | Typ | Nullwerte zulässig | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `method` | string (enum) | Ja | `ACTIVE_3D`, `FLASHING` oder `PASSIVE` (`LivenessMethodChoices`, `common/config/choices.py:514-517`). Die passive Prüfung läuft, wenn Desktop-Sitzungen erlaubt sind und der Benutzer sich an einem Desktop befindet. | `"PASSIVE"` |
| `score` | float (0-100) | Ja | Liveness-Konfidenz, auf 2 Dezimalstellen gerundet. | `92.41` |
| `reference_image` | string (URL) | Ja | Vorsignierte URL zum Referenz-Gesichtsausschnitt des Benutzers. | `"https://<media-host>/.../reference.jpg?..."` |
| `video_url` | string (URL) | Ja | Vorsignierte URL zum Liveness-Video (nur im aktiven Modus). | `"https://<media-host>/.../liveness.webm?..."` |
| `age_estimation` | float | Ja | Geschätztes Alter (in Jahren) des größten Gesichts im Referenzbild. | `34.2` |
| `matches` | Array aus Objekten | Nein | Gesichtsabgleiche über Sitzungen hinweg. Jedes Element: `{ session_id, session_number, similarity_percentage, vendor_data, vendor_user_id, biometric_template_id, verification_date, user_details: { full_name, document_type, document_number }, match_image_url, status, is_blocklisted, is_allowlisted, api_service, source }`. `source` ist `session`, `imported`, `list_entry` oder `retained_template`. Eine Übereinstimmung mit aufbewahrter Vorlage hat `vendor_user_id`, `vendor_data` und `biometric_template_id`; ihre Felder zu Sitzung, Bild, Identitätsdetails, Status und API-Service sind `null`. | `[]` |
| `face_quality` | float (0-100) | Ja | Face-Quality-Wert der passiven Liveness-Prüfung (auf einen Prozentsatz normalisiert). | `87.50` |
| `face_luminance` | float (0-100) | Ja | Helligkeitswert des Gesichts der passiven Liveness-Prüfung (von 0–255 auf einen Prozentsatz normalisiert). | `54.12` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Identifikator (V3). | `"first_liveness"` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "method": "PASSIVE",
  "score": 92.41,
  "reference_image": "https://<media-host>/.../reference.jpg?signature=...",
  "video_url": null,
  "age_estimation": 34.2,
  "matches": [],
  "face_quality": 87.50,
  "face_luminance": 54.12,
  "node_id": "first_liveness",
  "warnings": []
}
```

### Gesichtsabgleich

Wird pro Gesichtsabgleich zurückgegeben (typischerweise das Liveness-Gesicht des Benutzers gegen das Dokumentenporträt). Erscheint als `face_matches[]` in `GET /v3/session/{sessionId}/decision/`. Quelle: `face/serializers/face.py:367-389` (`FaceMatchV3Serializer`, erweitert `FaceMatchV2Serializer` unter `face/serializers/face.py:323-364`).

| Feld | Typ | Nullwerte zulässig | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `score` | float (0-100) | Ja | Ähnlichkeit, auf 2 Dezimalstellen gerundet. Liefert der Anbieter nur einen `unmatched_faces[].Confidence`-Wert, wird dieser in `100 - confidence` umgerechnet. | `97.83` |
| `source_image_session_id` | string (UUID) | Ja | Die Sitzung, deren gespeichertes Porträt die Quell-(Referenz-)Aufnahme geliefert hat. Gesetzt in porträtbasierten Abläufen (biometrische Authentifizierung oder ein bei der Sitzungserstellung übergebenes Porträt). `null`, wenn die Referenz das Dokumentenporträt aus derselben Sitzung ist. | `null` |
| `source_image` | string (URL) | Ja | Vorsignierte URL zur Quell-(Referenz-)Aufnahme, in der Regel das Dokumentenporträt oder in biometrischen Authentifizierungsabläufen das gespeicherte Porträt. | `"https://<media-host>/.../source.jpg?..."` |
| `target_image` | string (URL) | Ja | Vorsignierte URL zur Zielaufnahme (das während der Liveness-Prüfung aufgenommene Live-Gesicht). | `"https://<media-host>/.../target.jpg?..."` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Identifikator (V3). | `"first_face_match"` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |
| `face_coverage` | object | Ja | Gibt an, ob `eyes`, `mouth` und `face` im aufgenommenen Bild verdeckt sind. Jede Region hat `covered`, `calibrated` und `visibility_score`. `calibrated: false` bedeutet einen Schattenhinweis, auf den keine Warnung reagiert. Wird nur von `GET /v3/session/{sessionId}/decision/` zurückgegeben, niemals in Webhook-Payloads. | `{ "eyes": { "covered": false, "calibrated": true, "visibility_score": 0.98 } }` |

```json theme={null}
{
  "status": "Approved",
  "score": 97.83,
  "source_image_session_id": null,
  "source_image": "https://<media-host>/.../source.jpg?signature=...",
  "target_image": "https://<media-host>/.../target.jpg?signature=...",
  "node_id": "first_face_match",
  "warnings": []
}
```

### Gesichtssuche

Wird von der eigenständigen Gesichtssuche-API (`POST /v3/face-search/`) zurückgegeben. Die Gesichtssuche erscheint nie als Array mit mehreren Elementen in `/v3/session/{sessionId}/decision/`. Wenn sie mit `save_api_request=true` gespeichert wird, taucht die Sitzung dort als Eintrag `FACE_SEARCH` in `features[]` auf, zusammen mit einem Element `liveness_checks[]`, das die gespeicherten `matches` enthält. Quellen: `apis/serializers/face_search.py:8-79` (`FaceSearchResponseSerializer`, das `FaceSearchDetailsSerializer` umschließt); die Trefferobjekte (Dictionaries) werden in `face/utils/utils.py:869-884` erzeugt.

Antwort auf oberster Ebene:

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `request_id` | string (UUID) | Nein | Die gespeicherte Sitzungs-ID, wenn `save_api_request=true` ist (nutzbar mit `GET /v3/session/{sessionId}/decision/`). Andernfalls eine temporäre Korrelations-UUID. | `"4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f"` |
| `face_search` | object | Nein | Der Payload mit den Suchdetails, siehe Felder unten. | — |
| `vendor_data` | string | Ja | Aus der Anfrage zurückgegebenes `vendor_data`. | `null` |
| `metadata` | object | Ja | Aus der Anfrage zurückgegebenes `metadata`. | `null` |
| `created_at` | string (ISO 8601) | Nein | Serverseitiger Zeitstempel der Anfrage. | `"2026-06-12T01:04:42.763237+00:00"` |

`face_search`-Objekt:

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | `Declined` nur, wenn eine Warnung `FACE_IN_BLOCKLIST` oder `POSSIBLE_FACE_IN_BLOCKLIST` ausgelöst wurde; andernfalls `Approved`. Doppelte Treffer allein führen nie zu einer Ablehnung (`apis/views/face_search.py:242-248`). | `"Approved"` |
| `total_matches` | integer | Nein | Anzahl der zurückgegebenen Treffer in `matches[]` (0–5). | `1` |
| `matches` | Array aus [Gesichtssuche-Trefferobjekten](#gesichtssuche-trefferobjekt) | Nein | Bis zu 5 Treffer oberhalb der Mindestähnlichkeit, absteigend nach Ähnlichkeit sortiert (Sperrlisteneinträge zuerst, mit `search_type=blocklisted_or_approved`). | `[…]` |
| `user_image` | object | Nein | Erkennungsergebnis für das eingereichte Bild: `{ entities: [{ bbox, confidence }], best_angle }`, mit einem Eintrag pro erkanntem Gesicht. | `{ "entities": [{ "bbox": [40, 40, 120, 120], "confidence": 0.73 }], "best_angle": 0 }` |
| `warnings` | Array aus Objekten | Nein | Verkürzte Warnstruktur für diese eigenständige API, ohne `node_id`. Der Serializer-Vertrag deklariert `{ risk, additional_data, log_type, short_description, long_description }` (`apis/serializers/face_search.py:49-54`). Das Laufzeit-Payload enthält außerdem `feature`, immer `"LIVENESS"` (`apis/views/face_search.py:332-341`). | `[]` |

#### Gesichtssuche-Trefferobjekt

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `session_id` | string (UUID) | Ja | Die zugeordnete Verifizierungssitzung. `null`, wenn `source` den Wert `imported`, `list_entry` oder `retained_template` hat. | `"a3f2a6f1-…"` |
| `session_number` | integer | Ja | Für die Konsole lesbare Nummer der zugeordneten Sitzung; `null` bei Treffern ohne Sitzung. | `1024` |
| `similarity_percentage` | float (0-100) | Nein | Ähnlichkeit zwischen dem eingereichten Gesicht und dem zugeordneten Gesicht. | `96.42` |
| `source` | string (Enum) | Nein | Herkunft des zugeordneten Gesichts: `session` (Verifizierungssitzung oder gespeicherter eigenständiger Aufruf), `imported` (direkter Upload eines Gesichts im Benutzerprofil), `list_entry` (einer Liste zugeordnetes Gesicht), `retained_template` (bildloses [biometrisches Template](https://docs.didit.me/de/management-api/biometric-templates/overview.md), das nach dem Löschen der Quellsitzung aufbewahrt wurde). | `"session"` |
| `vendor_data` | string | Ja | Das `vendor_data` der zugeordneten Sitzung oder bei `imported`- und `retained_template`-Treffern das des verknüpften Benutzers. | `"user-12345"` |
| `vendor_user_id` | string (UUID) | Ja | Der verknüpfte Benutzer. `null` bei `list_entry`-Treffern und bei Sitzungen ohne Benutzer. | `"2f7c1a9e-…"` |
| `biometric_template_id` | string (UUID) | Ja | Die übereinstimmende aufbewahrte Vorlage. Nur bei `retained_template`-Treffern gesetzt; verwenden Sie es mit `GET`/`DELETE /v3/biometric-templates/{id}/`. | `null` |
| `verification_date` | string (ISO 8601) | Ja | Zeitpunkt, zu dem das zugeordnete Gesicht aufgenommen wurde, bzw. zu dem ein `retained_template` aufbewahrt wurde. `null` bei `list_entry`-Treffern. | `"2024-11-04T09:14:02Z"` |
| `user_details` | object | Ja | `{ full_name, document_type, document_number }` aus der Dokumentenverifizierung der zugeordneten Sitzung. Bei `imported`-Treffern ist nur `full_name` gesetzt. `null`, wenn keine Identitätsdaten vorliegen, und bei `retained_template`-Treffern immer `null`. | `{ "full_name": "María García López", "document_type": "Passport", "document_number": "AB1234567" }` |
| `match_image_url` | string (URL) | Ja | Referenzgesicht des zugeordneten Benutzers: vorab signierte URL bei `save_api_request=true`, andernfalls der rohe Speicherpfad. Bei `retained_template`-Treffern immer `null`, da diese kein Bild enthalten. | `"https://<media-host>/.../matched.jpg?..."` |
| `status` | string | Ja | Verifizierungsstatus der zugeordneten Sitzung (siehe [Status-Enum](#status-aufzählung)). `null` bei Treffern ohne Sitzung. | `"Approved"` |
| `is_blocklisted` | boolean | Nein | Ob das zugeordnete Gesicht in Ihrer Gesichts-Sperrliste steht. Bei `retained_template`-Treffern immer `false`. Ein gesperrtes Gesicht wird separat als `list_entry`-Treffer gemeldet. | `false` |
| `is_allowlisted` | boolean | Nein | Ob das zugeordnete Gesicht in einer Ihrer Zulassungslisten steht. | `false` |
| `api_service` | string (Enum) | Ja | Großgeschriebener Typ des eigenständigen API-Aufrufs der zugeordneten Sitzung (z. B. `PASSIVE_LIVENESS`, `FACE_MATCH`). `null` bei Workflow-Sitzungen und bei Treffern ohne Sitzung. | `null` |

```json theme={null}
{
  "request_id": "4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f",
  "face_search": {
    "status": "Approved",
    "total_matches": 1,
    "matches": [
      {
        "session_id": "a3f2a6f1-1c1c-4eec-8b69-1c1c2f3a2c7f",
        "session_number": 1024,
        "similarity_percentage": 96.42,
        "source": "session",
        "vendor_data": "user-12345",
        "verification_date": "2024-11-04T09:14:02Z",
        "user_details": {
          "full_name": "María García López",
          "document_type": "Passport",
          "document_number": "AB1234567"
        },
        "match_image_url": "https://<media-host>/.../matched.jpg?signature=...",
        "status": "Approved",
        "is_blocklisted": false,
        "is_allowlisted": false,
        "api_service": null
      }
    ],
    "user_image": {
      "entities": [
        {
          "bbox": [40, 40, 120, 120],
          "confidence": 0.732973
        }
      ],
      "best_angle": 0
    },
    "warnings": []
  },
  "vendor_data": null,
  "metadata": null,
  "created_at": "2026-06-12T01:04:42.763237+00:00"
}
```

### AML-Screening

Wird pro geprüfter Entität zurückgegeben. Erscheint als `aml_screenings[]` in `GET /v3/session/{sessionId}/decision/` sowohl für KYC- als auch für KYB-Sitzungen. Quelle: `aml/serializers/aml.py:63-85` (`AMLV3Serializer`, erweitert `AMLV2Serializer` in `aml/serializers/aml.py:28-60`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `total_hits` | integer | Nein | Anzahl der Screening-Treffer. Immer vorhanden, Standardwert ist `0`. | `2` |
| `entity_type` | string (Enum) | Ja | `person` oder `company` (`EntityTypeChoices`, `common/config/choices.py:675-677`). | `"person"` |
| `hits` | Array aus Objekten | Nein | Ein Eintrag pro Treffer. Wichtige Felder: `id`, `caption`, `match` (bool), `target` (bool \| null, also ob die Entität direktes Ziel des Eintrags ist), `match_score` (float 0-100, Identitäts-Konfidenz), `risk_score` (float 0-100, Risiko der Entität), `score` (veraltet, float 0-1), `datasets[]` (z. B. `PEP`, `PEP Level 1`-`4`, `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`), `properties` (Namen, Aliasse, Geburtsdaten usw.), `features`, `url`, `first_seen`, `last_seen`, `rca_name`, `risk_view`, `score_breakdown`, `pep_matches`, `sanction_matches`, `warning_matches`, `adverse_media_matches`, `adverse_media_details`, `linked_entities`, `additional_information` und `review_status` (`Unreviewed`, `Confirmed Match`, `False Positive`, `Inconclusive`; bearbeitbar über den Endpoint zum Aktualisieren des AML-Trefferstatus, `AMLHitStatusChoices`). | `[…]` |
| `score` | float (0-100) | Ja | Gesamtscore des Screenings: der höchste `risk_score` unter den Treffern, die nicht als `False Positive` markiert sind (`aml/services/aml.py:832-842`). Er ist `0`, wenn alle Treffer falsch positiv sind. `null`, bis er berechnet ist. | `42.7` |
| `screened_data` | object | Ja | Momentaufnahme der an das Screening übermittelten Daten: `full_name`, `nationality`, `date_of_birth`, `document_number`. | `{ "full_name": "María García López", "date_of_birth": "1990-05-12" }` |
| `is_ongoing_monitoring_enabled` | boolean | Nein | Ob die Entität für erneute Screenings im Rahmen der laufenden Überwachung angemeldet ist. | `false` |
| `next_ongoing_monitoring_bill_date` | string (YYYY-MM-DD) | Ja | Berechnet als `last_aml_bill_date + 365 days`, wenn die laufende Überwachung aktiviert ist. Ein **Abrechnungsdatum**, kein Screening-Datum. | `null` |
| `last_ongoing_screening_at` | string (ISO 8601) | Ja | Zeitpunkt, zu dem die laufende Überwachung zuletzt ein erneutes Screening dieses Datensatzes abgeschlossen hat, unabhängig davon, ob sich das Ergebnis geändert hat. `null`, wenn nie erneut gescreent wurde; wird nie rückwirkend befüllt. | `"2026-09-12T04:03:11Z"` |
| `last_ongoing_screening_datasets_updated_at` | string (ISO 8601) | Ja | Neueste AML-Datensatzaktualisierung, die der Anbieter für dieses Screening gemeldet hat. `null`, wenn kein Datensatzdatum gemeldet wurde; wird nie geschätzt. | `null` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Kennung (V3). | `"first_aml"` |
| `warnings` | array | Nein | Siehe [Warnobjekt](#warnungsobjekt). | `[]` |

```json theme={null}
{
  "status": "In Review",
  "total_hits": 1,
  "entity_type": "person",
  "hits": [
    {
      "id": "Q7XW3-aml-hit-1",
      "caption": "Maria Garcia Lopez",
      "match": true,
      "target": true,
      "match_score": 86.4,
      "risk_score": 42.7,
      "datasets": ["PEP Level 2"],
      "properties": {
        "name": ["María García López", "M. García"],
        "alias": ["Maria Garcia"],
        "birthDate": ["1990-05-12"]
      },
      "url": "https://example.org/registry/entities/Q7XW3",
      "first_seen": "2023-11-02T00:00:00Z",
      "last_seen": "2026-05-01T00:00:00Z",
      "review_status": "Unreviewed"
    }
  ],
  "score": 42.7,
  "screened_data": {
    "full_name": "María García López",
    "date_of_birth": "1990-05-12",
    "nationality": "ES",
    "document_number": "AB1234567"
  },
  "is_ongoing_monitoring_enabled": false,
  "next_ongoing_monitoring_bill_date": null,
  "last_ongoing_screening_at": null,
  "last_ongoing_screening_datasets_updated_at": null,
  "node_id": "first_aml",
  "warnings": []
}
```

### IP-Analyse

Wird pro erfasstem Netzwerkstandort zurückgegeben. Erscheint als `ip_analyses[]` in `GET /v3/session/{sessionId}/decision/` für KYC- und KYB-Sitzungen. Quelle: `kyc/serializers/location.py:196-243` (`IPAnalysisSerializerV3`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Kennung (V3). | `"first_ip_analysis"` |
| `device_brand` | string | Ja | Aus dem User-Agent abgeleitete Gerätemarke. | `"Apple"` |
| `device_model` | string | Ja | Gerätemodell. | `"iPhone"` |
| `browser_family` | string | Ja | Browserfamilie. | `"Mobile Safari"` |
| `os_family` | string | Ja | Betriebssystemfamilie. | `"iOS"` |
| `platform` | string | Ja | Übergeordnete Plattform (`mobile`, `desktop`, `tablet`). | `"mobile"` |
| `device_fingerprint` | string | Ja | Stabiler Hash-Fingerabdruck pro Gerät. | `"f2a3…"` |
| `ip_country` | string | Ja | Aus der IP aufgelöster Ländername. | `"Spain"` |
| `ip_country_code` | string (ISO 3166-1 alpha-2) | Ja | Aus der IP aufgelöster Ländercode. | `"ES"` |
| `ip_state` | string | Ja | Aus der IP aufgelöste Region / Bundesland. | `"Comunidad de Madrid"` |
| `ip_city` | string | Ja | Aus der IP aufgelöste Stadt. | `"Madrid"` |
| `latitude` | float | Ja | Aus der IP abgeleiteter Breitengrad. | `40.4168` |
| `longitude` | float | Ja | Aus der IP abgeleiteter Längengrad. | `-3.7038` |
| `ip_address` | string | Ja | Die erfasste Adresse. | `"203.0.113.42"` |
| `isp` | string | Ja | Name des ISP. | `"Telefonica de Espana"` |
| `organization` | string | Ja | Name der Organisation (oft identisch mit dem ISP). | `"Telefonica de Espana"` |
| `is_vpn_or_tor` | boolean | Ja | `true`, wenn die IP zu einem VPN, Proxy oder Tor-Exit-Knoten gehört. | `false` |
| `is_data_center` | boolean | Ja | `true`, wenn die IP zu einem bekannten Hosting- oder Rechenzentrums-ASN gehört. | `false` |
| `time_zone` | string | Ja | IANA-Zeitzonenname. | `"Europe/Madrid"` |
| `time_zone_offset` | string | Ja | UTC-Offset. | `"+02:00"` |
| `ip` | object | Nein | `{ location, distance_from_id_document, distance_from_poa_document }`. `location = { latitude, longitude }`. Entfernungen in km, `null`, wenn eine der beiden Seiten fehlt. | `{ "location": { "latitude": 40.4168, "longitude": -3.7038 }, "distance_from_id_document": 3.4, "distance_from_poa_document": 1.1 }` |
| `id_document` | object | Nein | `{ location, distance_from_ip, distance_from_poa_document }`. Standort des Ausweisdokuments, abgeleitet aus `issuing_state` und der geparsten Adresse. | `{ "location": { "latitude": 40.4165, "longitude": -3.7026 }, "distance_from_ip": 3.4, "distance_from_poa_document": 4.0 }` |
| `poa_document` | object | Nein | `{ location, distance_from_ip, distance_from_id_document }`. Geocodierte POA-Adresse. | `{ "location": { "latitude": 40.4170, "longitude": -3.7040 }, "distance_from_ip": 1.1, "distance_from_id_document": 4.0 }` |
| `matches` | array of objects | Nein | Sitzungsübergreifende IP- und Geräte-Treffer. Jedes Element: `{ session_id, session_number, vendor_data, verification_date, match_type, match_source, matched_value, status, is_blocklisted, api_service, source, device_info, location_info, confidence, match_mode }`. `match_type` ist `ip_address` oder `device_fingerprint`. `match_source` ist `ip_address`, `persistent_id`, `legacy_fp` oder `recovered_high` (wiederhergestellte Treffer enthalten zusätzlich `recovery_similarity`, `tls_ja4_corroborated`, `recovery_gate_reason`). Begrenzt auf 5 IP- und 5 Geräte-Treffer. | `[]` |
| `warnings` | array | Nein | Siehe [Warnobjekt](#warnungsobjekt). | `[]` |
| `browser_version`, `os_version` | string | Ja | Browser- und Betriebssystemversionen aus dem User-Agent. | `"17.4"` |
| `user_agent`, `accept_language` | string | Ja | Der User-Agent-String und der `Accept-Language`-Header, die der Browser gesendet hat. | `"en-US,en;q=0.9"` |
| `session_identifier`, `session_age_ms` | string, integer | Ja | Die Browsersitzung, in der der Schritt lief, und deren Alter in Millisekunden. | `48210` |
| `coords_accuracy` | float | Ja | Genauigkeitsradius in Metern der vom Gerät gemeldeten Koordinaten. | `35.0` |
| `raw_device_data` | object | Ja | Rohe Gerätesignale, die für den Schritt erfasst wurden. | `{}` |

```json theme={null}
{
  "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": []
}
```

### Standortverifizierung

Wird pro [Standortverifizierung](https://docs.didit.me/de/core-technology/location-verification/overview.md)-Schritt zurückgegeben. Erscheint als `geolocation_checks[]` in `GET /v3/session/{sessionId}/decision/`: ein Eintrag pro Schritt, und zwar dessen akzeptierter Versuch. `geolocation_attempts[]` listet jeden Versuch jedes Schritts auf, wobei der älteste zuerst aufgeführt wird. Beide sind `null` bei einem Workflow ohne diesen Schritt. Quelle: `GeolocationDecisionSerializer`.

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `node_id` | string | Ja | Workflow-Knoten, der das Ergebnis erzeugt hat. | `"geolocation_1"` |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Declined"` |
| `outcome` | string | Ja | Was beim Versuch passiert ist: `verified`, `low_accuracy`, `accuracy_undetermined`, `stale`, `approximate`, `denied`, `restricted`, `unavailable`, `timeout`, `mock_detected`, `outside_geofence`, `in_blocked_area`, `anonymizer_detected`, `skipped`, `replay_rejected` oder `unsupported_client`. | `"outside_geofence"` |
| `permission` | string | Ja | Was das System gewährt hat: `granted_precise`, `granted_approximate`, `denied`, `restricted`, `unavailable`, `timeout`, `dismissed` oder `not_requested`. | `"granted_precise"` |
| `latitude`, `longitude` | float | Ja | WGS84-Position. `null`, wenn keine Position vorliegt. | `48.8566` |
| `accuracy_m` | float | Ja | Unsicherheitsradius in Metern. | `35.0` |
| `accuracy_confidence` | string | Ja | `p95`, `p68` oder `unspecified`. | `"p95"` |
| `measured_at`, `age_seconds` | datetime, integer | Ja | Zeitpunkt, zu dem das Gerät die Standortbestimmung vorgenommen hat, und die Sekunden bis Didit sie empfangen hat. | `2` |
| `source`, `platform`, `sdk_version` | string | Ja | Herkunft der Standortbestimmung, der Client, der sie erzeugt hat, und dessen SDK-Version. | `"browser"` |
| `is_mock`, `produced_by_accessory` | boolean | Ja | Spoofing-Hinweise, die die Plattform meldet. `null` bedeutet, dass sie dies nicht meldet. | `null` |
| `integrity` | string | Nein | `attested`, `not_attested`, `failed`, `unsupported` (Web) oder `not_determined`. | `"unsupported"` |
| `country_code`, `region_code`, `city` | string | Ja | Der Ort, der sich aus der Standortbestimmung ergibt. | `"FR"` |
| `geofence`, `inside_geofence`, `geofence_basis`, `inside_areas`, `blocked_areas` | object, boolean, string, arrays | Ja | Ergebnis für Land und Gebiet. | `{ "enabled": true, "result": "outside" }` |
| `position_source`, `anonymizers` | string, object | Ja | Woher der Schritt die Position bezieht, sowie die Signale zu VPN, Proxy, Tor, Spoofing und Emulator. | `"device_and_ip"` |
| `ip_distance_km`, `ip_distance_uncertainty_km`, `ip_consistent`, `document_distance_km`, `travel_excused`, `consecutive_mismatches` | number, boolean, integer | Ja | Die Vergleiche mit dem IP-Standort und der hinterlegten Adresse. | `12.4` |
| `attempts` | integer | Nein | Die Nummer des Versuchs innerhalb des Schritts. | `3` |
| `consent` | object | Ja | `accepted_at`, `version` und `locale` des Hinweises, den die Person akzeptiert hat. | |
| `warnings` | Array aus [Warnobjekten](#warnungsobjekt) | Nein | Die Warnungen `LOCATION_*` des Schritts. Nicht in `geolocation_attempts[]` enthalten, das zusätzlich `received_at` und `created_at` enthält. | `[]` |

Alle Felder und Beispiele finden sich im [Bericht zur Standortverifizierung](https://docs.didit.me/de/core-technology/location-verification/report-location-verification.md).

### Adressnachweis

Wird pro eingereichtem Adressdokument zurückgegeben. Erscheint als `poa_verifications[]` in `GET /v3/session/{sessionId}/decision/`. Quelle: `poa/serializers/poa.py:212-227` (`POAV3Serializer`, erweitert `POAV2Serializer` unter `poa/serializers/poa.py:173-209`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Ja | Ländercode des Ausstellers des Dokuments. | `"ESP"` |
| `document_type` | string | Nein | Typ auf oberster Ebene aus `PoaDocumentTypeChoices` (`common/config/choices.py:868-873`): `UTILITY_BILL`, `BANK_STATEMENT`, `GOVERNMENT_ISSUED_DOCUMENT`, `OTHER_POA_DOCUMENT`. Fällt auf `UNKNOWN` zurück, niemals `null`. | `"UTILITY_BILL"` |
| `document_subtype` | string | Nein | Subtyp-Code aus `PoaDocumentSubtypeChoices` (z. B. `ELECTRICITY_BILL`, `WATER_BILL`, `ACCOUNT_STATEMENT`). Fällt auf `UNKNOWN` zurück, niemals `null`. | `"ELECTRICITY_BILL"` |
| `issuer` | string | Ja | Name der ausstellenden Stelle. | `"Iberdrola"` |
| `issue_date` | string (YYYY-MM-DD) | Ja | Ausstellungsdatum des Dokuments. | `"2026-04-15"` |
| `expiration_date` | string (YYYY-MM-DD) | Ja | Auf dem Dokument aufgedrucktes Ablaufdatum, sofern vorhanden. | `null` |
| `poa_address` | string | Ja | Rohe, aus OCR extrahierte Adresse. | `"Calle Mayor 1, 28001 Madrid"` |
| `poa_formatted_address` | string | Ja | Geocodierte bzw. formatierte Adresse. | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `poa_parsed_address` | object | Ja | Strukturierte Adresse (`street_1`, `street_2`, `city`, `region`, `postal_code`, `country` (alpha-2), `address_type`, `document_location`, …). | `{ "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001" }` |
| `document_file` | string (URL) | Ja | Vorsignierte URL zum hochgeladenen Dokument. | `"https://<media-host>/.../poa.pdf?..."` |
| `document_language` | string | Ja | Erkannte Dokumentsprache (ISO 639-1). | `"es"` |
| `document_metadata` | object | Ja | Gefilterte Metadaten: `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_fields` | object | Nein | Bankkontofelder (`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` sowie alle benutzerdefinierten Schlüssel, die im Datensatz gespeichert sind. | `{ "bank_iban": null, "additional_names": [] }` |
| `name_on_document` | string | Ja | Name, wie er auf dem Adressnachweis steht. | `"María García López"` |
| `expected_details_address` | string | Ja | Vom Kunden bei der Registrierung eingegebene Adresse (wortgetreu). | `"Calle Mayor 1, Madrid"` |
| `expected_details_formatted_address` | string | Ja | Geocodierte erwartete Adresse. | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `expected_details_parsed_address` | object | Ja | Strukturierte erwartete Adresse. | `{ "city": "Madrid", "postal_code": "28001" }` |
| `name_match_score_expected_details` | float (0-100) | Ja | Unscharfer Abgleich von `name_on_document` mit dem Namen, der bei der Sitzungserstellung angegeben wurde. | `94.0` |
| `name_match_score_id_verification` | float (0-100) | Ja | Unscharfer Abgleich von `name_on_document` mit dem `full_name` des verifizierten Ausweises. | `100.0` |
| `extra_files` | Array aus Strings (URL) | Nein | Vorsignierte URLs zu zusätzlich hochgeladenen Dateien. | `[]` |
| `detected_codes` | Array aus Objekten | Nein | QR-Codes und Barcodes, die auf jeder verarbeiteten Seite des Dokuments erkannt wurden: `type`, `page_number` (ab 1 gezählt), `position` (Polygon), `x`/`y`/`width`/`height` (Begrenzungsrahmen), `page_width`/`page_height`, `raw_payload` (Base64), `parsed_payload` (dekodierter Wert, `null`, wenn ein Code gefunden, aber nicht dekodiert werden konnte). Leeres Array, wenn die Erkennung nichts findet. | `[{ "type": "QR_CODE", "page_number": 1, "parsed_payload": "https://issuer.example/inv/9981" }]` |
| `node_id` | String \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_poa"` |
| `warnings` | Array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "issuing_state": "ESP",
  "document_type": "UTILITY_BILL",
  "document_subtype": "ELECTRICITY_BILL",
  "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_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" },
  "document_file": "https://<media-host>/.../poa.pdf?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_name": "Iberdrola Clientes", "date": "2026-04-15T08:11:32Z" },
    "exif_original_date": null,
    "exif_digitized_date": null,
    "processed_by_known_editor": false,
    "has_different_creation_mod_date": false,
    "overlay_manipulation": null
  },
  "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": [],
  "detected_codes": [
    {
      "type": "QR_CODE",
      "page_number": 1,
      "position": [[820, 1120], [1002, 1120], [1002, 1302], [820, 1302]],
      "x": 820,
      "y": 1120,
      "width": 182,
      "height": 182,
      "page_width": 1190,
      "page_height": 1684,
      "raw_payload": "aHR0cHM6Ly9pYmVyZHJvbGEuZXMvZmFjdHVyYS85OTgx",
      "parsed_payload": "https://iberdrola.es/factura/9981"
    },
    {
      "type": "CODE_128",
      "page_number": 1,
      "position": [[112, 1480], [560, 1480], [560, 1540], [112, 1540]],
      "x": 112,
      "y": 1480,
      "width": 448,
      "height": 60,
      "page_width": 1190,
      "page_height": 1684,
      "raw_payload": "MDA5OTgxMDAwNDI=",
      "parsed_payload": "0099810042"
    }
  ],
  "node_id": "first_poa",
  "warnings": []
}
```

### Telefonverifizierung

Wird pro Telefonverifizierungsversuch zurückgegeben. Erscheint als `phone_verifications[]` in `GET /v3/session/{sessionId}/decision/` für KYC- und KYB-Sitzungen. Quelle: `phone/serializers/phone.py:251-266` (`PhoneV3Serializer`, erweitert `PhoneV2Serializer` unter `phone/serializers/phone.py:103-248`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | String | Nein | Siehe [Status-Aufzählung](#status-aufzählung). | `"Approved"` |
| `phone_number_prefix` | String | Nein | E.164-Ländervorwahl (mit `+`). | `"+34"` |
| `phone_number` | String | Nein | Teilnehmernummer ohne Vorwahl. | `"612345678"` |
| `full_number` | String | Nein | Die vollständige E.164-Nummer (`phone_number_prefix + phone_number`). | `"+34612345678"` |
| `country_code` | String (ISO 3166-1 Alpha-2) | Ja | Land der Nummer. | `"ES"` |
| `country_name` | String | Ja | Lokalisierter Ländername. | `"Spain"` |
| `carrier` | Objekt | Nein | `{ name, type }`, wobei `type` ein Wert von `LineTypeChoices` ist (`common/config/choices.py:648-667`): `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `satellite`, `pager`, `payphone`, `voice_mail`, `unknown` sowie weitere Leitungsklassen. | `{ "name": "Movistar", "type": "mobile" }` |
| `is_disposable` | Boolean | Nein | `true`, wenn der Netzbetreiber die Nummer als temporär bzw. Wegwerfnummer kennzeichnet. | `false` |
| `is_virtual` | Boolean | Nein | `true`, wenn `carrier.type` einer der Werte `voip`, `isp` oder `vpn` ist. | `false` |
| `verification_method` | String | Nein | Kanal, über den der OTP zugestellt wurde (`whatsapp`, `sms`, …). Wird aus `actual_channel` des letzten Sendeversuchs gelesen (Fallback: der angeforderte `channel`, dann `sms`). | `"whatsapp"` |
| `verification_attempts` | Integer | Nein | Gesamtzahl der OTP-Sendeversuche (erstes Senden plus erneute Sendungen). | `1` |
| `verified_at` | String (ISO 8601) | Ja | Zeitstempel, zu dem der OTP erfolgreich eingegeben wurde. | `"2026-05-17T10:14:02Z"` |
| `lifecycle` | Array aus Objekten | Nein | Chronologische Ereignisse: Sendeversuche, Zustellungs-Callbacks, Codeprüfungen und das abschließende Statusereignis. Jedes Ereignis ist `{ type, timestamp, details, fee }`. Die Ereignistypen stammen aus `PhoneEventChoices`. | `[…]` |
| `matches` | Array aus Objekten | Nein | Sitzungsübergreifende Übereinstimmungen von Telefonnummern. Jeder Eintrag: `{ session_id, session_number, vendor_data, verification_date, phone_number, status, is_blocklisted, api_service, source }`. `source` ist `session` oder `list_entry`. | `[]` |
| `node_id` | String \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_phone"` |
| `warnings` | Array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |
| `phone_intelligence` | Objekt | Ja | Signale der Telefon-Intelligence. Nur vorhanden, wenn das Intelligence-Add-on für die Nummer ausgeführt wurde. | |
| `phone_social` | Objekt | Ja | Social-Footprint der Nummer. Nur vorhanden, wenn das Social-Footprint-Add-on ausgeführt wurde. | |

```json theme={null}
{
  "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": "Success", "reason": null, "channel": "whatsapp", "actual_channel": "whatsapp" },
      "fee": 0.02
    },
    {
      "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": []
}
```

### E-Mail-Verifizierung

Wird pro E-Mail-Verifizierungsversuch zurückgegeben. Erscheint als `email_verifications[]` in `GET /v3/session/{sessionId}/decision/` für KYC- und KYB-Sitzungen. Quelle: `email_verification/serializers/email.py:149-164` (`EmailV3Serializer`, erweitert `EmailV2Serializer` unter `email_verification/serializers/email.py:38-146`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | String | Nein | Siehe [Status-Aufzählung](#status-aufzählung). | `"Approved"` |
| `email` | String | Nein | Die übermittelte E-Mail-Adresse. | `"maria.garcia@example.com"` |
| `is_breached` | Boolean | Nein | `true`, wenn die E-Mail-Adresse in einem bekannten Datenleck vorkommt. | `false` |
| `breaches` | Array aus Objekten | Nein | Details zu jedem Datenleck, wenn `is_breached` `true` ist: `{ name, domain, logo_path, breach_date, description, is_verified, data_classes, breach_emails_count }`. | `[]` |
| `is_disposable` | Boolean | Nein | `true`, wenn die E-Mail-Adresse zu einem Anbieter für Wegwerf-E-Mails gehört. | `false` |
| `is_undeliverable` | Boolean | Nein | `true`, wenn die SMTP-Zustellprüfung ergibt, dass das Postfach keine E-Mails annimmt. | `false` |
| `verification_attempts` | Integer | Nein | Gesamtzahl der OTP-Prüfversuche. | `1` |
| `verified_at` | String (ISO 8601) | Ja | Zeitstempel, zu dem der OTP erfolgreich eingegeben wurde. | `"2026-05-17T10:15:22Z"` |
| `lifecycle` | Array aus Objekten | Nein | Chronologische Ereignisse: Sendeversuche, Codeprüfungen und das abschließende Statusereignis. Jedes Ereignis ist `{ type, timestamp, details, fee }`. Die Ereignistypen stammen aus `EmailEventChoices`. | `[…]` |
| `matches` | Array aus Objekten | Nein | Sitzungsübergreifende Übereinstimmungen von E-Mail-Adressen. Jeder Eintrag: `{ session_id, session_number, vendor_data, verification_date, email, status, is_blocklisted, api_service, source }`. `source` ist `session` oder `list_entry`. | `[]` |
| `node_id` | String \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_email"` |
| `warnings` | Array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |
| `email_intelligence` | Objekt | Ja | Signale der E-Mail-Intelligence. Nur vorhanden, wenn das Intelligence-Add-on für die Adresse ausgeführt wurde. | |
| `email_social` | Objekt | Ja | Social-Footprint der Adresse. Nur vorhanden, wenn das Social-Footprint-Add-on ausgeführt wurde. | |

```json theme={null}
{
  "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": "Success", "reason": null },
      "fee": 0.02
    },
    {
      "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": []
}
```

### Datenbankvalidierung

Wird pro Datenbankabfrage zurückgegeben, die mit den übermittelten Daten des Benutzers ausgeführt wurde. Erscheint als `database_validations[]` in `GET /v3/session/{sessionId}/decision/`. Quelle: `database_validation/serializers/database_validation.py:21-142` (`DatabaseValidationV3Serializer`, erweitert `DatabaseValidationV2Serializer`).

| Field | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Ja | Land, dessen Register abgefragt wurde. | `"ESP"` |
| `validation_type` | string (enum) | Nein | Wie das Ergebnis bestätigt wurde: `one_by_one` (Ergebnis eines einzelnen Dienstes), `two_by_two` (zwei oder mehr verschiedene Dienste haben die Identifikationsnummer unabhängig voneinander vollständig abgeglichen) oder `not_enabled` (der Validator wurde übersprungen oder kein Anbieter hat geantwortet; ein eindeutiges `no_match` ergibt trotzdem `one_by_one`). Niemals `null`. Quelle: `DatabaseValidationChoices` (`common/config/choices.py:1097-1100`). | `"one_by_one"` |
| `screened_data` | object | Nein | Die an das Register übermittelten Daten. Dateifelder (`selfie`, `cnh_qr_code_image`, `document_image`) werden zum Lesezeitpunkt vorsigniert. | `{ "document_number": "99999999R", "date_of_birth": "1990-05-12" }` |
| `validations` | Array von Objekten | Nein | Ein Eintrag pro Katalogdienst, der eine Übereinstimmung geliefert hat. Jeder Eintrag kann `service_id`, `service_name`, `validation` (Prüfergebnis des Anbieters), `outcome_code`, `outcome_detail` und `source_data` (bereinigtes Bürgerprofil: `full_name`, `gender`, `date_of_birth`, `photo` (vorsignierte URL), `signature` (vorsignierte URL), …) enthalten. | `[…]` |
| `errors` | Array von Objekten | Ja | Fehler pro Dienst, wenn eine Abfrage fehlgeschlagen ist; der Schlüssel wird vollständig weggelassen, wenn das Array leer ist. Jeder Eintrag ist das Fehlerobjekt des vorgelagerten Dienstes zuzüglich der `service_id`, die ihn erzeugt hat. | `[]` |
| `match_type` | string (enum) | Ja | Gesamturteil der Übereinstimmung über alle abgefragten Dienste: `full_match`, `partial_match` oder `no_match` (`DatabaseValidationMatchTypeChoices`, `common/config/choices.py:1103-1106`). `null`, bis ausgewertet. | `"full_match"` |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Kennung (V3). | `"first_db_validation"` |
| `warnings` | Array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

```json theme={null}
{
  "issuing_state": "ESP",
  "validation_type": "one_by_one",
  "screened_data": {
    "document_number": "99999999R",
    "date_of_birth": "1990-05-12",
    "first_name": "María",
    "last_name": "García López"
  },
  "validations": [
    {
      "service_id": "esp_dni",
      "service_name": "Spain - DNI/NIE verification",
      "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://<media-host>/.../registry_photo.jpg?signature=...",
        "signature": null
      }
    }
  ],
  "match_type": "full_match",
  "status": "Approved",
  "node_id": "first_db_validation",
  "warnings": []
}
```

### Fragebogen-Antwort

Wird pro Fragebogen-Übermittlung zurückgegeben. Erscheint als `questionnaire_responses[]` in `GET /v3/session/{sessionId}/decision/` für KYC- und KYB-Sitzungen. Quelle: `questionnaires/serializers/questionnaire.py:591-597` (`QuestionnaireResponseV3Serializer`, erweitert `QuestionnaireResponseSerializer` unter `questionnaires/serializers/questionnaire.py:520-588`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `questionnaire_id` | string (UUID) | Nein | Kennung der beantworteten Version des Fragebogens. | `"6a0f1c2c-…"` |
| `title` | string | Nein | Name des Fragebogens, wie er in der Console festgelegt ist. | `"Customer risk profile"` |
| `description` | string | Ja | Beschreibung des Fragebogens. | `"Short risk-profile questions."` |
| `languages` | Array von Strings | Nein | Sprachcodes, in denen der Fragebogen veröffentlicht ist. | `["en", "es"]` |
| `default_language` | string | Nein | Ersatz-Sprachcode. | `"en"` |
| `is_active` | boolean | Nein | Gibt an, ob diese Version des Fragebogens die aktive ist. | `true` |
| `is_simple_questionnaire` | boolean | Nein | `true`, wenn der Fragebogen keine Verzweigungen hat (flache Liste). | `true` |
| `questionnaire_group_id` | string (UUID) | Nein | Kennung, die allen Versionen desselben Fragebogens gemeinsam ist. | `"a7c2c2c2-…"` |
| `version` | integer | Nein | Versionsnummer der aktiven Vorlage. | `3` |
| `status` | string | Nein | Eines von `Approved`, `In Review`, `Not Finished` (eine Ablehnung auf Fragebogenebene wird auf `In Review` abgebildet). | `"Approved"` |
| `published_at` | string (ISO 8601) | Ja | Zeitpunkt, zu dem die Vorlage veröffentlicht wurde. | `"2026-01-12T11:00:00Z"` |
| `sections` | Array von Objekten | Nein | Geordnete Abschnitte nach Anwendung der Graph-Traversierung und der Sichtbarkeitsfilterung. Jeder Abschnitt ist `{ title, description, items[] }` (title und description stammen aus dem öffnenden `SECTION_HEADER` und sind bereits übersetzt). Jeder Eintrag ist ein Formularelement (`uuid`, `value` (Knoten-ID), `element_type`, `is_required`, `title`, `description`, `placeholder`, `choices`, `max_files`, `required_if`, `repeatable_config` sowie ein Feld `answer`, das `null` ist, wenn nicht beantwortet; bei Layout-Elementen `HEADING`/`PARAGRAPH`/`SEPARATOR` entfällt das Feld). Dateiantworten enthalten `{ files: [<presigned URL>, …] }`. | `[…]` |
| `node_id` | string \| null | Ja | Workflow-Knoten-Kennung (V3). | `"first_questionnaire"` |

```json theme={null}
{
  "questionnaire_id": "6a0f1c2c-3b7d-4d2c-9eb6-fdc6c7c92ef9",
  "title": "Customer risk profile",
  "description": "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": "Source of funds",
      "description": null,
      "items": [
        {
          "uuid": "4f1d5e2c-aaaa-4d2c-9eb6-fdc6c7c92ef9",
          "value": "q_source_of_funds",
          "element_type": "SINGLE_CHOICE",
          "is_required": true,
          "title": "What is your main source of funds?",
          "description": null,
          "placeholder": null,
          "choices": [
            { "label": "Salary", "value": "salary" },
            { "label": "Business income", "value": "business" },
            { "label": "Investments", "value": "investments" }
          ],
          "max_files": 1,
          "required_if": null,
          "repeatable_config": null,
          "answer": { "value": "salary" }
        }
      ]
    }
  ],
  "node_id": "first_questionnaire"
}
```

### E-Signatur

Wird pro Unterzeichner eines [E-Signatur](https://docs.didit.me/de/core-technology/electronic-signature/overview.md)-Schritts zurückgegeben. Erscheint als `signatures[]` in `GET /v3/session/{sessionId}/decision/` für KYC- und KYB-Sitzungen, nur wenn der Workflow diesen Schritt enthält. Anders als die übrigen Berichtsobjekte ist sein `status` die Unterschriftsphase, und das Ergebnis steht in `verdict`. Die Einträge in `warnings[]` sind `{ code, node_id }` statt [Warnungsobjekte](#warnungsobjekt).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `id` | string (UUID) | Nein | Die Signatur des Unterzeichners. Verwenden Sie sie als `signature_id` für die Nachweis- und Validierungs-Routen. | `"0e6c2a8e-…"` |
| `node_id` | string | Nein | Workflow-Knoten-Kennung. | `"feature_signature"` |
| `status` | string | Nein | Unterschriftsphase: `intro`, `review`, `code`, `signing`, `signed` oder `declined`. Nur `signed` bedeutet, dass die Dokumente unterschrieben sind. | `"signed"` |
| `verdict` | string | Nein | `Not Finished`, `Approved`, `In Review` oder `Declined`. | `"Approved"` |
| `level` | string | Nein | `simple` (Standard) oder `aes`. `qes` ist ein Zusatzmodul, das noch nicht verfügbar ist. | `"aes"` |
| `format` | string | Nein | `pdf` für eine einfache Signatur, `pades` für die fortgeschrittene Signatur (AES). | `"pades"` |
| `profile` | string | Ja | `PAdES-B-LT`, sobald eine fortgeschrittene (AES) Signatur unterzeichnet ist, andernfalls null. | `"PAdES-B-LT"` |
| `signer` | object | Nein | `{ name, capacity, company, role, roles, identity_session_id }`. `capacity` ist `self` (KYC) oder `company` (KYB). | `{ "name": "Jane Doe", "capacity": "self", … }` |
| `identity_used` | object | Nein | `{ session_id, kyc_id, verified, expected_name }`: die verifizierte Identität, auf die sich die Signatur stützt. Bei einer einfachen Signatur ohne verifizierte Identität leer. | `{ "verified": true, … }` |
| `certificate` | object | Ja | `{ issuer, issued_to, serial, valid_from, valid_until }`. `null` bis zur Unterzeichnung, und bei einer einfachen Signatur immer `null`. | `{ "serial": "5A3F9C21", … }` |
| `confirmation` | Objekt | Nein | `{ channel, destination, confirmed_at, attempts }`. `destination` ist maskiert. `attempts` zählt die eingegebenen Codes, einschließlich des richtigen. Bei einer Simple-Signatur gibt es keinen Code, daher sind `channel` und `destination` `null`. | `{ "channel": "email", … }` |
| `timestamp` | Objekt | Ja | `{ time, qualified, valid }`. `qualified` ist bei AES immer `false`. `null`, bis unterschrieben, und bei einer Simple-Signatur immer `null`. | `{ "qualified": false, … }` |
| `documents` | Array aus Objekten | Nein | `{ id, uuid, title, file_name, pages, size_bytes, sha256_original, sha256_signed, status, opened_at, read_at, read_to_end, consented_at, consent, signed_file, mode, source_format, conversion, fields }`. `status` ist `signed`, `declined`, `not_signed` oder `not_reached`. `mode` ist `fields` oder `read_and_agree`. `source_format` ist `pdf` oder `docx`. `conversion` beschreibt die ursprüngliche Word-Datei oder ist bei einer PDF-Datei `null`. | `[…]` |
| `documents[].fields` | Array aus Objekten | Nein | `{ key, type, role, label, page, x, y, width, height, required, value, display_value, value_source, filled_at, image_url, value_unavailable_reason }` für jedes Feld im Dokument. `value` ist eine Zeichenkette, bei einer Checkbox ein Boolean oder `true` bei einer angewendeten Signatur oder Paraphe. Bei einem Dokument ohne Felder leer. | `[…]` |
| `adopted_signature` | Objekt | Ja | `{ method, font, adopted_at }`: die Unterschrift und Paraphe, die der Unterzeichner übernommen hat. `method` ist `typed` oder `drawn`. `font` ist der Handschriftstil einer getippten Unterschrift. `null`, bis sie übernommen wurde. | `{ "method": "drawn", … }` |
| `electronic_signature_consent_at` | Zeichenkette (ISO 8601) | Ja | Wann der Unterzeichner zugestimmt hat, die Dokumente elektronisch zu signieren. Wird gesetzt, wenn ein Dokument Felder hat. | `"2026-11-03T10:41:40Z"` |
| `evidence_file` | Zeichenkette | Ja | Pfad des Nachweis-PDFs, sobald unterschrieben. | `"/v3/session/…/evidence/?signature_id=…"` |
| `warnings` | Array aus Objekten | Nein | `{ code, node_id }`, wobei `code` einer der folgenden Werte ist: `SIGNATURE_DECLINED`, `SIGNATURE_OTP_FAILED`, `SIGNATURE_NAME_MISMATCH`, `SIGNATURE_IDENTITY_NOT_VERIFIED`, `SIGNATURE_DOCUMENT_CHANGED`. | `[]` |
| `validation` | Objekt | Ja | `{ valid, checked_at, documents[] }`: die letzte kryptografische Prüfung der signierten Dokumente. `null`, bis unterschrieben. `{ valid: null, reason: "signature_provider_outcome_unknown", checked_at }`, wenn das Ergebnis der Signatur nicht bestätigt werden konnte. | `{ "valid": true, … }` |
| `declined_at` | Zeichenkette (ISO 8601) | Ja | Wann der Unterzeichner abgelehnt hat. | `null` |
| `declined_action` | Zeichenkette | Nein | Die `signature_declined_action` des Schritts. | `"REVIEW"` |
| `signed_at` | Zeichenkette (ISO 8601) | Ja | Wann die Dokumente unterschrieben wurden. | `"2026-11-03T10:42:24Z"` |
| `expires_at` | Zeichenkette (ISO 8601) | Nein | Wann der Signatur-Link nicht mehr funktioniert. | `"2026-11-10T10:30:00Z"` |
| `email_sent_at` | Zeichenkette (ISO 8601) | Ja | Wann dem Unterzeichner eine signierte Kopie per E-Mail gesendet wurde. | `"2026-11-03T10:42:30Z"` |
| `email_unavailable_reason` | Zeichenkette | Ja | Warum keine Kopie per E-Mail gesendet wurde, wenn eine angefordert war. | `null` |
| `ip_address` | Zeichenkette | Ja | Die IP-Adresse des Unterzeichners, als er seinen Code angefordert hat. | `"203.0.113.10"` |
| `place` | Zeichenkette | Ja | Wird nicht erfasst: immer `null`. | `null` |
| `place_unavailable_reason` | Zeichenkette | Ja | `not_collected`. | `"not_collected"` |

Der [E-Signatur-Bericht](https://docs.didit.me/de/core-technology/electronic-signature/report-electronic-signature.md) enthält ein vollständiges Beispiel und alle verschachtelten Felder.

### Altersschätzung

Wird von der eigenständigen Altersschätzungs-API (`POST /v3/age-estimation/`) zurückgegeben. Die Antwort enthält einen Teil der Struktur von [`Liveness check`](#liveness-prüfung) in einer `age_estimation`-Hülle: `status`, `method`, `score`, `age_estimation`, `warnings`. Dazu kommt ein nur im eigenständigen Modus verfügbarer `user_image`-Block zur Gesichtsdetektion. Sie enthält **nicht** `reference_image`, `video_url`, `matches`, `face_quality` oder `face_luminance`. In Workflow-Sitzungen gibt es kein separates Array: Das geschätzte Alter erscheint als `liveness_checks[].age_estimation` in `GET /v3/session/{sessionId}/decision/`. Quelle: `apis/serializers/age_estimation.py:50-55` (`AgeEstimationResponseSerializer`). Die Hülle wird in `apis/views/age_estimation.py:138-174` zusammengesetzt.

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `request_id` | Zeichenkette (UUID) | Nein | Gespeicherte Sitzungs-ID, wenn `save_api_request=true` (Standard). Andernfalls eine flüchtige Korrelations-UUID. | `"3b1f1e2c-…"` |
| `age_estimation` | Objekt | Nein | Ergebnis-Hülle: `status` (`Approved` / `Declined`), `method` (immer `PASSIVE`), `score` (Liveness 0-100, nullable), `age_estimation` (geschätztes Alter in Jahren des größten Gesichts, nullable), `user_image` (`entities[]` mit `age`, `bbox` `[x_min, y_min, x_max, y_max]`, `confidence`, `gender` für jedes Gesicht; außerdem `best_angle`), `warnings[]`. | `{ … }` |
| `vendor_data` | Zeichenkette | Ja | Aus der Anfrage übernommenes `vendor_data`. | `null` |
| `metadata` | Objekt | Ja | Aus der Anfrage übernommenes `metadata`. | `null` |
| `created_at` | Zeichenkette (ISO 8601) | Nein | Serverseitiger Zeitstempel der Anfrage. | `"2026-05-17T10:22:13.512941+00:00"` |

```json theme={null}
{
  "request_id": "3b1f1e2c-7777-4d2c-9eb6-fdc6c7c92ef9",
  "age_estimation": {
    "status": "Approved",
    "method": "PASSIVE",
    "score": 94.10,
    "age_estimation": 28.7,
    "user_image": {
      "entities": [
        { "age": 28.7, "bbox": [40, 40, 100, 100], "confidence": 0.72, "gender": "male" }
      ],
      "best_angle": 0
    },
    "warnings": []
  },
  "vendor_data": null,
  "metadata": null,
  "created_at": "2026-05-17T10:22:13.512941+00:00"
}
```

### Biometrische Authentifizierung

Die biometrische Authentifizierung führt dieselbe Liveness- und Gesichtsabgleich-Pipeline aus, die beim Standard-KYC verwendet wird. Das erfasste Gesicht wird jedoch mit dem vorhandenen Referenzbild des Benutzers verglichen, statt mit einem frisch per OCR ausgelesenen Dokumentporträt. Dafür gibt es keinen eigenen Serializer: `GET /v3/session/{sessionId}/decision/` liefert die Standardobjekte [Liveness-Prüfung](#liveness-prüfung) und [Gesichtsabgleich](#gesichtsabgleich) unter `liveness_checks[]` und `face_matches[]`. Der Workflow der Sitzung ist mit `workflow_type = "biometric_authentication"` konfiguriert (`WorkflowTypeChoices`, `common/config/choices.py:636`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `liveness_checks` | Array aus [Liveness-Prüfung](#liveness-prüfung) | Nein | Liveness-Ergebnis für den Authentifizierungsversuch. | `[ { "status": "Approved", … } ]` |
| `face_matches` | Array aus [Gesichtsabgleich](#gesichtsabgleich) | Nein | Abgleichergebnis mit dem hinterlegten Referenzbild. `source_image_session_id` ist auf die eigene `session_id` der Sitzung gesetzt: Das Referenzgesicht (das übergebene `portrait_image` oder das gespeicherte Gesicht, das über `vendor_data` wiederverwendet wird, wenn `portrait_image` fehlt) wird unter der Authentifizierungssitzung selbst gespeichert (`face/views/face.py:656-659`). | `[ { "status": "Approved", "source_image_session_id": "…", … } ]` |
| `status` | string | Nein | Sitzungsstatus auf oberster Ebene (siehe [Status-Enum](#status-aufzählung)). | `"Approved"` |

```json theme={null}
{
  "session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
  "status": "Approved",
  "liveness_checks": [
    {
      "status": "Approved",
      "method": "PASSIVE",
      "score": 95.10,
      "reference_image": "https://<media-host>/.../reference.jpg?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": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
      "source_image": "https://<media-host>/.../source.jpg?signature=...",
      "target_image": "https://<media-host>/.../target.jpg?signature=...",
      "node_id": "biometric_auth_face_match",
      "warnings": []
    }
  ]
}
```

### KYB-Unternehmensregister

Wird pro im Unternehmensregister bestätigtem Unternehmen in einem KYB-Workflow zurückgegeben. Erscheint als `registry_checks[]` in `GET /v3/session/{sessionId}/decision/` für Unternehmenssitzungen. Quelle: `kyb/serializers/kyb.py:939-964` (`RegistryCheckV3Serializer`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `node_id` | string \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_registry"` |
| `data_resolved` | boolean | Nein | `true`, sobald der Registerabruf abgeschlossen ist (oder `is_from_registry` den Wert `false` hat, was bedeutet, dass die Daten manuell eingegeben wurden). | `true` |
| `company` | object | Nein | Vollständiger Unternehmens-Payload: siehe [Unternehmensobjekt](#unternehmensobjekt) unten. | `{ … }` |
| `ownership_structure` | object | Ja | Die vom Unternehmensregister nachgewiesene Anteilsstruktur: `shareholders[]` und `beneficial_owners[]`, wobei jeder Eigentümer seine Registerdaten, seine Beteiligung und das kanonische `shareholding` enthält. | `{ "shareholders": [...], "beneficial_owners": [] }` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

#### Unternehmensobjekt

Aus `kyb/serializers/kyb.py:220-321` (`KYBCompanyResponseSerializer`).

| Feld | Typ | Nullable | Beschreibung |
| - | - | - | - |
| `uuid` | string (UUID) | Nein | Interne Unternehmenskennung. |
| `node_id` | string \| null | Ja | Kennung des Workflow-Knotens. |
| `status` | string | Nein | Funktionsstatus (`FeatureStatusChoices`). |
| `registry_status` | string | Ja | Unternehmensstatus aus dem Unternehmensregister (`active`, `dissolved`, …). |
| `data_resolved` | boolean | Nein | Gleiche Definition wie im übergeordneten Objekt. |
| `company_name` | string | Ja | Eingetragener Unternehmensname. |
| `registration_number` | string | Ja | Registernummer. |
| `country_code` | string (ISO 3166-1 alpha-2) | Ja | Gründungsland. |
| `region` | string | Ja | ISO-3166-2-Unterteilung, sofern zutreffend (z. B. `US-CA`). |
| `company_type` | string | Ja | Rechtsform (`LLC`, `SL`, …). |
| `incorporation_date` | string (YYYY-MM-DD) | Ja | Gründungsdatum. |
| `registered_address` | string | Ja | Eingetragene rechtliche Anschrift. |
| `tax_number` | string | Ja | Steuer- bzw. USt-Identifikationsnummer. |
| `risk_level` | string | Ja | Vom Anbieter gelieferte Risikostufe. |
| `verification_status` | string | Ja | Internes Enum für den Verifizierungsstatus. |
| `is_from_registry` | boolean | Nein | `true`, wenn die Daten aus dem Unternehmensregister stammen (statt manueller Eingabe). |
| `fetch_status` | string | Ja | `pending`, `resolved`, `failed`. |
| `alternative_names` | string | Ja | Kommagetrennte alternative Handelsnamen. |
| `nature_of_business` | string | Ja | Freitext-Beschreibung der Geschäftstätigkeit. |
| `registered_capital` | string | Ja | Eingetragenes Kapital als lesbare Zeichenkette. |
| `registered_capital_amount` | string (decimal) | Ja | Geparster Betrag des eingetragenen Kapitals. |
| `registered_capital_currency` | string (ISO 4217) | Ja | Währungscode. |
| `website` | string (URL) | Ja | Unternehmenswebsite. |
| `email` | string | Ja | Öffentliche Kontakt-E-Mail-Adresse. |
| `phone` | string | Ja | Öffentliche Kontakttelefonnummer. |
| `legal_entity_identifier` | string | Ja | LEI, sofern verfügbar. |
| `location_of_registration` | string | Ja | Registerbehörde bzw. Region. |
| `vat_number` | string | Ja | Für das Unternehmen übermittelte USt-IdNr. |
| `vat_validation_status` | string | Nein | Ergebnis der Validierung der USt-IdNr. oder, falls keine vorhanden ist, der `tax_number`: `valid`, `invalid`, `format_valid`, `invalid_format`, `could_not_validate` oder `not_applicable`. Siehe [USt- und Steuernummernvalidierung](https://docs.didit.me/de/business-verification/company-data.md#umsatzsteuer-id--und-steuernummernprüfung). |
| `vat_validated_number` | string | Ja | Die geprüfte Nummer, so wie die Quelle sie kennt. |
| `vat_validation_source` | string | Ja | Quelle, die den Status festgelegt hat: `eu_vies`, `pl_vat_white_list`, `no_brreg`, `ch_uid_register`, `br_receita_federal`, `co_rues`, `cr_hacienda`, `ec_sri`, `py_dnit` oder `format_rules`. |
| `vat_validated_name` | string | Ja | Bei der Quelle registrierter Name (leer, wenn sie keinen angibt). |
| `vat_validated_address` | string | Ja | Bei der Quelle registrierte Adresse (leer, wenn nicht angegeben). |
| `vat_checked_at` | string (ISO 8601) | Ja | Zeitstempel der Prüfung; `null`, wenn keine Prüfung stattfand. |
| `financial_summary` | object | Ja | Momentaufnahme der neuesten Finanzkennzahlen, sofern vom Unternehmensregister bereitgestellt. |
| `officers` | array of objects | Nein | Für B2C geeignete Liste der Organmitglieder: `{ uuid, name, designation, role, nationality, is_active, kyc_status, kyc_session_url }`. |
| `beneficial_owners` | array of objects | Nein | Für B2C geeignete Liste der wirtschaftlich Berechtigten (UBO): `{ 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 }`. |
| `addresses` | array of objects | Ja | Adressdetails aus dem Unternehmensregister. |
| `industries` | array of objects | Ja | Klassifikationen nach dem Muster SIC/NAICS. |
| `accounts` | array of objects | Ja | Metadaten zu eingereichten Abschlüssen. |
| `registry_data` | object | Ja | Normalisierte Registerdetails von Didit (Ergebnis der Eigentümerermittlung, Korrekturen in der Konsole, Registerfakten ohne eigenes Feld). Keine stabile Schnittstelle. |
| `user_provided_data` | object | Ja | Momentaufnahme der vom Benutzer bearbeiteten Felder. |
| `confirmed_by_user_at` | string (ISO 8601) | Ja | Zeitstempel, zu dem der Benutzer die extrahierten Daten bestätigt hat. |
| `last_console_edit_at` | string (ISO 8601) | Ja | Zeitstempel der letzten Bearbeitung in der Konsole. |
| `is_editable` | boolean | Nein | `true`, solange die aus dem Unternehmensregister stammenden Daten vom Endbenutzer noch bearbeitet werden können. |

```json theme={null}
{
  "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",
    "vat_number": "ESB12345678",
    "vat_validation_status": "valid",
    "vat_validated_name": "SANTE CLINICS SL",
    "vat_validated_address": "CALLE MAYOR 1, 28001 MADRID",
    "vat_checked_at": "2026-05-17T10:11:05Z",
    "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-Dokument

Wird pro Knoten zurückgegeben, der KYB-Nachweisdokumente erfasst. Erscheint als `document_verifications[]` in `GET /v3/session/{sessionId}/decision/` für Unternehmenssitzungen: ein Eintrag pro `node_id`, wobei `items[]` jedes hochgeladene Dokument auflistet. Quelle: `kyb/serializers/kyb.py:1053-1068` (`DocumentVerificationV3Serializer`); jedes Element entspricht `kyb/serializers/kyb.py:811-851` (`KYBDocumentResponseSerializer`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Aggregierter Status über alle Dokumente dieses Knotens: `Approved` nur, wenn jedes Dokument der Pipeline genehmigt ist; `Declined`, wenn eines abgelehnt ist; andernfalls `In Review`; `Not Finished`, solange ausstehend. Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `node_id` | string \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_kyb_documents"` |
| `items` | array von [KYB-Dokumentelement-Objekten](#kyb-dokumentelement-objekt) | Nein | Ein Eintrag pro hochgeladenem oder angefordertem Dokument. | `[…]` |
| `groups` | object | Nein | Anzahl je Dokumentgruppe: `{ <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_groups` | array von strings | Nein | Dokumentgruppen, die durch die Workflow-Konfiguration vorgegeben sind. | `["incorporation_certificate", "shareholder_register"]` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

#### KYB-Dokumentelement-Objekt

| Feld | Typ | Nullable | Beschreibung |
| - | - | - | - |
| `uuid` | string (UUID) | Nein | Interne Dokumentkennung. |
| `document_type` | string | Ja | Übergeordnete Gruppe (`incorporation_certificate`, `shareholder_register`, …). |
| `document_subtype` | string | Ja | Anbieterspezifischer Untertyp. |
| `document_group` | string | Ja | Spiegelt `document_type` wider (Alias zur besseren Übersicht). |
| `file_url` | string (URL) | Ja | Vorsignierte URL zur bereinigten Datei. |
| `original_filename` | string | Ja | Dateiname, wie er hochgeladen wurde. |
| `file_size` | integer | Ja | Dateigröße in Byte. |
| `status` | string | Nein | Status des einzelnen Dokuments (`FeatureStatusChoices`). |
| `created_at` | string (ISO 8601) | Nein | Zeitstempel des Uploads. |
| `cross_check_result` | object | Ja | Ergebnis der Kreuzprüfung mit dem Register oder anderen Dokumenten. |
| `document_metadata` | object | Ja | Dieselbe gefilterte Metadatenstruktur wie `document_metadata` bei POA. |
| `description` | string | Ja | Vom Prüfer oder vom System angegebene Beschreibung. |
| `is_requested` | boolean | Nein | `true`, wenn der Workflow dieses Dokument erwartet hat. |
| `ocr_data` | object | Ja | Per OCR extrahierte Felder, sofern verfügbar. |
| `is_console_upload` | boolean | Nein | `true`, wenn das Dokument von einem Prüfer in der Konsole hochgeladen wurde (wird aus dem Gesamtergebnis ausgeschlossen). |
| `is_confirmed` | boolean | Nein | `true`, wenn der Prüfer das Dokument ausdrücklich bestätigt hat. |

```json theme={null}
{
  "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://<media-host>/.../incorporation.pdf?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-Schlüsselperson

Wird pro Knoten „Key People“ in einem KYB-Workflow zurückgegeben. Erscheint als `key_people_checks[]` in `GET /v3/session/{sessionId}/decision/` für Unternehmenssitzungen. Quelle: `kyb/serializers/kyb.py:967-1050` (`KeyPeopleCheckV3Serializer`).

| Feld | Typ | Nullable | Beschreibung | Beispiel |
| - | - | - | - | - |
| `status` | string | Nein | Siehe [Status-Enum](#status-aufzählung). | `"Approved"` |
| `node_id` | string \| null | Ja | Kennung des Workflow-Knotens (V3). | `"first_key_people"` |
| `registry` | object | Nein | Aus dem Register extrahiertes `{ officers[], beneficial_owners[] }`. Die Amtsträger folgen `KYBPersonResponseSerializer` (`kyb/serializers/kyb.py:533-645`). Wirtschaftlich Berechtigte folgen `KYBBeneficialOwnerResponseSerializer` (`kyb/serializers/kyb.py:648-788`), der zusätzlich `date_of_birth`, `country_of_birth`, `email`, `company_name`, `registration_number`, `entity_type`, `roles`, `ownership_min_shares`, `ownership_max_shares`, `child_beneficial_owners` und `effective_ownership_percent` enthält. Beide enthalten pro Partei eine AML- und KYC-Anreicherung (`aml_status`, `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": [...] }` |
| `submitted` | object | Nein | `{ parties[] }` - Einträge, die das Unternehmen über den Ablauf für Schlüsselpersonen bestätigt oder eingereicht hat (`BusinessParty`-Zeilen mit `source=USER`). Jede Partei folgt `BusinessPartySubmissionResponseSerializer` (`kyb/serializers/party.py:146-194`): `uuid`, `entity_type`, `source`, `name`, `first_name`, `last_name`, `company_name`, `registration_number`, `email`, `nationality`, `phone_number`, `date_of_birth`, `position`, `custom_fields`, `is_active`, `is_skipped`, `requires_verification`, `roles[]` (`{ role, ownership_percent, voting_percent }`), `kyc_session_id`, `kyc_session_status`, `kyc_session_url`, `kyc_session_deleted`, `kyb_sub_session_id`, `kyb_sub_session_status`, `kyb_sub_session_url`, `kyb_sub_session_deleted`, `verification_workflow_type`, `verification_workflow_id`, `verification_workflow_label`, `verification_workflow_features` und `didit_internal_id`. `kyc_session_deleted` bzw. `kyb_sub_session_deleted` kennzeichnen eine untergeordnete Sitzung, die gelöscht wurde: Ihr Status bleibt auf dem zuletzt erreichten Wert eingefroren, die zugehörige `*_session_url` wird als `null` zurückgegeben, weil der Link nicht mehr aufgelöst werden kann, und die Partei blockiert die übergeordnete Sitzung nicht mehr (die Prüfung fällt stattdessen auf `In Review` zurück). Zum Zurücksetzen dieses Flags verwenden Sie [`PATCH /v3/session/{id}/kyb/parties/{party_uuid}/`](https://docs.didit.me/de/sessions-api/update-data#eine-partei-der-schlüsselpersonen-überspringen). | `{ "parties": [...] }` |
| `ubo_kyc_summary` | object | Ja | Anzahl der aktiven wirtschaftlich Berechtigten mit verknüpftem KYC: `{ total, approved, flagged, pending }`. `null`, wenn keine aktiven wirtschaftlich Berechtigten ein verknüpftes KYC haben. | `{ "total": 2, "approved": 2, "flagged": 0, "pending": 0 }` |
| `warnings` | array | Nein | Siehe [Warnungsobjekt](#warnungsobjekt). | `[]` |

```json theme={null}
{
  "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": "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",
        "entity_type": "person",
        "source": "USER",
        "name": "María García López",
        "first_name": "María",
        "last_name": "García López",
        "company_name": null,
        "registration_number": null,
        "email": "maria.garcia@example.com",
        "nationality": "ESP",
        "phone_number": null,
        "date_of_birth": "1990-05-12",
        "position": "Administrador único",
        "custom_fields": {},
        "is_active": true,
        "is_skipped": false,
        "requires_verification": true,
        "roles": [
          { "role": "UBO", "ownership_percent": 75.0, "voting_percent": null }
        ],
        "kyc_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
        "kyc_session_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…",
        "kyb_sub_session_id": null,
        "kyb_sub_session_status": null,
        "kyb_sub_session_url": null,
        "verification_workflow_type": "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" }
        ],
        "didit_internal_id": "user-12345"
      }
    ]
  },
  "ubo_kyc_summary": { "total": 1, "approved": 1, "flagged": 0, "pending": 0 },
  "warnings": []
}
```

## Felder auf Entscheidungsebene

Diese Schlüssel stehen neben den Funktions-Arrays bei `GET /v3/session/{sessionId}/decision/` und innerhalb von `decision` in einem Webhook.

| Feld | Typ | Nullable | Beschreibung |
| - | - | - | - |
| `status_override` | Objekt | Ja | `{ overridden_at, automatic_status }`, nachdem ein Prüfer `status` manuell gesetzt hat; `null`, wenn es sich um den automatisch ermittelten Status handelt. |
| `decision_trace` | Objekt | Nein | Wie der Status zustande kam: `status`, `decided_by` (`manual`, `automatic` oder `investigator`), `decided_at`, `automatic_status`, `terminal_node_id`, `actor`, `warning_counts` und `status_warnings`. |
| `linked_records` | Objekt | Ja | Zusammenfassungen zu `same_face`, `earlier_verifications` und `networks`; `null`, wenn es nichts anzuzeigen gibt. |
| `biometric_retention` | Objekt | Nein | `{ jurisdictions, deletes_at }`. `deletes_at` ist das Datum, an dem die biometrischen Live-Daten der Sitzung gelöscht werden, und `null`, wenn noch kein Datum gilt. |
| `database_validation_not_performed_reason` | Objekt | Ja | `{ code, message }`, das erklärt, warum eine konfigurierte Datenbankvalidierung kein Ergebnis erzeugt hat. |
| `assignee`, `waiting_since`, `sla_due_at` | Objekt, Datum und Uhrzeit | Ja | Der Console-Prüfer, dem die Sitzung zugewiesen ist, und die Prüfungsuhr der Sitzung; die Uhr ist `null`, sofern die Sitzung nicht im Status `In Review` ist. |
| `shared_from_session`, `shared_from_session_number` | UUID, Ganzzahl | Ja | Die Quellsitzung einer importierten Sitzung. |
| `sandbox_scenario` | Zeichenkette | Ja | Das Szenario, mit dem eine Sandbox-Sitzung erstellt wurde. |
| `fraud_check` | Objekt | Ja | Das Ergebnis der Fraud Check API; `null` für alle anderen Sitzungen. |
| `full_session_video`, `full_session_video_recorded_at` | URL, Datum und Uhrzeit | Ja | Die Aufnahme und der Zeitpunkt, zu dem sie entstand. Wird nur zurückgegeben, wenn Ihre Organisation Video der gesamten Sitzung aufzeichnet. |

Informationen zum Lesen dieser Felder finden Sie unter [Sitzung abrufen](https://docs.didit.me/de/sessions-api/retrieve-session.md#status-entscheidungsverlauf-und-prüffelder).

## Biometrische Einwilligung

Jede Entscheidung zur Benutzerverifizierung und jeder Sitzungs-Webhook enthält ein einzelnes `biometric_consent`-Objekt (kein Array). Es gibt an, ob die Sitzung eine ausdrückliche biometrische Einwilligung erforderte, warum dies erforderlich war und welcher Nachweis für die Antwort vorliegt. Es ist `null`, wenn die Sitzung nie ausgewertet wurde, zum Beispiel bei einem Workflow ohne Gesichtsaufnahme. Quelle: `BiometricConsentDecisionSerializer` (`sessions/serializers/biometric_consent.py`). Wann der Schritt erscheint und was die einzelnen Fälle bedeuten, wird unter [Biometrische Einwilligung](https://docs.didit.me/de/getting-started/biometric-consent.md) erklärt.

Felder ohne erfassten Wert sind `null`, niemals ein leerer String.

| Feld | Typ | Beschreibung |
| - | - | - |
| `required` | boolean | Ob die Sitzung eine ausdrückliche biometrische Einwilligung einholen muss. Wird nie wieder auf `false` zurückgesetzt. |
| `trigger` | string (Enum) \| null | Warum eine Einwilligung erforderlich ist oder wie sie erfüllt wurde: `declared_state`, `ip_state`, `ip_unknown`, `document_issuer`, `forced` (der Modus der Anwendung ist Immer), `customer_collected` (Sie haben `biometric_consent` bei der Sitzungserstellung gesendet). `null`, solange keine Einwilligung erforderlich ist. |
| `status` | string (Enum) | `not_required`, `pending` (erforderlich, nicht erteilt), `given`, `declined` (eine Ablehnung wurde erfasst; derzeit bietet kein Didit-Bildschirm eine Ablehnung an). |
| `given_at` | string (ISO 8601) \| null | Zeitpunkt, zu dem die Einwilligung erteilt wurde. Bei `customer_collected` der von Ihnen gesendete `given_at`-Wert. |
| `declined_at` | string (ISO 8601) \| null | Zeitpunkt, zu dem eine Ablehnung erfasst wurde. |
| `text_version` | string \| null | Versionskennung des Einwilligungstexts, den die Person beantwortet hat, oder des von Ihnen gesendeten Texts. |
| `text_hash` | string \| null | SHA-256 (hex) des exakt angezeigten Texts in der Sprache, in der er angezeigt wurde. |
| `locale` | string \| null | Sprache, in der der Text angezeigt wurde. |
| `policy_url` | string \| null | Die Richtlinie zu biometrischen Daten, auf die der Schritt verlinkt hat. |
| `step` | string \| null | Workflow-Schritt, auf dem sich die Sitzung befand, als die Person geantwortet hat (zum Beispiel `LIVENESS`). |
| `node_id` | string \| null | Workflow-Graph-Knoten, auf dem sich die Sitzung befand, als die Person geantwortet hat. |
| `ip_address` | string \| null | Adresse, von der die Antwort kam. |
| `ip_country_code` | string \| null | ISO-3166-1-Alpha-2-Ländercode der Adresse der Antwort. |
| `ip_state` | string \| null | ISO-3166-2-Region der Adresse der Antwort (zum Beispiel `US-IL`). |
| `ip_city` | string \| null | Stadt der Adresse der Antwort. |
| `user_agent` | string \| null | User Agent der Anfrage, mit der geantwortet wurde. |
| `detected_ip_address` | string \| null | Adresse der Person, von der die Anforderung zuletzt ausgewertet wurde. Kann sich von `ip_address` unterscheiden, wenn die Person auf einem anderen Gerät geantwortet hat. |
| `detected_country_code` | string \| null | ISO-3166-1-Alpha-2-Ländercode der erkannten Adresse. |
| `detected_state` | string \| null | ISO-3166-2-Region der erkannten Adresse. |
| `detected_city` | string \| null | Stadt der erkannten Adresse. |
| `declared_state` | string \| null | Von Ihnen angegebene ISO-3166-2-Region: `user_state` oder der Bundesstaat einer US-Adresse in `expected_details`. |
| `document_state` | string \| null | ISO-3166-2-Untergliederung, in der das Identitätsdokument ausgestellt wurde, beim Erfassen des Ausweises gelesen. |
| `jurisdictions` | array of string | US-Bundesstaaten (USPS-Codes, zum Beispiel `IL`), für die das Biometrie-Gesetz für die Person gilt. `US`, wenn die Nachweise die Person in den USA verorten, aber kein Bundesstaat bekannt ist. Leer, wenn keines zutrifft. |
| `retention_months` | integer \| null | Die kürzeste biometrische Aufbewahrungsfrist in Monaten für die `jurisdictions`. `null`, wenn keines zutrifft. |
| `reason` | string (Enum) \| null | `BIOMETRIC_CONSENT_UNSUPPORTED_SDK`: Eine Einwilligung war erforderlich, und ein natives SDK unterhalb von 4.10.0 oder ein SDK, das seine Version nicht gemeldet hat, hat ein Gesicht ohne den Schritt erfasst. `status` bleibt `pending`, oder `given`, wenn die Person später auf der gehosteten Verifizierungsseite zugestimmt hat. `BIOMETRIC_CONSENT_DECLINED`: Eine Ablehnung wurde erfasst (sie ersetzt den SDK-Grund). Sonst `null`, und immer `null`, wenn die Sitzung keine Einwilligung erforderte. |
| `decline_reason` | string \| null | `BIOMETRIC_CONSENT_DECLINED`, wenn eine erfasste Ablehnung die Sitzung beendet hat, sonst `null`. |
| `face_data_deleted_at` | string (ISO 8601) \| null | Zeitpunkt, zu dem die Ablehnung die Gesichtsbilder, Videos und biometrischen Templates der Sitzung gelöscht hat. `null`, solange keine Ablehnung erfasst wurde. |

Eine Sitzung in Illinois, die mit einem nativen SDK unterhalb von 4.10.0 durchgeführt wurde und bei der das Selfie ohne den Schritt aufgenommen wurde:

```json theme={null}
{
  "required": true,
  "trigger": "ip_state",
  "status": "pending",
  "given_at": null,
  "declined_at": null,
  "text_version": null,
  "text_hash": null,
  "locale": null,
  "policy_url": null,
  "step": null,
  "node_id": null,
  "ip_address": null,
  "ip_country_code": null,
  "ip_state": null,
  "ip_city": null,
  "user_agent": null,
  "detected_ip_address": "203.0.113.42",
  "detected_country_code": "US",
  "detected_state": "US-IL",
  "detected_city": "Chicago",
  "declared_state": null,
  "document_state": null,
  "jurisdictions": ["IL"],
  "retention_months": 36,
  "reason": "BIOMETRIC_CONSENT_UNSUPPORTED_SDK",
  "decline_reason": null,
  "face_data_deleted_at": null
}
```

Eine Person über ein VPN mit Ausgang außerhalb der USA, die auf der gehosteten Verifizierungsseite zugestimmt hat:

```json theme={null}
{
  "required": true,
  "trigger": "declared_state",
  "status": "given",
  "given_at": "2026-10-13T18:31:07.412000Z",
  "declined_at": null,
  "text_version": "bio-consent-2026-10-12",
  "text_hash": "9b2f0c5e4d8a7f61c3e2b4a5d6f7081923a4b5c6d7e8f90a1b2c3d4e5f6a7b8c",
  "locale": "en",
  "policy_url": "https://didit.me/legal/biometric-data-policy",
  "step": "LIVENESS",
  "node_id": "feature_liveness_1",
  "ip_address": "198.51.100.23",
  "ip_country_code": "ES",
  "ip_state": "ES-M",
  "ip_city": "Madrid",
  "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
  "detected_ip_address": "198.51.100.23",
  "detected_country_code": "ES",
  "detected_state": "ES-M",
  "detected_city": "Madrid",
  "declared_state": null,
  "document_state": null,
  "jurisdictions": ["IL"],
  "retention_months": 36,
  "reason": null,
  "decline_reason": null,
  "face_data_deleted_at": null
}
```

## Status-Aufzählung

Zwei verwandte Wertebereiche verwenden den Feldnamen `status`. Jedes Berichtsobjekt auf Funktionsebene auf dieser Seite verwendet die Aufzählung auf Funktionsebene. Der Top-Level-`status` der übergeordneten Sitzung verwendet die umfassendere Sitzungsaufzählung.

### Status auf Funktionsebene

Wird vom Feld `status` jedes Berichtsobjekts verwendet. Quelle: `common/config/choices.py:343-348` (`FeatureStatusChoices`).

| Wert | Bedeutung |
| - | - |
| `Not Finished` | Die Funktion wurde bereitgestellt, der Benutzer hat sie aber noch nicht abgeschlossen. |
| `Approved` | Die Funktion hat alle Prüfungen bestanden. |
| `Declined` | Die Funktion hat mindestens eine harte Prüfung nicht bestanden (siehe `warnings[]` mit `log_type: "error"`). |
| `In Review` | Die Funktion hat weiche Fehlersignale ausgelöst und wartet auf die manuelle Prüfung (siehe `warnings[]` mit `log_type: "warning"`). |
| `Resub Requested` | Ein Prüfer hat den Benutzer aufgefordert, diese Funktion erneut einzureichen. |

Telefonverifizierung, E-Mail-Verifizierung und Ausweisverifizierung können zusätzlich `Expired` zurückgeben, wenn ihr Schritt abläuft (`PhoneStatusChoices` in `common/config/choices.py:377-382`, `EmailStatusChoices` in `common/config/choices.py:434-439`).

### Status auf Sitzungsebene

Wird vom Top-Level-`status` der übergeordneten Sitzung verwendet. Quelle: `common/config/choices.py:106-117` (`StatusChoices`).

| Wert | Bedeutung |
| - | - |
| `Not Started` | Die Sitzung wurde erstellt, der Benutzer hat sie aber noch nicht begonnen. |
| `In Progress` | Der Benutzer hat den Ablauf gestartet, das Ergebnis ist noch nicht endgültig. |
| `Approved` | Die Sitzung hat alle Prüfungen bestanden. |
| `Declined` | Die Sitzung hat mindestens eine harte Prüfung nicht bestanden. |
| `In Review` | Die Sitzung wartet auf die manuelle Prüfung. |
| `Expired` | Die Sitzung ist abgelaufen, bevor sie abgeschlossen wurde. |
| `Abandoned` | Der Benutzer hat den Ablauf verlassen, ohne ihn abzuschließen. |
| `Kyc Expired` | Das Gültigkeitsfenster des KYC ist abgelaufen (wird in Abläufen zur erneuten Verifizierung verwendet). |
| `Resubmitted` | Der Benutzer hat nach einer früheren Ablehnung erneut eingereicht; diese Sitzung wurde durch eine neuere ersetzt. |
| `Awaiting User` | Das System wartet auf eine Aktion des Benutzers (z. B. die Eingabe eines OTP). |

> [!TIP]
>
> Die endgültigen Sitzungswerte sind `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired` und `Abandoned`. Eine Sitzung kann ihre Gesamtentscheidung erreichen, während eine einzelne Funktion weiterhin `In Review` ist.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.