> ## 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 Bukti Alamat: Verifikasi POA & OCR

> Verifikasi bukti alamat Didit via POST /v3/poa/ untuk tagihan utilitas dan rekening bank. OCR alamat, cek keaslian, harga per pakai, tanpa kontrak.



## OpenAPI

````yaml id/openapi-25.json POST /v3/poa/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API Verifikasi Identitas. Lakukan autentikasi dengan header x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/poa/:
    post:
      tags:
        - Standalone APIs
      summary: Bukti Alamat (OCR dokumen + pemeriksaan alamat)
      description: >-
        Ekstrak dan validasi dokumen Bukti Alamat — tagihan utilitas, rekening
        koran, dan dokumen yang diterbitkan pemerintah — dalam satu panggilan.
        Mengembalikan penerbit, tanggal penerbitan/kedaluwarsa, nama pemegang,
        alamat mentah dan yang telah diurai/digeocoding, `status`
        `Approved`/`Declined`, serta daftar `warnings` yang menjelaskan setiap
        masalah yang ditemukan.


        **Latensi.** Ekstraksi berbasis LLM: panggilan umum memerlukan waktu
        **5–15 detik**, PDF multi-halaman hingga **~30 detik**. Konfigurasikan
        batas waktu klien **setidaknya 45 detik** dan jangan coba lagi sebelum
        panggilan selesai.


        **Cara kerjanya.** Dokumen (gambar atau PDF, hingga 15 MB; PDF
        terenkripsi memerlukan `document_password`) diklasifikasikan ke dalam
        tipe dan subtipe dokumen (misalnya `UTILITY_BILL` / `WATER_BILL`), dan
        penerbit, tanggal, nama pemegang, serta alamat diekstrak menggunakan
        ekstraksi berbasis LLM. Alamat diurai dan digeocoding ke dalam
        `poa_parsed_address`. Forensik PDF/EXIF memindai adanya manipulasi —
        modifikasi setelah penandatanganan digital, editor PDF yang dikenal,
        manipulasi teks overlay, ekspor ulang yang mencurigakan — yang
        memunculkan `SUSPECTED_DOCUMENT_MANIPULATION` atau
        `DOCUMENT_METADATA_MISMATCH`. Kolom teks yang dikosongkan dan diketik
        ulang dengan font lain, saat file itu sendiri tidak memuat bukti apakah
        isinya berubah, akan memunculkan
        `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`. Usia dokumen divalidasi
        terhadap `poa_document_age_months`, dan bahasa terhadap
        `poa_languages_allowed`. Jika Anda meneruskan `expected_address`,
        `expected_country`, atau `expected_first_name`/`expected_last_name`,
        nilai yang diekstrak akan diperiksa silang dan ketidakcocokan akan
        ditandai.


        **Logika keputusan.** `status` adalah `Approved` kecuali jika setidaknya
        satu peringatan berujung pada penolakan. Kegagalan mutlak selalu
        menghasilkan penolakan: `MISSING_ADDRESS_INFORMATION`,
        `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`,
        `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, ditambah
        `UNABLE_TO_EXTRACT_ISSUE_DATE` dan `POA_NAME_NOT_DETECTED` (tidak dapat
        dikonfigurasi pada endpoint ini). Lima grup risiko dapat dikonfigurasi
        per permintaan melalui opsi `poa_*_action` (`DECLINE` atau `NO_ACTION`,
        semuanya secara default bernilai `DECLINE`).
        `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` dan
        `UNPARSABLE_OR_INVALID_ADDRESS` bersifat informasional pada endpoint ini
        dan tidak pernah menghasilkan penolakan. Dokumen yang tidak dapat
        diproses sama sekali akan mengembalikan `400`; dokumen yang dapat dibaca
        tetapi bermasalah akan mengembalikan `200` dengan `status: "Declined"` —
        selalu periksa `poa.status` dan `poa.warnings`, bukan hanya kode HTTP.


        **Penagihan.** Setiap respons `200` menggunakan satu kredit API Bukti
        Alamat (dibayar dari kredit paket atau saldo isi saldo Anda). Jika saldo
        organisasi tidak dapat mencukupi panggilan, endpoint akan mengembalikan
        `403` dengan kesalahan kredit tidak mencukupi sebelum pemrosesan dokumen
        apa pun dilakukan.


        **Persistensi sesi (`save_api_request`, default `true`).** Jika `true`,
        panggilan akan disimpan sebagai sesi bertipe API: sesi ini muncul di
        Business Console, dokumen yang diunggah akan disimpan, `request_id` yang
        dikembalikan adalah id sesi nyata yang dapat Anda teruskan ke `GET
        /v3/session/{sessionId}/decision/` (keputusan tersebut juga menampilkan
        `document_file` dan forensik `document_metadata`, yang ditiadakan dalam
        respons ini), dan webhook `status.updated` akan dikirimkan. Jika
        `false`, tidak ada yang disimpan dan `request_id` adalah UUID korelasi
        sekali pakai yang tidak dapat dicari nantinya.


        **Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan:
        setelah validasi permintaan (input yang salah format tetap mengembalikan
        `400`), endpoint akan mengembalikan payload tiruan `Approved` statis
        (tagihan listrik fiktif "Sandbox Power Co."), tidak ada sesi yang
        disimpan, dan tidak ada kredit yang digunakan.


        **Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`.
        Kredensial yang hilang atau tidak valid akan mengembalikan `403`
        (`{"detail": "You do not have permission to perform this action."}`) —
        API ini tidak pernah mengembalikan `401`.


        **Batas laju.** Kuota penulisan bersama sebesar 300 permintaan/menit per
        kunci API di seluruh endpoint POST/PATCH/DELETE; melebihi batas ini akan
        mengembalikan `429`.


        Catatan: `FUTURE_ISSUE_DATE` dan `POOR_DOCUMENT_QUALITY` ada dalam sesi
        alur kerja tetapi tidak pernah dihasilkan oleh endpoint mandiri ini —
        dokumen bertanggal masa depan tidak ditolak secara otomatis di sini.
      operationId: post_v3poa
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - document
              properties:
                document:
                  type: string
                  format: binary
                  description: >-
                    Dokumen Bukti Alamat. Ekstensi yang diizinkan: `tiff`,
                    `jpg`, `jpeg`, `png`, `pdf`, `webp`. Ukuran unggahan
                    maksimum: **15 MB** (file yang lebih besar akan ditolak
                    dengan `400`). PDF multi-halaman didukung (perkirakan
                    latensi lebih tinggi); PDF terenkripsi memerlukan
                    `document_password`. Gambar dikompresi secara otomatis
                    sebelum diproses.
                document_password:
                  type: string
                  description: >-
                    Kata sandi untuk mendekripsi `document` jika berupa PDF
                    terenkripsi. Mengirimkan PDF terenkripsi tanpa kata sandi
                    (atau dengan kata sandi yang salah) mengembalikan `400`.
                  writeOnly: true
                expected_address:
                  type: string
                  description: >-
                    Alamat yang akan diverifikasi terhadap dokumen. Alamat ini
                    di-geocode dan dibandingkan dengan alamat yang diekstrak;
                    ketidakcocokan (atau alamat yang diharapkan tidak dapat
                    di-geocode/diverifikasi) menambahkan
                    `ADDRESS_MISMATCH_WITH_PROVIDED`, yang diatur oleh
                    `poa_address_mismatch_action`. Bentuk yang di-geocode
                    ditampilkan kembali di `expected_details_formatted_address`
                    / `expected_details_parsed_address`.
                  example: Av. Monseñor Tavella 1291, Salta, Argentina
                expected_country:
                  type: string
                  description: >-
                    Negara yang akan diverifikasi terhadap dokumen (kode ISO
                    3166-1, misalnya `ARG` atau `AR`). Ketidakcocokan dengan
                    negara dokumen menambahkan
                    `POA_COUNTRY_MISMATCH_WITH_PROVIDED`, yang diatur oleh
                    `poa_address_mismatch_action`.
                  example: ARG
                expected_first_name:
                  type: string
                  description: >-
                    Nama depan untuk diverifikasi terhadap `name_on_document`
                    (pencocokan samar, mendukung transliterasi). Skor di bawah
                    ambang batas kecocokan menambahkan
                    `NAME_MISMATCH_WITH_PROVIDED`, yang diatur oleh
                    `poa_address_mismatch_action`.
                  example: Sophia
                expected_last_name:
                  type: string
                  description: >-
                    Nama belakang untuk diverifikasi terhadap
                    `name_on_document`, digabungkan dengan `expected_first_name`
                    untuk skor kecocokan.
                  example: Martinez
                poa_languages_allowed:
                  type: string
                  description: >-
                    Daftar bahasa dokumen yang diterima yang dipisahkan koma
                    sebagai kode ISO 639-1 (misalnya `en,es,fr`). Jika
                    dihilangkan atau kosong, **seluruh 51 bahasa yang didukung**
                    akan diterima. Dokumen dalam bahasa di luar daftar akan
                    menambahkan `UNSUPPORTED_DOCUMENT_LANGUAGE` (diatur oleh
                    `poa_unsupported_language_action`); kode yang tidak dikenal
                    dalam daftar akan mengembalikan `400` beserta seluruh kode
                    yang didukung.
                  example: en,es
                poa_document_age_months:
                  type: string
                  description: >-
                    Pasangan `key:value` yang dipisahkan koma yang menetapkan
                    usia dokumen maksimum dalam hitungan bulan per jenis dokumen
                    — kunci: `utility_bill`, `bank_statement`,
                    `government_issued_document`, `other_poa_document`; nilai:
                    `1`–`120`, atau `-1` untuk tanpa batas (tanpa pemeriksaan
                    usia). Nilai default jika dihilangkan:
                    `utility_bill:3,bank_statement:3,government_issued_document:12,other_poa_document:12`.
                    Dokumen yang lebih lama dari batasnya akan ditolak dengan
                    `POA_DOCUMENT_EXPIRED`. **Perhatian:** saat Anda memberikan
                    kolom ini, cantumkan *setiap* jenis yang Anda terima — jenis
                    yang dihilangkan akan dianggap tidak diterima
                    (`POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` bersifat
                    informasi) dan pemeriksaan usianya dilewati.
                  example: utility_bill:3,bank_statement:6
                poa_name_mismatch_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Diterima tetapi **saat ini tidak diterapkan** — peringatan
                    ketidakcocokan nama (`NAME_MISMATCH_WITH_PROVIDED`)
                    mengikuti `poa_address_mismatch_action`. Atur
                    `poa_address_mismatch_action` untuk mengontrol perilaku
                    ketidakcocokan nama maupun alamat.
                poa_document_issues_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Tindakan yang diambil saat terjadi masalah integritas file —
                    dalam praktiknya hanya `DOCUMENT_METADATA_MISMATCH` yang
                    dihasilkan oleh endpoint ini.
                poa_document_authenticity_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Tindakan yang diambil saat manipulasi dokumen dicurigai
                    (`SUSPECTED_DOCUMENT_MANIPULATION`) — misalnya PDF
                    dimodifikasi setelah penandatanganan digital, diproses oleh
                    editor PDF yang dikenal, menunjukkan manipulasi overlay
                    teks, atau memiliki tanggal EXIF yang tidak konsisten. Opsi
                    ini juga mengatur `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`
                    (kolom teks yang diketik ulang yang tidak dapat dibuktikan
                    oleh file apakah telah diubah atau tidak): `DECLINE` juga
                    akan menolaknya, `NO_ACTION` menyimpannya sebagai
                    peringatan.
                poa_unsupported_language_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Tindakan yang harus diambil ketika bahasa dokumen berada di
                    luar `poa_languages_allowed`
                    (`UNSUPPORTED_DOCUMENT_LANGUAGE`).
                poa_address_mismatch_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Tindakan yang harus diambil ketika detail yang diekstrak
                    tidak cocok dengan kolom `expected_*`:
                    `ADDRESS_MISMATCH_WITH_PROVIDED`,
                    `NAME_MISMATCH_WITH_PROVIDED`, dan
                    `POA_COUNTRY_MISMATCH_WITH_PROVIDED` semuanya mengikuti
                    tindakan ini.
                poa_issuer_not_identified_action:
                  type: string
                  enum:
                    - DECLINE
                    - NO_ACTION
                  default: DECLINE
                  description: >-
                    Tindakan yang diambil saat tidak ada perusahaan/organisasi
                    penerbit yang dapat diidentifikasi pada dokumen
                    (`ISSUER_NOT_IDENTIFIED`).
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    Jika `true` (default), menyimpan panggilan sebagai sesi tipe
                    API — terlihat di Business Console, dapat diambil melalui
                    `GET /v3/session/{sessionId}/decision/` menggunakan
                    `request_id` yang dikembalikan, diumumkan melalui webhook
                    `status.updated`, dan dengan dokumen yang diunggah disimpan.
                    Jika `false`, tidak ada yang disimpan dan `request_id`
                    adalah UUID sementara hanya untuk korelasi respons.
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    String buram opsional (ID pengguna internal, email, UUID
                    Anda…) yang disimpan pada sesi yang dipertahankan dan
                    dikembalikan dalam respons. Gunakan untuk mengorelasikan
                    panggilan API dengan catatan Anda sendiri dan memfilter sesi
                    nantinya.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Objek JSON opsional yang disimpan bersama sesi (saat
                    `save_api_request=true`) dan dikembalikan dalam respons.
                    Dalam permintaan multipart, kirimkan sebagai kolom string
                    yang dikodekan dalam JSON (misalnya
                    `metadata={"flow":"onboarding"}`) — kolom ini akan diuraikan
                    menjadi sebuah objek.
                  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: >-
            Dokumen diproses. `poa.status` bernilai `Approved` atau `Declined`;
            setiap masalah yang terdeteksi dirinci dalam `poa.warnings`. Dokumen
            yang kedaluwarsa, tidak cocok, atau mencurigakan tetap menghasilkan
            `200` dengan `status: "Declined"` — periksa isi respons, bukan hanya
            kode HTTP. Ketika `save_api_request=true`, `request_id` adalah id
            sesi yang disimpan.
          content:
            application/json:
              examples:
                Approved:
                  summary: >-
                    Tagihan utilitas dibaca dengan jelas, tanpa pemeriksaan
                    detail yang diharapkan
                  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: >-
                    Tanggal penerbitan lebih lama dari `poa_document_age_months`
                    yang diizinkan
                  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` tidak cocok
                    dengan `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 sesi yang disimpan saat `save_api_request=true` (dapat
                      digunakan dengan `GET /v3/session/{sessionId}/decision/`);
                      jika tidak, berupa UUID korelasi sementara.
                  poa:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                        description: >-
                          `Approved` saat tidak ada peringatan yang menghasilkan
                          penolakan; jika tidak `Declined` — daftar `warnings`
                          menjelaskan alasannya.
                      issuing_state:
                        type: string
                        nullable: true
                        description: >-
                          Negara tempat dokumen diterbitkan, sebagaimana
                          diekstrak dari dokumen — biasanya ISO 3166-1 alpha-3
                          (misalnya `ARG`).
                        example: ARG
                      document_type:
                        type: string
                        enum:
                          - UTILITY_BILL
                          - BANK_STATEMENT
                          - GOVERNMENT_ISSUED_DOCUMENT
                          - OTHER_POA_DOCUMENT
                          - UNKNOWN
                        description: >-
                          Kategori dokumen yang terdeteksi. `UNKNOWN` berarti
                          dokumen tidak dapat diklasifikasikan sebagai Bukti
                          Alamat yang dapat diterima dan otomatis ditolak dengan
                          `INVALID_DOCUMENT_TYPE`. Tidak pernah null — kegagalan
                          klasifikasi beralih ke `UNKNOWN`.
                      document_subtype:
                        type: string
                        description: >-
                          Klasifikasi yang lebih terperinci dalam
                          `document_type` — mis. `ELECTRICITY_BILL`,
                          `WATER_BILL`, `GAS_BILL`, `INTERNET_BILL`,
                          `PHONE_BILL` (tagihan utilitas); `ACCOUNT_STATEMENT`,
                          `CREDIT_CARD_STATEMENT` (rekening koran bank);
                          `TAX_ASSESSMENT`, `RESIDENCY_CERTIFICATE` (dokumen
                          pemerintah). `UNKNOWN` jika tidak ada subtipe yang
                          dapat ditentukan. Tidak pernah null — jika klasifikasi
                          gagal, digunakan `UNKNOWN` sebagai fallback.
                        example: WATER_BILL
                      document_language:
                        type: string
                        nullable: true
                        description: Bahasa dokumen yang terdeteksi (ISO 639-1).
                        example: es
                      issuer:
                        type: string
                        nullable: true
                        description: >-
                          Perusahaan atau organisasi yang menerbitkan dokumen.
                          `null` menambahkan `ISSUER_NOT_IDENTIFIED`.
                        example: Aguas del Norte
                      issue_date:
                        type: string
                        format: date
                        nullable: true
                        description: >-
                          Tanggal penerbitan dokumen (`YYYY-MM-DD`). `null` jika
                          tidak dapat diekstraksi — kondisi ini menyebabkan
                          permintaan ditolak dengan
                          `UNABLE_TO_EXTRACT_ISSUE_DATE` pada endpoint ini.
                        example: '2021-02-10'
                      expiration_date:
                        type: string
                        format: date
                        nullable: true
                        description: >-
                          Tanggal kedaluwarsa/masa berlaku eksplisit yang
                          tertera pada dokumen, jika ada. Tidak bergantung pada
                          pemeriksaan usia dokumen `poa_document_age_months`.
                      poa_address:
                        type: string
                        nullable: true
                        description: >-
                          Alamat persis seperti yang tertera pada dokumen.
                          `null` otomatis ditolak dengan
                          `MISSING_ADDRESS_INFORMATION`.
                      poa_formatted_address:
                        type: string
                        nullable: true
                        description: >-
                          Versi yang telah dinormalisasi dan di-geocode dari
                          `poa_address`.
                        example: Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina
                      poa_parsed_address:
                        type: object
                        nullable: true
                        description: >-
                          Rincian terstruktur dan telah diberi geocode dari
                          alamat dokumen. `null` jika alamat tidak dapat diurai.
                        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: Kode negara ISO 3166-1 alpha-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: Koordinat hasil geocoding dari alamat dokumen.
                      expected_details_address:
                        type: string
                        nullable: true
                        description: >-
                          Salinan `expected_address` yang Anda kirimkan, atau
                          `null`.
                      expected_details_formatted_address:
                        type: string
                        nullable: true
                        description: >-
                          Versi `expected_address` yang dinormalisasi dan
                          di-geocode; bernilai `null` jika tidak disediakan atau
                          tidak dapat di-geocode.
                      expected_details_parsed_address:
                        type: object
                        nullable: true
                        additionalProperties: true
                        description: >-
                          Hasil geocoding lengkap untuk `expected_address`
                          (jalan/kota/wilayah/negara/kode pos ditambah output
                          geocoder mentah dan tanda `is_verified`). Bernilai
                          `null` jika `expected_address` tidak diberikan.
                      name_on_document:
                        type: string
                        nullable: true
                        description: >-
                          Nama pemegang utama yang diekstrak dari dokumen;
                          dibandingkan dengan
                          `expected_first_name`/`expected_last_name` jika
                          diberikan. `null` akan ditolak dengan
                          `POA_NAME_NOT_DETECTED` pada endpoint ini.
                        example: OESTE EMBOTELLADORA S.A.
                      extra_fields:
                        type: object
                        description: >-
                          Tambahan khusus dokumen. Kolom bank diisi untuk
                          rekening koran jika tercetak pada dokumen; `null` jika
                          tidak.
                        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: Nomor telepon kontak yang tercetak pada dokumen.
                          additional_names:
                            type: array
                            items:
                              type: string
                            description: >-
                              Nama pemegang lain yang ditemukan pada dokumen
                              (misalnya, pemegang rekening bersama, nama
                              rekening sebelumnya).
                      warnings:
                        type: array
                        description: >-
                          Kosong jika persetujuan bersih. Setiap entri
                          menjelaskan satu risiko yang terdeteksi; entri dengan
                          `log_type: "error"` menetapkan `status` ke `Declined`.
                        items:
                          type: object
                          properties:
                            risk:
                              type: string
                              description: >-
                                Kode risiko yang dapat dibaca mesin. Selalu
                                ditolak: `MISSING_ADDRESS_INFORMATION`,
                                `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`,
                                `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, ditambah
                                `UNABLE_TO_EXTRACT_ISSUE_DATE` dan
                                `POA_NAME_NOT_DETECTED` (ditetapkan untuk
                                ditolak pada endpoint ini). Diatur oleh opsi
                                permintaan: `NAME_MISMATCH_WITH_PROVIDED` /
                                `ADDRESS_MISMATCH_WITH_PROVIDED` /
                                `POA_COUNTRY_MISMATCH_WITH_PROVIDED`
                                (`poa_address_mismatch_action`),
                                `POOR_DOCUMENT_QUALITY` (tidak pernah dihasilkan
                                oleh endpoint ini) /
                                `DOCUMENT_METADATA_MISMATCH`
                                (`poa_document_issues_action`),
                                `SUSPECTED_DOCUMENT_MANIPULATION` dan
                                `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`
                                (`poa_document_authenticity_action`),
                                `UNSUPPORTED_DOCUMENT_LANGUAGE`
                                (`poa_unsupported_language_action`),
                                `ISSUER_NOT_IDENTIFIED`
                                (`poa_issuer_not_identified_action`). Bersifat
                                informasional pada endpoint ini:
                                `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION`,
                                `UNPARSABLE_OR_INVALID_ADDRESS`.
                              example: POA_DOCUMENT_EXPIRED
                            feature:
                              type: string
                              enum:
                                - PROOF_OF_ADDRESS
                              description: >-
                                Fitur yang memunculkan peringatan. Selalu
                                `PROOF_OF_ADDRESS` pada endpoint ini.
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                Konteks tambahan untuk beberapa risiko —
                                misalnya `POA_DOCUMENT_EXPIRED` menyertakan
                                `expiration_reason` (`printed_expiration` atau
                                `age_window`), `document_type`,
                                `document_subtype`, dan `issue_date`, ditambah
                                `expiration_date` pada jalur
                                `printed_expiration` atau `max_age_months` pada
                                jalur `age_window`;
                                `SUSPECTED_DOCUMENT_MANIPULATION` menyertakan
                                `reason` dan `detection_method`;
                                `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`
                                menyertakan `reason`, `detection_method`
                                (`unproven_text_replacement`), `replaced_text`,
                                `manipulated_regions`, dan `manipulated_blocks`.
                                `null` untuk sebagian besar risiko.
                            log_type:
                              type: string
                              enum:
                                - error
                                - information
                              description: >-
                                Tingkat keparahan. Peringatan `error` mendorong
                                `status` menjadi `Declined`; entri `information`
                                bersifat anjuran dan tidak pernah menolak dengan
                                sendirinya. (`warning` tidak dihasilkan oleh
                                endpoint ini — opsinya hanya menerima `DECLINE`
                                atau `NO_ACTION`.)
                            short_description:
                              type: string
                              description: >-
                                Ringkasan satu baris yang dapat dibaca manusia
                                tentang risiko.
                            long_description:
                              type: string
                              description: Penjelasan risiko yang mudah dibaca manusia.
                      detected_codes:
                        type: array
                        description: >-
                          Kode QR dan barcode yang terdeteksi di setiap halaman
                          dokumen yang diproses. Kosong jika tidak ada yang
                          ditemukan. Kode QR yang ditemukan namun tidak dapat
                          didekode memiliki `parsed_payload: null`.
                        items:
                          $ref: '#/components/schemas/DocumentAIDetectedCode'
                  vendor_data:
                    type: string
                    nullable: true
                    description: Salinan `vendor_data` yang Anda kirimkan, atau `null`.
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: Salinan objek `metadata` yang Anda kirimkan, atau `null`.
                  created_at:
                    type: string
                    format: date-time
                    description: Stempel waktu ISO 8601 (UTC) saat respons dibuat.
        '400':
          description: >-
            Kesalahan validasi atau pemrosesan. Masalah tingkat kolom
            mengembalikan envelope standar DRF (satu array pesan per kolom yang
            bermasalah). Masalah PDF terenkripsi mengembalikan `{"detail":
            ...}`. Dokumen yang tidak dapat diproses oleh pipeline ekstraksi
            mengembalikan `{"error": ["Error extracting POA information"]}`.
          content:
            application/json:
              examples:
                Missing document:
                  summary: '`document` tidak disertakan dalam data formulir'
                  value:
                    document:
                      - No file was submitted.
                Unsupported file extension:
                  summary: Ekstensi file di luar 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: Unggahan melebihi batas 15 MB
                  value:
                    document:
                      - File size should not exceed 15 MB
                Encrypted PDF:
                  summary: PDF diunggah tanpa kata sandi yang diperlukan
                  value:
                    detail: >-
                      The PDF is encrypted. Please upload a decrypted PDF or a
                      photo instead.
                Wrong PDF password:
                  summary: '`document_password` tidak dapat mendekripsi PDF'
                  value:
                    detail: >-
                      The PDF password is incorrect. Please provide the correct
                      password.
                Invalid language code:
                  summary: '`poa_languages_allowed` memuat kode yang tidak didukung'
                  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: >-
                    Nilai `poa_document_age_months` berada di luar rentang 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: Dokumen tidak dapat diproses oleh pipeline ekstraksi
                  value:
                    error:
                      - Error extracting POA information
        '403':
          description: >-
            Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan
            juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya
            panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa
            mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan
            `{"detail": ...}`; kunci yang salah, dicabut, atau kedaluwarsa
            mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan
            `{"error": ...}` sebelum pemrosesan dokumen apa pun terjadi.
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: >-
                    Tidak ada header `x-api-key`, atau kuncinya tidak
                    valid/dicabut
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: Saldo organisasi tidak mencukupi untuk panggilan ini
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '429':
          description: >-
            Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran
            300 permintaan penulisan per menit per kunci API (pembuatan
            transaksi dan ingesti event memiliki anggaran terpisah sebesar 600).
            Respons menyertakan header `X-RateLimit-Limit`,
            `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: Lebih dari 300 permintaan tulis pada menit ini
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '503':
          $ref: '#/components/responses/DocumentProcessingBusy'
      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: >-
            Simbologi yang terdeteksi, misalnya `QR_CODE`, `CODE_128`, `EAN_13`,
            `DATA_MATRIX`, atau `PDF_417`.
        page_number:
          type: integer
          minimum: 1
          description: Nomor halaman berbasis 1.
        position:
          type: array
          nullable: true
          description: >-
            Poligon yang terdeteksi dalam koordinat piksel halaman yang
            dirender. Bernilai `null` jika tidak ada lokasi andal yang tersedia.
          items:
            type: array
            minItems: 2
            maxItems: 2
            items:
              type: integer
        x:
          type: integer
          nullable: true
          description: Tepi kiri bounding box dalam piksel halaman yang dirender.
        'y':
          type: integer
          nullable: true
          description: Tepi atas bounding box dalam piksel halaman yang dirender.
        width:
          type: integer
          nullable: true
          description: Lebar bounding-box dalam piksel halaman yang dirender.
        height:
          type: integer
          nullable: true
          description: Tinggi bounding-box dalam piksel halaman yang dirender.
        page_width:
          type: integer
          description: Lebar halaman yang dirender dalam piksel.
        page_height:
          type: integer
          description: Tinggi halaman yang dirender dalam piksel.
        raw_payload:
          type: string
          description: >-
            Payload dekoder mentah sebagai string base64 jika tersedia; jika
            tidak, berupa string kosong.
        parsed_payload:
          nullable: true
          description: >-
            String atau nilai terstruktur yang didekodekan. `null` jika kode
            ditemukan tetapi tidak dapat didekodekan.
  responses:
    DocumentProcessingBusy:
      description: >-
        Terlalu banyak dokumen yang sedang diproses saat ini, sehingga unggahan
        ini tidak diproses: tidak ada yang disimpan dan tidak ada percobaan yang
        terpakai. Kirim kembali file yang sama setelah menunggu selama jumlah
        detik yang tercantum dalam `Retry-After`. Lakukan percabangan
        berdasarkan `code`, bukan pada teks pesan.
      headers:
        Retry-After:
          description: >-
            Jumlah detik yang harus ditunggu sebelum mengirimkan permintaan yang
            sama lagi.
          schema:
            type: integer
            example: 10
      content:
        application/json:
          schema:
            type: object
            required:
              - detail
              - code
            properties:
              detail:
                type: string
              code:
                type: string
                enum:
                  - document_processing_busy
          example:
            detail: We are busy processing documents. Please try again in a moment.
            code: document_processing_busy
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Kunci API aplikasi Anda, dari Developers -> API keys di Business
        Console. Kunci utama memiliki akses penuh. Kunci bernama dapat diberi
        cakupan: none, read, atau write per sumber daya, dibatasi pada beberapa
        alur kerja atau pada sesi yang disetujui, pada daftar alamat IP, dan
        pada tanggal kedaluwarsa. 401 berarti kuncinya salah, dicabut, atau
        kedaluwarsa; 403 berarti tidak ada kunci yang dikirimkan, kunci tidak
        memiliki akses ke sumber daya atau tindakan ini, atau permintaan datang
        dari alamat di luar daftar IP-nya; 404 pada rute sesi berarti sesi
        berada di luar alur kerja atau status kunci tersebut. Kunci tanpa akses
        media menerima URL gambar, video, dan PDF sebagai null, dan kunci tanpa
        izin tulis sesi menerima tautan sesi dan token sebagai null. Lihat
        https://docs.didit.me/console/api-keys.

````

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