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

# API de comprobante de domicilio: verificación POA y OCR

> POST /v3/poa/ de Didit verifica facturas, extractos bancarios y alquileres: OCR de dirección, autenticidad y pago por uso sin contratos.



## OpenAPI

````yaml es/openapi-25.json POST /v3/poa/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de verificación de identidad. Autentícate con el encabezado x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/poa/:
    post:
      tags:
        - Standalone APIs
      summary: Prueba de domicilio (OCR del documento + comprobaciones de dirección)
      description: >-
        Extrae y valida un documento de prueba de domicilio (facturas de
        servicios, extractos bancarios y documentos emitidos por el gobierno) en
        una sola llamada. Devuelve el emisor, las fechas de emisión y caducidad,
        el nombre del titular, la dirección sin procesar y la dirección
        analizada y geocodificada, un `status` `Approved`/`Declined` y una lista
        `warnings` que explica cada problema detectado.


        **Latencia.** La extracción se basa en un LLM: las llamadas típicas
        tardan **5–15 segundos** y los PDF de varias páginas, hasta **~30
        segundos**. Configura un tiempo de espera del cliente de **al menos 45
        segundos** y no reintentes antes de que la llamada termine.


        **Cómo funciona.** El documento (imagen o PDF, hasta 15 MB; los PDF
        cifrados requieren `document_password`) se clasifica en un tipo y un
        subtipo de documento (p. ej., `UTILITY_BILL` / `WATER_BILL`), y el
        emisor, las fechas, el nombre del titular y la dirección se obtienen
        mediante extracción basada en LLM. La dirección se analiza y se
        geocodifica en `poa_parsed_address`. El análisis forense de PDF/EXIF
        detecta manipulaciones (modificaciones posteriores a la firma digital,
        editores de PDF conocidos, manipulación con texto superpuesto,
        reexportaciones sospechosas) y devuelve
        `SUSPECTED_DOCUMENT_MANIPULATION` o `DOCUMENT_METADATA_MISMATCH`. La
        antigüedad del documento se valida con `poa_document_age_months` y el
        idioma, con `poa_languages_allowed`. Si envías `expected_address`,
        `expected_country` o `expected_first_name`/`expected_last_name`, los
        valores extraídos se contrastan con ellos y se señalan las
        discrepancias.


        **Lógica de decisión.** `status` es `Approved` salvo que al menos una
        advertencia derive en un rechazo. Los fallos graves siempre provocan un
        rechazo: `MISSING_ADDRESS_INFORMATION`, `POA_DOCUMENT_EXPIRED`,
        `INVALID_DOCUMENT_TYPE`, `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, además de
        `UNABLE_TO_EXTRACT_ISSUE_DATE` y `POA_NAME_NOT_DETECTED` (no
        configurables en este endpoint). Cinco grupos de riesgo se pueden
        configurar en cada solicitud con las opciones `poa_*_action` (`DECLINE`
        o `NO_ACTION`, todas con `DECLINE` por defecto).
        `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` y
        `UNPARSABLE_OR_INVALID_ADDRESS` son informativas en este endpoint y
        nunca provocan un rechazo. Un documento que no se puede procesar en
        absoluto devuelve `400`; un documento legible pero con problemas
        devuelve `200` con `status: "Declined"`. Revisa siempre `poa.status` y
        `poa.warnings`, no solo el código HTTP.


        **Facturación.** Cada respuesta `200` consume un crédito de la API de
        prueba de domicilio (con cargo al crédito de tu plan o a tu saldo de
        recarga). Si el saldo de la organización no cubre la llamada, el
        endpoint devuelve `403` con el error de créditos insuficientes antes de
        procesar ningún documento.


        **Persistencia de la sesión (`save_api_request`, `true` por defecto).**
        Con `true`, la llamada se guarda como una sesión de tipo API: aparece en
        la Business Console, el documento subido se almacena, el `request_id`
        devuelto es un ID de sesión real que puedes pasar a `GET
        /v3/session/{sessionId}/decision/` (la decisión expone además
        `document_file` y el análisis forense `document_metadata`, que esta
        respuesta omite) y se emite un webhook `status.updated`. Con `false`, no
        se almacena nada y `request_id` es un UUID de correlación de un solo uso
        que no se puede consultar más adelante.


        **Sandbox.** Las claves de API de sandbox omiten todo el procesamiento y
        la facturación: tras validar la solicitud (una entrada mal formada sigue
        devolviendo `400`), el endpoint devuelve un payload simulado estático
        `Approved` (una factura de electricidad ficticia de "Sandbox Power
        Co."), no se guarda ninguna sesión y no se consumen créditos.


        **Autenticación.** Envía la clave de API de tu aplicación en el
        encabezado `x-api-key`. Si faltan las credenciales o no son válidas, se
        devuelve `403` (`{"detail": "You do not have permission to perform this
        action."}`). Esta API nunca devuelve `401`.


        **Límite de solicitudes.** Presupuesto de escritura compartido de 300
        solicitudes/min por clave de API entre todos los endpoints
        POST/PATCH/DELETE; si lo superas, se devuelve `429`.


        Nota: `FUTURE_ISSUE_DATE` y `POOR_DOCUMENT_QUALITY` existen en las
        sesiones de flujo, pero este endpoint independiente nunca los genera.
        Aquí un documento con fecha futura no se rechaza automáticamente.
      operationId: post_v3poa
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - document
              properties:
                document:
                  type: string
                  format: binary
                  description: >-
                    El documento de prueba de domicilio. Extensiones permitidas:
                    `tiff`, `jpg`, `jpeg`, `png`, `pdf`, `webp`. Tamaño máximo
                    de carga: **15 MB** (los archivos más grandes se rechazan
                    con `400`). Se admiten PDF de varias páginas (la latencia es
                    mayor); los PDF cifrados requieren `document_password`. Las
                    imágenes se comprimen automáticamente antes de procesarlas.
                document_password:
                  type: string
                  description: >-
                    Contraseña para descifrar `document` cuando es un PDF
                    cifrado. Enviar un PDF cifrado sin contraseña (o con una
                    incorrecta) devuelve `400`.
                  writeOnly: true
                expected_address:
                  type: string
                  description: >-
                    Dirección que se verifica frente al documento. Se
                    geocodifica y se compara con la dirección extraída; una
                    discrepancia (o una dirección esperada que no se puede
                    geocodificar o verificar) añade
                    `ADDRESS_MISMATCH_WITH_PROVIDED`, que se rige por
                    `poa_address_mismatch_action`. La forma geocodificada se
                    devuelve en `expected_details_formatted_address` /
                    `expected_details_parsed_address`.
                  example: Av. Monseñor Tavella 1291, Salta, Argentina
                expected_country:
                  type: string
                  description: >-
                    País que se verifica contra el documento (código ISO 3166-1,
                    p. ej., `ARG` o `AR`). Si no coincide con el país del
                    documento, se añade `POA_COUNTRY_MISMATCH_WITH_PROVIDED`,
                    que se rige por `poa_address_mismatch_action`.
                  example: ARG
                expected_first_name:
                  type: string
                  description: >-
                    Nombre que se verifica contra `name_on_document`
                    (coincidencia aproximada, con soporte de transliteración).
                    Una puntuación inferior al umbral de coincidencia añade
                    `NAME_MISMATCH_WITH_PROVIDED`, que se rige por
                    `poa_address_mismatch_action`.
                  example: Sophia
                expected_last_name:
                  type: string
                  description: >-
                    Apellido que se verifica contra `name_on_document`,
                    combinado con `expected_first_name` para la puntuación de
                    coincidencia.
                  example: Martinez
                poa_languages_allowed:
                  type: string
                  description: >-
                    Lista separada por comas de los idiomas de documento
                    aceptados, como códigos ISO 639-1 (por ejemplo, `en,es,fr`).
                    Si se omite o se deja en blanco, se aceptan **los 51 idiomas
                    admitidos**. Un documento en un idioma que no está en la
                    lista añade `UNSUPPORTED_DOCUMENT_LANGUAGE` (regulado por
                    `poa_unsupported_language_action`); un código desconocido en
                    la lista devuelve `400` con el conjunto completo de códigos
                    admitidos.
                  example: en,es
                poa_document_age_months:
                  type: string
                  description: >-
                    Pares `key:value` separados por comas que fijan la
                    antigüedad máxima del documento en meses por tipo de
                    documento. Claves: `utility_bill`, `bank_statement`,
                    `government_issued_document`, `other_poa_document`; valores:
                    `1`–`120`, o `-1` para sin límite (sin comprobación de
                    antigüedad). Valores predeterminados si se omite:
                    `utility_bill:3,bank_statement:3,government_issued_document:12,other_poa_document:12`.
                    Un documento con más antigüedad que su límite se rechaza con
                    `POA_DOCUMENT_EXPIRED`. **Precaución:** cuando proporcionas
                    este campo, indica *todos* los tipos que aceptas; los tipos
                    omitidos se consideran no aceptados
                    (`POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION`, informativo)
                    y se omite su comprobación de antigüedad.
                  example: utility_bill:3,bank_statement:6
                poa_name_mismatch_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Se acepta, pero **actualmente no se aplica**: las
                    advertencias de discrepancia de nombre
                    (`NAME_MISMATCH_WITH_PROVIDED`) siguen
                    `poa_address_mismatch_action`. Configura
                    `poa_address_mismatch_action` para controlar el
                    comportamiento ante discrepancias tanto de nombre como de
                    dirección.
                poa_document_issues_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Qué hacer ante problemas de integridad del archivo; en la
                    práctica, este endpoint solo genera
                    `DOCUMENT_METADATA_MISMATCH`.
                poa_document_authenticity_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Qué hacer cuando se sospecha una manipulación del documento
                    (`SUSPECTED_DOCUMENT_MANIPULATION`); por ejemplo, el PDF se
                    modificó después de la firma digital, se procesó con un
                    editor de PDF conocido, muestra manipulación con texto
                    superpuesto o tiene fechas EXIF incoherentes.
                poa_unsupported_language_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Qué hacer cuando el idioma del documento no está en
                    `poa_languages_allowed` (`UNSUPPORTED_DOCUMENT_LANGUAGE`).
                poa_address_mismatch_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Qué hacer cuando los datos extraídos no coinciden con los
                    campos `expected_*`: `ADDRESS_MISMATCH_WITH_PROVIDED`,
                    `NAME_MISMATCH_WITH_PROVIDED` y
                    `POA_COUNTRY_MISMATCH_WITH_PROVIDED` siguen todos esta
                    acción.
                poa_issuer_not_identified_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Qué hacer cuando no se puede identificar ninguna empresa u
                    organización emisora en el documento
                    (`ISSUER_NOT_IDENTIFIED`).
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    Cuando es `true` (valor predeterminado), guarda la llamada
                    como una sesión de tipo API: visible en la Business Console,
                    recuperable mediante `GET /v3/session/{sessionId}/decision/`
                    con el `request_id` devuelto, notificada mediante un webhook
                    `status.updated` y con el documento subido almacenado.
                    Cuando es `false`, no se almacena nada y `request_id` es un
                    UUID temporal que solo sirve para correlacionar la
                    respuesta.
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    Cadena opaca opcional (tu ID de usuario interno, correo
                    electrónico, UUID…) que se guarda en la sesión persistida y
                    se devuelve en la respuesta. Úsala para relacionar las
                    llamadas a la API con tus propios registros y para filtrar
                    sesiones más adelante.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Objeto JSON opcional que se almacena con la sesión (cuando
                    `save_api_request=true`) y se devuelve en la respuesta. En
                    solicitudes multipart, envíalo como un campo de cadena
                    codificado en JSON (p. ej.,
                    `metadata={"flow":"onboarding"}`): se convierte en un
                    objeto.
                  example:
                    flow: onboarding
            example:
              document: (binary JPEG/PNG/PDF of the utility bill or bank statement)
              expected_address: Av. Monseñor Tavella 1291, Salta, Argentina
              expected_country: ARG
              expected_first_name: Sophia
              expected_last_name: Martinez
              poa_languages_allowed: en,es
              save_api_request: true
              vendor_data: user-123
      responses:
        '200':
          description: >-
            Documento procesado. `poa.status` es `Approved` o `Declined`; cada
            problema detectado se detalla en `poa.warnings`. Un documento
            expirado, que no coincide o sospechoso también devuelve `200` con
            `status: "Declined"`: revisa el cuerpo, no solo el código HTTP.
            Cuando `save_api_request=true`, `request_id` es el ID de la sesión
            guardada.
          content:
            application/json:
              examples:
                Approved:
                  summary: >-
                    Factura de servicios leída correctamente, sin comprobaciones
                    de datos esperados
                  value:
                    request_id: 4b523a8d-ed32-45e4-8aa8-a89eda459d88
                    poa:
                      issuing_state: ARG
                      document_type: UTILITY_BILL
                      document_subtype: WATER_BILL
                      document_language: es
                      issuer: Aguas del Norte
                      issue_date: '2026-04-10'
                      expiration_date: null
                      poa_address: >-
                        AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP:
                        4400, CAPITAL - SALTA
                      poa_formatted_address: Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina
                      poa_parsed_address:
                        street_1: Avenida Monseñor Tavella 1291
                        street_2: b
                        city: Salta
                        region: Salta
                        country: AR
                        postal_code: A4400
                        document_location:
                          latitude: -24.8208682
                          longitude: -65.4130954
                      expected_details_address: null
                      expected_details_formatted_address: null
                      expected_details_parsed_address: null
                      name_on_document: OESTE EMBOTELLADORA S.A.
                      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:
                          - LA EMBOTELLADORA DEL NORTE SA
                      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: >-
                            aHR0cHM6Ly9hZ3Vhc2RlbG5vcnRlLmNvbS9mYWN0dXJhLzk5ODgxMQ==
                          parsed_payload: https://aguasdelnorte.com/factura/998811
                        - 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: MDA5OTg4MTEwMDA0Mg==
                          parsed_payload: '0099881100042'
                      status: Approved
                      warnings: []
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:29:02.439655+00:00'
                Declined - document too old:
                  summary: >-
                    Fecha de emisión anterior a lo permitido por
                    `poa_document_age_months`
                  value:
                    request_id: f61681b8-9422-4378-ac3e-04c6a247fb45
                    poa:
                      issuing_state: ARG
                      document_type: UTILITY_BILL
                      document_subtype: WATER_BILL
                      document_language: es
                      issuer: Aguas del Norte
                      issue_date: '2021-02-10'
                      expiration_date: null
                      poa_address: >-
                        AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP:
                        4400, CAPITAL - SALTA
                      poa_formatted_address: Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina
                      poa_parsed_address:
                        street_1: Avenida Monseñor Tavella 1291
                        street_2: b
                        city: Salta
                        region: Salta
                        country: AR
                        postal_code: A4400
                        document_location:
                          latitude: -24.8208682
                          longitude: -65.4130954
                      expected_details_address: null
                      expected_details_formatted_address: null
                      expected_details_parsed_address: null
                      name_on_document: OESTE EMBOTELLADORA S.A.
                      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:
                          - LA EMBOTELLADORA DEL NORTE SA
                      status: Declined
                      warnings:
                        - risk: POA_DOCUMENT_EXPIRED
                          feature: PROOF_OF_ADDRESS
                          additional_data:
                            expiration_reason: age_window
                            max_age_months: 3
                            document_subtype: WATER_BILL
                            document_type: UTILITY_BILL
                            issue_date: '2021-02-10'
                          log_type: error
                          short_description: Document expired
                          long_description: >-
                            The submitted document is older than the maximum
                            accepted age of 3 months from its issue date, which
                            exceeds the acceptable time period for validity.
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:23:02.165493+00:00'
                Declined - name mismatch:
                  summary: >-
                    `expected_first_name`/`expected_last_name` no coinciden con
                    `name_on_document`
                  value:
                    request_id: 0a7f2f9c-58f1-4b8e-b1e3-2f6f9d4f7a21
                    poa:
                      issuing_state: ARG
                      document_type: UTILITY_BILL
                      document_subtype: WATER_BILL
                      document_language: es
                      issuer: Aguas del Norte
                      issue_date: '2021-02-10'
                      expiration_date: null
                      poa_address: >-
                        AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP:
                        4400, CAPITAL - SALTA
                      poa_formatted_address: Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina
                      poa_parsed_address:
                        street_1: Avenida Monseñor Tavella 1291
                        street_2: b
                        city: Salta
                        region: Salta
                        country: AR
                        postal_code: A4400
                        document_location:
                          latitude: -24.8208682
                          longitude: -65.4130954
                      expected_details_address: null
                      expected_details_formatted_address: null
                      expected_details_parsed_address: null
                      name_on_document: OESTE EMBOTELLADORA S.A.
                      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:
                          - LA EMBOTELLADORA DEL NORTE SA
                      status: Declined
                      warnings:
                        - risk: NAME_MISMATCH_WITH_PROVIDED
                          feature: PROOF_OF_ADDRESS
                          additional_data: null
                          log_type: error
                          short_description: Name mismatch with provided information
                          long_description: >-
                            The full name on the document does not match the
                            name from the user's verified identity documents, or
                            the full name sent by API.
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:27:21.330172+00:00'
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: >-
                      ID de la sesión guardada cuando `save_api_request=true`
                      (se puede usar con `GET
                      /v3/session/{sessionId}/decision/`); en caso contrario, un
                      UUID de correlación temporal.
                  poa:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                        description: >-
                          `Approved` cuando ninguna advertencia se resuelve en
                          un rechazo; `Declined` en caso contrario: la lista
                          `warnings` explica el motivo.
                      issuing_state:
                        type: string
                        nullable: true
                        description: >-
                          País en el que se emitió el documento, tal como se
                          extrae del documento; normalmente ISO 3166-1 alfa-3
                          (p. ej., `ARG`).
                        example: ARG
                      document_type:
                        type: string
                        enum:
                          - UTILITY_BILL
                          - BANK_STATEMENT
                          - GOVERNMENT_ISSUED_DOCUMENT
                          - OTHER_POA_DOCUMENT
                          - UNKNOWN
                        description: >-
                          Categoría de documento detectada. `UNKNOWN` significa
                          que el documento no se pudo clasificar como una Prueba
                          de domicilio aceptable y se rechaza automáticamente
                          con `INVALID_DOCUMENT_TYPE`. Nunca es null: si la
                          clasificación falla, el valor es `UNKNOWN`.
                      document_subtype:
                        type: string
                        description: >-
                          Clasificación más detallada dentro de `document_type`,
                          por ejemplo `ELECTRICITY_BILL`, `WATER_BILL`,
                          `GAS_BILL`, `INTERNET_BILL`, `PHONE_BILL` (facturas de
                          servicios); `ACCOUNT_STATEMENT`,
                          `CREDIT_CARD_STATEMENT` (extractos bancarios);
                          `TAX_ASSESSMENT`, `RESIDENCY_CERTIFICATE` (documentos
                          gubernamentales). Es `UNKNOWN` cuando no se pudo
                          determinar ningún subtipo. Nunca es null: los fallos
                          de clasificación recurren a `UNKNOWN`.
                        example: WATER_BILL
                      document_language:
                        type: string
                        nullable: true
                        description: Idioma del documento detectado (ISO 639-1).
                        example: es
                      issuer:
                        type: string
                        nullable: true
                        description: >-
                          Empresa u organización que emitió el documento. `null`
                          añade `ISSUER_NOT_IDENTIFIED`.
                        example: Aguas del Norte
                      issue_date:
                        type: string
                        format: date
                        nullable: true
                        description: >-
                          Fecha de expedición del documento (`YYYY-MM-DD`).
                          `null` cuando no se pudo extraer; en este endpoint,
                          eso provoca un rechazo con
                          `UNABLE_TO_EXTRACT_ISSUE_DATE`.
                        example: '2021-02-10'
                      expiration_date:
                        type: string
                        format: date
                        nullable: true
                        description: >-
                          Fecha de caducidad o validez explícita impresa en el
                          documento, cuando existe. Es independiente de la
                          comprobación de antigüedad `poa_document_age_months`.
                      poa_address:
                        type: string
                        nullable: true
                        description: >-
                          Dirección tal como aparece impresa en el documento.
                          `null` rechaza automáticamente con
                          `MISSING_ADDRESS_INFORMATION`.
                      poa_formatted_address:
                        type: string
                        nullable: true
                        description: Versión geocodificada y normalizada de `poa_address`.
                        example: Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina
                      poa_parsed_address:
                        type: object
                        nullable: true
                        description: >-
                          Desglose estructurado y geocodificado de la dirección
                          del documento. `null` cuando no se pudo analizar la
                          dirección.
                        properties:
                          street_1:
                            type: string
                            nullable: true
                            example: Avenida Monseñor Tavella 1291
                          street_2:
                            type: string
                            nullable: true
                          city:
                            type: string
                            nullable: true
                            example: Salta
                          region:
                            type: string
                            nullable: true
                            example: Salta
                          country:
                            type: string
                            nullable: true
                            description: Código de país ISO 3166-1 alfa-2.
                            example: AR
                          postal_code:
                            type: string
                            nullable: true
                            example: A4400
                          document_location:
                            type: object
                            nullable: true
                            properties:
                              latitude:
                                type: number
                              longitude:
                                type: number
                            description: >-
                              Coordenadas geocodificadas de la dirección del
                              documento.
                      expected_details_address:
                        type: string
                        nullable: true
                        description: Devuelve el `expected_address` que enviaste, o `null`.
                      expected_details_formatted_address:
                        type: string
                        nullable: true
                        description: >-
                          Versión geocodificada y normalizada de
                          `expected_address`; `null` cuando no se proporciona o
                          no se puede geocodificar.
                      expected_details_parsed_address:
                        type: object
                        nullable: true
                        additionalProperties: true
                        description: >-
                          Resultado completo de geocodificación de
                          `expected_address` (calle, ciudad, región, país y
                          código postal, además de la salida sin procesar del
                          geocodificador y un indicador `is_verified`). `null`
                          cuando no se proporcionó `expected_address`.
                      name_on_document:
                        type: string
                        nullable: true
                        description: >-
                          Nombre del titular principal extraído del documento;
                          se compara con
                          `expected_first_name`/`expected_last_name` cuando se
                          proporcionan. Un valor `null` provoca el rechazo con
                          `POA_NAME_NOT_DETECTED` en este endpoint.
                        example: OESTE EMBOTELLADORA S.A.
                      extra_fields:
                        type: object
                        description: >-
                          Datos adicionales propios del documento. Los campos
                          bancarios se rellenan en los extractos bancarios
                          cuando aparecen impresos en el documento; en caso
                          contrario, `null`.
                        properties:
                          bank_account_number:
                            type: string
                            nullable: true
                          bank_iban:
                            type: string
                            nullable: true
                          bank_sort_code:
                            type: string
                            nullable: true
                          bank_routing_number:
                            type: string
                            nullable: true
                          bank_swift_bic:
                            type: string
                            nullable: true
                          bank_branch_name:
                            type: string
                            nullable: true
                          bank_branch_address:
                            type: string
                            nullable: true
                          document_phone_number:
                            type: string
                            nullable: true
                            description: >-
                              Número de teléfono de contacto impreso en el
                              documento.
                          additional_names:
                            type: array
                            items:
                              type: string
                            description: >-
                              Otros nombres de titulares que aparecen en el
                              documento (p. ej., cotitulares de la cuenta,
                              nombres anteriores de la cuenta).
                      warnings:
                        type: array
                        description: >-
                          Vacío en una aprobación sin incidencias. Cada entrada
                          explica un riesgo detectado; las entradas con
                          `log_type: "error"` establecen `status` en `Declined`.
                        items:
                          type: object
                          properties:
                            risk:
                              type: string
                              description: >-
                                Código de riesgo legible por máquina. Siempre
                                rechazan: `MISSING_ADDRESS_INFORMATION`,
                                `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`,
                                `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, además de
                                `UNABLE_TO_EXTRACT_ISSUE_DATE` y
                                `POA_NAME_NOT_DETECTED` (fijados en rechazo en
                                este endpoint). Controlados por opciones de la
                                solicitud: `NAME_MISMATCH_WITH_PROVIDED` /
                                `ADDRESS_MISMATCH_WITH_PROVIDED` /
                                `POA_COUNTRY_MISMATCH_WITH_PROVIDED`
                                (`poa_address_mismatch_action`),
                                `POOR_DOCUMENT_QUALITY` (este endpoint nunca lo
                                genera) / `DOCUMENT_METADATA_MISMATCH`
                                (`poa_document_issues_action`),
                                `SUSPECTED_DOCUMENT_MANIPULATION`
                                (`poa_document_authenticity_action`),
                                `UNSUPPORTED_DOCUMENT_LANGUAGE`
                                (`poa_unsupported_language_action`),
                                `ISSUER_NOT_IDENTIFIED`
                                (`poa_issuer_not_identified_action`).
                                Informativos en este endpoint:
                                `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION`,
                                `UNPARSABLE_OR_INVALID_ADDRESS`.
                              example: POA_DOCUMENT_EXPIRED
                            feature:
                              type: string
                              enum:
                                - PROOF_OF_ADDRESS
                              description: >-
                                Función que emitió la advertencia. En este
                                endpoint siempre es `PROOF_OF_ADDRESS`.
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                Contexto adicional para algunos riesgos: p. ej.,
                                `POA_DOCUMENT_EXPIRED` incluye
                                `expiration_reason` (`printed_expiration` o
                                `age_window`), `document_type`,
                                `document_subtype` e `issue_date`, además de
                                `expiration_date` en la ruta
                                `printed_expiration` o `max_age_months` en la
                                ruta `age_window`;
                                `SUSPECTED_DOCUMENT_MANIPULATION` incluye
                                `reason` y `detection_method`. `null` para la
                                mayoría de los riesgos.
                            log_type:
                              type: string
                              enum:
                                - error
                                - information
                              description: >-
                                Gravedad. Las advertencias `error` llevan
                                `status` a `Declined`; las entradas
                                `information` son orientativas y nunca rechazan
                                por sí solas. (Este endpoint no produce
                                `warning`: sus opciones solo aceptan `DECLINE` o
                                `NO_ACTION`.)
                            short_description:
                              type: string
                              description: Resumen legible del riesgo en una línea.
                            long_description:
                              type: string
                              description: Explicación legible del riesgo.
                      detected_codes:
                        type: array
                        description: >-
                          Códigos QR y códigos de barras detectados en todas las
                          páginas procesadas del documento. Vacío cuando no se
                          encuentra ninguno. Un código QR localizado pero que no
                          se puede decodificar tiene `parsed_payload: null`.
                        items:
                          $ref: '#/components/schemas/DocumentAIDetectedCode'
                  vendor_data:
                    type: string
                    nullable: true
                    description: Devuelve el `vendor_data` que enviaste, o `null`.
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: Devuelve el objeto `metadata` que enviaste, o `null`.
                  created_at:
                    type: string
                    format: date-time
                    description: >-
                      Marca de tiempo ISO 8601 (UTC) del momento en que se
                      generó la respuesta.
        '400':
          description: >-
            Error de validación o de procesamiento. Los problemas a nivel de
            campo devuelven el formato estándar de DRF (un array de mensajes por
            cada campo afectado). Los problemas con PDF cifrados devuelven
            `{"detail": ...}`. Un documento que el proceso de extracción no
            puede procesar devuelve `{"error": ["Error extracting POA
            information"]}`.
          content:
            application/json:
              examples:
                Missing document:
                  summary: '`document` no se incluyó en los datos del formulario'
                  value:
                    document:
                      - No file was submitted.
                Unsupported file extension:
                  summary: Extensión de archivo distinta de tiff/jpg/jpeg/png/pdf/webp
                  value:
                    document:
                      - >-
                        File extension “txt” is not allowed. Allowed extensions
                        are: tiff, jpg, jpeg, png, pdf, webp.
                File too large:
                  summary: El archivo supera el límite de 15 MB
                  value:
                    document:
                      - File size should not exceed 15 MB
                Encrypted PDF:
                  summary: PDF subido sin la contraseña requerida
                  value:
                    detail: >-
                      The PDF is encrypted. Please upload a decrypted PDF or a
                      photo instead.
                Wrong PDF password:
                  summary: '`document_password` no descifra el PDF'
                  value:
                    detail: >-
                      The PDF password is incorrect. Please provide the correct
                      password.
                Invalid language code:
                  summary: '`poa_languages_allowed` contiene un código no admitido'
                  value:
                    poa_languages_allowed:
                      - >-
                        Invalid language code: 'xx'. Must be one of the
                        supported languages: ['ar', 'bn', 'hy', 'bg', 'bs',
                        'ca', 'cnr', 'sq', 'zh', 'hr', 'cs', 'da', 'nl', 'en',
                        'et', 'fi', 'fr', 'ka', 'kk', 'de', 'el', 'he', 'hi',
                        'hu', 'id', 'it', 'ja', 'ko', 'ky', 'lv', 'lt', 'mk',
                        'mn', 'ms', 'no', 'fa', 'pl', 'pt', 'ro', 'ru', 'sr',
                        'sk', 'sl', 'so', 'es', 'sv', 'th', 'tr', 'uk', 'uz',
                        'vi'].
                Invalid document age value:
                  summary: >-
                    Valor de `poa_document_age_months` fuera del rango 1–120 /
                    -1
                  value:
                    poa_document_age_months:
                      - >-
                        Invalid integer value for 'utility_bill': '999'. Must be
                        -1 (unlimited) or a positive integer between 1 and 120.
                Extraction failure:
                  summary: El pipeline de extracción no pudo procesar el documento
                  value:
                    error:
                      - Error extracting POA information
        '403':
          description: >-
            Permiso denegado. Se devuelve cuando falta el encabezado `x-api-key`
            y también cuando el saldo de la organización que realiza la llamada
            no la cubre; una clave incorrecta, revocada o expirada devuelve
            `401`. Si falta la clave, se devuelve `403` con `{"detail": ...}`;
            una clave incorrecta, revocada o expirada devuelve `401`. La falta
            de créditos devuelve `403` con `{"error": ...}` antes de que se
            procese ningún documento.
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: >-
                    Falta el encabezado `x-api-key`, o la clave no es válida o
                    está revocada
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: El saldo de la organización no cubre la llamada
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '429':
          description: >-
            Límite de solicitudes superado. Todos los endpoints
            POST/PATCH/DELETE comparten un presupuesto de 300 solicitudes de
            escritura por minuto por clave de API. La respuesta incluye los
            encabezados `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
            `X-RateLimit-Reset` y `Retry-After`.
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: Más de 300 solicitudes de escritura en el minuto actual
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST 'https://verification.didit.me/v3/poa/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -F 'document=@./utility-bill.pdf' \
              -F 'expected_address=Av. Monseñor Tavella 1291, Salta, Argentina' \
              -F 'expected_country=ARG' \
              -F 'expected_first_name=Sophia' \
              -F 'expected_last_name=Martinez' \
              -F 'poa_languages_allowed=en,es' \
              -F 'vendor_data=user-123' \
              --max-time 45
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.proof_of_address.verify(
                document=open("document.pdf", "rb"),
                expected_address="Av. Monseñor Tavella 1291, Salta, Argentina",
                expected_country="ARG",
                expected_first_name="Sophia",
                expected_last_name="Martinez",
                poa_languages_allowed="en,es",
                save_api_request=True,
                vendor_data="user-123",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit, { fileFromPath } from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.proofOfAddress.verify({
              document: await fileFromPath("document.pdf"),
              expected_address: "Av. Monseñor Tavella 1291, Salta, Argentina",
              expected_country: "ARG",
              expected_first_name: "Sophia",
              expected_last_name: "Martinez",
              poa_languages_allowed: "en,es",
              save_api_request: true,
              vendor_data: "user-123",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.ProofOfAddress.Verify(ctx, didit.ProofOfAddressVerifyParams{\n\tDocument:            didit.FileFromPath(\"document.pdf\"),\n\tExpectedAddress:     didit.String(\"Av. Monseñor Tavella 1291, Salta, Argentina\"),\n\tExpectedCountry:     didit.String(\"ARG\"),\n\tExpectedFirstName:   didit.String(\"Sophia\"),\n\tExpectedLastName:    didit.String(\"Martinez\"),\n\tPOALanguagesAllowed: didit.String(\"en,es\"),\n\tSaveAPIRequest:      didit.Bool(true),\n\tVendorData:          didit.String(\"user-123\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.nio.file.Path;

            import me.didit.Didit;

            import me.didit.types.ProofOfAddressVerifyParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.proofOfAddress().verify(ProofOfAddressVerifyParams.builder()
                    .document(Path.of("document.pdf"))
                    .expectedAddress("Av. Monseñor Tavella 1291, Salta, Argentina")
                    .expectedCountry("ARG")
                    .expectedFirstName("Sophia")
                    .expectedLastName("Martinez")
                    .poaLanguagesAllowed("en,es")
                    .saveApiRequest(true)
                    .vendorData("user-123")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;
            use Didit\File;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->proofOfAddress->verify([
                'document' => File::fromPath('document.pdf'),
                'expected_address' => 'Av. Monseñor Tavella 1291, Salta, Argentina',
                'expected_country' => 'ARG',
                'expected_first_name' => 'Sophia',
                'expected_last_name' => 'Martinez',
                'poa_languages_allowed' => 'en,es',
                'save_api_request' => true,
                'vendor_data' => 'user-123',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.proof_of_address.verify(
              document: Pathname("document.pdf"),
              expected_address: "Av. Monseñor Tavella 1291, Salta, Argentina",
              expected_country: "ARG",
              expected_first_name: "Sophia",
              expected_last_name: "Martinez",
              poa_languages_allowed: "en,es",
              save_api_request: true,
              vendor_data: "user-123"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.ProofOfAddress.VerifyAsync(new
            ProofOfAddressVerifyParams

            {
                Document = FileUpload.FromPath("document.pdf"),
                ExpectedAddress = "Av. Monseñor Tavella 1291, Salta, Argentina",
                ExpectedCountry = "ARG",
                ExpectedFirstName = "Sophia",
                ExpectedLastName = "Martinez",
                PoaLanguagesAllowed = "en,es",
                SaveApiRequest = true,
                VendorData = "user-123",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    DocumentAIDetectedCode:
      type: object
      required:
        - type
        - page_number
        - position
        - x
        - 'y'
        - width
        - height
        - page_width
        - page_height
        - raw_payload
        - parsed_payload
      properties:
        type:
          type: string
          description: >-
            Simbología detectada, por ejemplo `QR_CODE`, `CODE_128`, `EAN_13`,
            `DATA_MATRIX` o `PDF_417`.
        page_number:
          type: integer
          minimum: 1
          description: Número de página, empezando en 1.
        position:
          type: array
          nullable: true
          description: >-
            Polígono detectado en coordenadas de píxeles de la página
            renderizada. Es `null` cuando no hay una ubicación fiable
            disponible.
          items:
            type: array
            minItems: 2
            maxItems: 2
            items:
              type: integer
        x:
          type: integer
          nullable: true
          description: >-
            Borde izquierdo del cuadro delimitador, en píxeles de la página
            renderizada.
        'y':
          type: integer
          nullable: true
          description: >-
            Borde superior del cuadro delimitador, en píxeles de la página
            renderizada.
        width:
          type: integer
          nullable: true
          description: Ancho del cuadro delimitador en píxeles de la página renderizada.
        height:
          type: integer
          nullable: true
          description: Altura del cuadro delimitador en píxeles de la página renderizada.
        page_width:
          type: integer
          description: Ancho de la página renderizada en píxeles.
        page_height:
          type: integer
          description: Altura de la página renderizada en píxeles.
        raw_payload:
          type: string
          description: >-
            Payload del decodificador sin procesar como cadena base64 cuando
            está disponible; en caso contrario, una cadena vacía.
        parsed_payload:
          nullable: true
          description: >-
            Cadena decodificada o valor estructurado. `null` cuando el código se
            localizó pero no se pudo decodificar.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clave de API de tu aplicación, que encontrarás en Developers -> API
        keys en la Business Console. La clave principal tiene acceso completo.
        Una clave con nombre puede tener un alcance limitado: ninguno, lectura o
        escritura por recurso, limitada a algunos flujos o a sesiones aprobadas,
        a una lista de direcciones IP y a una fecha de caducidad. 401 significa
        que la clave es incorrecta, se revocó o expiró; 403 significa que no se
        envió ninguna clave, que la clave no tiene acceso a este recurso o
        acción, o que la solicitud provino de una dirección fuera de su lista de
        IP; 404 en una ruta de sesión significa que la sesión está fuera de los
        flujos o estados de la clave. Una clave sin acceso a contenido
        multimedia recibe las URL de imágenes, videos y PDF como null, y una
        clave sin permiso de escritura en sesiones recibe los enlaces y tokens
        de sesión como null. Consulta https://docs.didit.me/console/api-keys.

````

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