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 45from 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)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);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.ProofOfAddress.Verify(ctx, didit.ProofOfAddressVerifyParams{
Document: didit.FileFromPath("document.pdf"),
ExpectedAddress: didit.String("Av. Monseñor Tavella 1291, Salta, Argentina"),
ExpectedCountry: didit.String("ARG"),
ExpectedFirstName: didit.String("Sophia"),
ExpectedLastName: didit.String("Martinez"),
POALanguagesAllowed: didit.String("en,es"),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)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);<?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());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_husing 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));Proof of Address API: POA Verification & OCR
POST /v3/poa/ to verify utility bills, bank statements, and leases. OCR address extraction, authenticity checks, pay-per-use pricing, no contracts.
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 45from 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)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);ctx := context.Background()
// Reads DIDIT_API_KEY.
client := didit.NewClient()
result, err := client.ProofOfAddress.Verify(ctx, didit.ProofOfAddressVerifyParams{
Document: didit.FileFromPath("document.pdf"),
ExpectedAddress: didit.String("Av. Monseñor Tavella 1291, Salta, Argentina"),
ExpectedCountry: didit.String("ARG"),
ExpectedFirstName: didit.String("Sophia"),
ExpectedLastName: didit.String("Martinez"),
POALanguagesAllowed: didit.String("en,es"),
SaveAPIRequest: didit.Bool(true),
VendorData: didit.String("user-123"),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)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);<?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());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_husing 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));Authorizations
Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is wrong, revoked or expired; 403 means no key was sent, the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys.
Body
The Proof of Address document. Allowed extensions: tiff, jpg, jpeg, png, pdf, webp. Maximum upload size: 15 MB (larger files are rejected with 400). Multi-page PDFs are supported (expect higher latency); encrypted PDFs require document_password. Images are automatically compressed before processing.
Address to verify against the document. It is geocoded and compared with the extracted address; a mismatch (or an expected address that cannot be geocoded/verified) adds ADDRESS_MISMATCH_WITH_PROVIDED, governed by poa_address_mismatch_action. The geocoded form is echoed back in expected_details_formatted_address / expected_details_parsed_address.
"Av. Monseñor Tavella 1291, Salta, Argentina"
Comma-separated list of accepted document languages as ISO 639-1 codes (e.g. en,es,fr). When omitted or blank, all 51 supported languages are accepted. A document in a language outside the list adds UNSUPPORTED_DOCUMENT_LANGUAGE (governed by poa_unsupported_language_action); an unknown code in the list returns 400 with the full set of supported codes.
"en,es"
Comma-separated key:value pairs setting the maximum document age in months per document type — keys: utility_bill, bank_statement, government_issued_document, other_poa_document; values: 1–120, or -1 for unlimited (no age check). Defaults when omitted: utility_bill:3,bank_statement:3,government_issued_document:12,other_poa_document:12. A document older than its limit declines with POA_DOCUMENT_EXPIRED. Caution: when you provide this field, list every type you accept — omitted types are treated as not accepted (informational POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION) and their age check is skipped.
"utility_bill:3,bank_statement:6"
Accepted but currently not applied — name-mismatch warnings (NAME_MISMATCH_WITH_PROVIDED) follow poa_address_mismatch_action instead. Set poa_address_mismatch_action to control both name and address mismatch behavior.
DECLINE, NO_ACTION What to do when document manipulation is suspected (SUSPECTED_DOCUMENT_MANIPULATION) — e.g. the PDF was modified after digital signing, processed by a known PDF editor, shows overlay-text manipulation, or has inconsistent EXIF dates. Also governs POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT (a re-typed text field the file cannot prove changed or unchanged): DECLINE declines it too, NO_ACTION keeps it as a warning.
DECLINE, NO_ACTION When true (default), persists the call as an API-type session — visible in the Business Console, retrievable via GET /v3/session/{sessionId}/decision/ using the returned request_id, announced through a status.updated webhook, and with the uploaded document stored. When false, nothing is stored and request_id is a transient UUID for response correlation only.
true
Response
Document processed. poa.status is Approved or Declined; every detected issue is itemized in poa.warnings. An expired, mismatched, or suspicious document still returns 200 with status: "Declined" — inspect the body, not just the HTTP code. When save_api_request=true, request_id is the persisted session id.