Skip to main content

Overview

Proof-of-address (POA) verification accepts a single PDF or image (TIFF, JPG, JPEG, PNG, WEBP, optionally ZIP-compressed) up to 15 MB, runs document-type classification, LLM-based extraction, and PDF/EXIF forensics, and returns:
  • The extracted address — both raw and structured (street_1, city, region, postal_code, lat/lng).
  • Document metadata — file size, content type, creation and modified dates, EXIF dates, signature info, and any overlay-manipulation evidence from PDF forensics.
  • Name match scores against the verified ID document and against expected details supplied at session creation.
  • Bank-related extra fields (account number, IBAN, sort code, routing number, SWIFT/BIC, branch) when the document is a bank statement.
Didit proof of address report screenshot showing extracted address fields and document type
POA extraction performs unstructured-text reading, which introduces a 5–15 second latency per document. Webhooks fire only when the entire workflow step completes — do not poll the decision endpoint faster than every 5 s during this window.

Where it appears in API responses

The decision endpoint returns POA as the plural array poa_verifications[] in GET /v3/session/{sessionId}/decision/. Each entry is one execution of the POA node in your workflow; sessions with multiple POA steps (e.g., bank statement + utility bill) produce one entry per execution with its own node_id.
GET /v3/session/{sessionId}/decision/
  ──▶ { "poa_verifications": [ { node_id, status, document_type, poa_address, … }, … ] }
The shape below mirrors the canonical schema — see Data models.

Schema

See Proof of address in the Data Models reference for the canonical schema.
interface POAV3 {
  status: 'Not Finished' | 'Approved' | 'Declined' | 'In Review';
  node_id: string | null;

  issuing_state: string | null;         // ISO 3166-1 alpha-3
  document_type:                        // never null — falls back to 'UNKNOWN'
    | 'UTILITY_BILL'
    | 'BANK_STATEMENT'
    | 'GOVERNMENT_ISSUED_DOCUMENT'
    | 'OTHER_POA_DOCUMENT'
    | 'UNKNOWN';
  document_subtype: string;             // e.g. 'ELECTRICITY_BILL', 'ACCOUNT_STATEMENT';
                                        // never null — falls back to 'UNKNOWN'
  issuer: string | null;
  issue_date: string | null;            // YYYY-MM-DD
  expiration_date: string | null;       // YYYY-MM-DD when present

  // Extracted address
  poa_address: string | null;           // raw, single-line
  poa_formatted_address: string | null; // geocoded/formatted
  poa_parsed_address: {
    address_type?: string;
    street_1?: string;
    street_2?: string;
    city?: string;
    region?: string;
    postal_code?: string;
    country?: string;                   // ISO 3166-1 alpha-2
    raw_results?: object;
    document_location?: { latitude: number; longitude: number };
  } | null;

  document_file: string | null;         // presigned URL, expires after ~4 hours
  document_language: string | null;     // ISO 639-1, e.g. 'en'
  name_on_document: string | null;

  // Expected details (when supplied at session creation)
  expected_details_address: string | null;
  expected_details_formatted_address: string | null;
  expected_details_parsed_address: object | null;

  // Match scores (float, 0-100)
  name_match_score_expected_details: number | null;
  name_match_score_id_verification: number | null;

  // PDF + image forensics
  document_metadata: {
    file_size: number | null;
    content_type: string | null;
    creation_date: string | null;
    modified_date: string | null;
    creator: string | null;
    producer: string | null;
    software: string | null;
    encryption: string | null;
    is_signed: boolean | null;
    is_tampered: boolean | null;
    signature_info: object | null;
    exif_original_date: string | null;
    exif_digitized_date: string | null;
    processed_by_known_editor: boolean | string | null;
    has_different_creation_mod_date: boolean | null;
    overlay_manipulation: {
      detected: boolean;
      analyzed: boolean;
      signals: string[];                // 'duplicate_font_subset', 'glyph_fragmentation'
      duplicate_font_subsets: object[];
      fragmented_fonts: object[];
      manipulated_regions: {
        page: number;
        x: number;
        y: number;
        width: number;
        height: number;
        page_width: number;
        page_height: number;
      }[];
    } | null;                           // null for non-PDF uploads or when not analyzed
  } | null;

  // Bank-related and custom fields
  extra_fields: {
    bank_account_number: string | null;
    bank_iban: string | null;
    bank_sort_code: string | null;
    bank_routing_number: string | null;
    bank_swift_bic: string | null;
    bank_branch_name: string | null;
    bank_branch_address: string | null;
    document_phone_number: string | null;
    additional_names: string[];
    [customField: string]: unknown;
  };

  extra_files: string[];                // presigned URLs for additional uploaded files

  warnings: Warning[];                  // see Data Models — Warning object
}
Each entry in warnings[] is a Warning object: { feature, risk, additional_data, log_type, short_description, long_description, node_id }, with feature always "PROOF_OF_ADDRESS" for this report.

Status values

status uses the feature-level status enum (FeatureStatusChoices).
ValueMeaning
Not FinishedThe POA node has not completed for this session (default state).
ApprovedThe document parsed cleanly and no warning resolved to Decline or Review.
In ReviewAt least one configurable warning is set to Review for your workflow (and nothing declined).
DeclinedA hard-decline warning fired (MISSING_ADDRESS_INFORMATION, POA_DOCUMENT_EXPIRED, INVALID_DOCUMENT_TYPE, UNABLE_TO_VALIDATE_DOCUMENT_AGE), or a configurable warning is set to Decline for your workflow.
Custom status rules configured on the workflow node can further adjust the computed status; rules combine with precedence Declined > In Review > Approved. See Proof of address warnings for the full risk-to-action mapping, including the workflow-only retry behavior of FUTURE_ISSUE_DATE.

PDF overlay-manipulation evidence

When the submitted document is a PDF, document_metadata.overlay_manipulation may contain forensic evidence of suspected text overlays:
  • detectedtrue when the check found manipulation evidence.
  • analyzedtrue when the PDF could be analysed at all.
  • signals — the checks that fired (duplicate_font_subset, glyph_fragmentation).
  • manipulated_regions — page-coordinate rectangles around the suspected edited text. Each rectangle uses the PDF page coordinate space (x, y, width, height, page_width, page_height) so reviewers can highlight the affected area in a PDF preview.
The field is null when the document is not a PDF or the PDF could not be analysed. When detected=true, the system also emits a SUSPECTED_DOCUMENT_MANIPULATION warning whose additional_data mirrors the signals and rectangles above (unless a stronger signal — modification after digital signing, is_tampered=true — took priority, in which case additional_data describes the signature tampering instead).

Examples

Approved — bank statement

{
  "poa_verifications": [
    {
      "status": "Approved",
      "node_id": "feature_poa_1",
      "issuing_state": "USA",
      "document_type": "BANK_STATEMENT",
      "document_subtype": "ACCOUNT_STATEMENT",
      "issuer": "National Bank",
      "issue_date": "2026-04-15",
      "expiration_date": null,
      "document_language": "en",
      "name_on_document": "John A. Smith",
      "poa_address": "123 Main St, Apartment 4B, New York, NY 10001",
      "poa_formatted_address": "123 Main St, Apartment 4B, New York, NY 10001, USA",
      "poa_parsed_address": {
        "address_type": "Street",
        "street_1": "123 Main St",
        "street_2": "Apartment 4B",
        "city": "New York",
        "region": "NY",
        "postal_code": "10001",
        "country": "US",
        "document_location": { "latitude": 40.7128, "longitude": -74.0060 }
      },
      "document_file": "https://<media-host>/.../poa.pdf?X-Amz-Expires=14400",
      "document_metadata": {
        "file_size": 246810,
        "content_type": "application/pdf",
        "creation_date": "2026-04-15",
        "modified_date": "2026-04-15",
        "creator": "PDFKit",
        "producer": "Quartz",
        "software": null,
        "encryption": null,
        "is_signed": false,
        "is_tampered": false,
        "signature_info": null,
        "exif_original_date": null,
        "exif_digitized_date": null,
        "processed_by_known_editor": false,
        "has_different_creation_mod_date": false,
        "overlay_manipulation": null
      },
      "name_match_score_expected_details": 100,
      "name_match_score_id_verification": 98,
      "expected_details_address": null,
      "expected_details_formatted_address": null,
      "expected_details_parsed_address": null,
      "extra_fields": {
        "bank_account_number": "****1234",
        "bank_iban": null,
        "bank_sort_code": null,
        "bank_routing_number": "021000089",
        "bank_swift_bic": "NABNUS33",
        "bank_branch_name": "Manhattan Midtown",
        "bank_branch_address": "111 Wall St, New York, NY",
        "document_phone_number": null,
        "additional_names": []
      },
      "extra_files": [],
      "warnings": []
    }
  ]
}

Declined — overlay manipulation + name mismatch

{
  "poa_verifications": [
    {
      "status": "Declined",
      "node_id": "feature_poa_1",
      "issuing_state": "GBR",
      "document_type": "UTILITY_BILL",
      "document_subtype": "ELECTRICITY_BILL",
      "issuer": "BritishEnergy",
      "issue_date": "2026-03-10",
      "expiration_date": null,
      "document_language": "en",
      "name_on_document": "JOHN B SMYTH",
      "poa_address": "44 King's Road, London, SW3 4UD",
      "poa_formatted_address": "44 King's Road, London, SW3 4UD, United Kingdom",
      "poa_parsed_address": {
        "street_1": "44 King's Road",
        "city": "London",
        "postal_code": "SW3 4UD",
        "country": "GB",
        "document_location": { "latitude": 51.4880, "longitude": -0.1690 }
      },
      "document_file": "https://<media-host>/.../poa.pdf?X-Amz-Expires=14400",
      "document_metadata": {
        "file_size": 412910,
        "content_type": "application/pdf",
        "creation_date": "2026-03-10",
        "modified_date": "2026-05-12",
        "creator": "Adobe Acrobat Pro",
        "producer": "Adobe PDF Library",
        "software": "Adobe Acrobat",
        "encryption": null,
        "is_signed": false,
        "is_tampered": false,
        "signature_info": null,
        "exif_original_date": null,
        "exif_digitized_date": null,
        "processed_by_known_editor": false,
        "has_different_creation_mod_date": true,
        "overlay_manipulation": {
          "detected": true,
          "analyzed": true,
          "signals": ["duplicate_font_subset", "glyph_fragmentation"],
          "duplicate_font_subsets": [{ "page": 1, "base_font": "Helvetica" }],
          "fragmented_fonts": [],
          "manipulated_regions": [
            { "page": 1, "x": 102.4, "y": 318.1, "width": 187.0, "height": 18.0, "page_width": 595, "page_height": 842 }
          ]
        }
      },
      "name_match_score_expected_details": 62,
      "name_match_score_id_verification": 60,
      "expected_details_address": null,
      "expected_details_formatted_address": null,
      "expected_details_parsed_address": 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": []
      },
      "extra_files": [],
      "warnings": [
        {
          "feature": "PROOF_OF_ADDRESS",
          "risk": "SUSPECTED_DOCUMENT_MANIPULATION",
          "additional_data": {
            "reason": "Overlay-text manipulation detected: same base font embedded with multiple subset prefixes on 1 page(s).",
            "detection_method": "overlay_text_manipulation",
            "signals": ["duplicate_font_subset", "glyph_fragmentation"],
            "duplicate_font_subsets": [{ "page": 1, "base_font": "Helvetica" }],
            "fragmented_fonts": [],
            "manipulated_regions": [
              { "page": 1, "x": 102.4, "y": 318.1, "width": 187.0, "height": 18.0, "page_width": 595, "page_height": 842 }
            ]
          },
          "log_type": "error",
          "short_description": "Suspected document manipulation",
          "long_description": "The system detected signs of potential document manipulation or editing.",
          "node_id": "feature_poa_1"
        },
        {
          "feature": "PROOF_OF_ADDRESS",
          "risk": "NAME_MISMATCH_ID_VERIFICATION",
          "additional_data": {
            "poa_name": "JOHN B SMYTH",
            "kyc_name": "John A. Smith",
            "match_score": 60
          },
          "log_type": "warning",
          "short_description": "Name mismatch with ID verification",
          "long_description": "The full name on the document does not match the name from the user's verified identity documents.",
          "node_id": "feature_poa_1"
        }
      ]
    }
  ]
}
document_file and extra_files[] are presigned URLs that expire after about 4 hours. Re-fetch the decision endpoint to refresh URLs. Store only the verification status and parsed address fields on your side — minimise retained document data.