Skip to main content
Didit Raises $7.5M to Build the Infrastructure for Identity and Fraud
Didit
Back to blog
Blog · March 6, 2026

Integrating Didit's Proof of Address with FastAPI and MongoDB

Learn how to build a scalable KYC system by integrating Didit's Proof of Address verification with a FastAPI backend and MongoDB. This guide covers setting up your environment, handling document uploads, processing verification.

By DiditUpdated
integrating-didits-proof-of-address-with-fastapi-and-mongodb.png

Seamless IntegrationIntegrate Didit's Proof of Address API with FastAPI and MongoDB to create a robust and scalable KYC backend, streamlining your verification workflows.

Automated VerificationLeverage Didit's AI-native capabilities for automatic extraction, validation, and authenticity checks of address documents, reducing manual review and improving accuracy.

Configurable WorkflowsUtilize Didit's flexible settings to define custom actions for various verification outcomes, such as name mismatches or document quality issues, ensuring compliance with diverse regulatory requirements.

Scalable & Cost-EffectiveDidit offers a modular, developer-first approach with Free Core KYC and pay-per-successful-check pricing, making it an ideal choice for businesses of all sizes looking for scalable identity verification.

The Challenge of Proof of Address Verification in KYC

Proof of Address (PoA) verification is a critical component of Know Your Customer (KYC) processes across various industries, from financial services to online marketplaces. It's essential for confirming a user's physical residence, helping to prevent fraud, comply with Anti-Money Laundering (AML) regulations, and establish trust. However, manually reviewing utility bills, bank statements, and government-issued documents is time-consuming, prone to human error, and doesn't scale. Businesses need a robust, automated, and secure solution to handle the complexities of PoA verification while maintaining a smooth user experience.

Traditional PoA solutions often involve complex integrations, high setup costs, and rigid workflows. This is where modern, AI-native identity platforms like Didit shine, offering a developer-first approach that simplifies integration and provides powerful, automated verification capabilities. By combining Didit's Proof of Address API with a scalable backend like FastAPI and a flexible NoSQL database like MongoDB, businesses can build highly efficient and compliant KYC systems.

Setting Up Your FastAPI and MongoDB Environment

To begin, you'll need a FastAPI application and a MongoDB instance. FastAPI is chosen for its high performance and ease of use, while MongoDB offers the flexibility to store diverse document types and verification reports. Here’s a basic setup:

1. FastAPI Application Setup

First, install FastAPI and Uvicorn:

pip install fastapi uvicorn python-multipart motor

Create a main.py file:

from fastapi import FastAPI, UploadFile, File, Form, HTTPException
from motor.motor_asyncio import AsyncIOMotorClient
from typing import Optional
import httpx
import os

app = FastAPI()

# MongoDB setup
MONGO_DETAILS = os.getenv("MONGO_DETAILS", "mongodb://localhost:27017")
client = AsyncIOMotorClient(MONGO_DETAILS)
database = client.didit_kyc

# Didit API Key
DIDIT_API_KEY = os.getenv("DIDIT_API_KEY")
if not DIDIT_API_KEY:
    raise ValueError("DIDIT_API_KEY environment variable not set")

@app.on_event("startup")
async def startup_db_client():
    app.mongodb_client = client
    app.mongodb = database

@app.on_event("shutdown")
async def shutdown_db_client():
    app.mongodb_client.close()

@app.get("/health")
async def health_check():
    return {"status": "ok", "message": "FastAPI is running"}

2. MongoDB Connection

Ensure MongoDB is running, either locally or via a cloud service. The motor library enables asynchronous interaction with MongoDB, crucial for high-performance FastAPI applications.

Integrating Didit's Proof of Address API

Didit's Proof of Address API allows you to submit document images or PDFs for verification, extracting and validating address information, performing authenticity checks, and returning structured data. This process is designed to be highly automated and accurate, thanks to Didit's AI-native architecture.

1. Sending Documents to Didit

You'll need an endpoint in your FastAPI application to accept document uploads and forward them to Didit. Didit's API supports various document types (PDF, JPEG, PNG, WebP, TIFF) and offers configurable parameters for enhanced validation.

@app.post("/verify-poa/")
async def verify_proof_of_address(
    document: UploadFile = File(...),
    expected_first_name: Optional[str] = Form(None),
    expected_last_name: Optional[str] = Form(None),
    expected_address: Optional[str] = Form(None),
    expected_country: Optional[str] = Form(None),
    poa_name_mismatch_action: str = Form("DECLINE"),
    poa_document_issues_action: str = Form("DECLINE"),
    poa_document_authenticity_action: str = Form("DECLINE"),
):
    if not document.content_type.startswith(('image/', 'application/pdf')):
        raise HTTPException(status_code=400, detail="Invalid document format. Only images and PDFs are allowed.")

    DIDIT_POA_ENDPOINT = "https://verification.didit.me/v3/poa/"
    headers = {"x-api-key": DIDIT_API_KEY}

    # Prepare form data for Didit API
    files = {'document': (document.filename, document.file.read(), document.content_type)}
    data = {
        "poa_name_mismatch_action": poa_name_mismatch_action,
        "poa_document_issues_action": poa_document_issues_action,
        "poa_document_authenticity_action": poa_document_authenticity_action,
    }
    if expected_first_name: data["expected_first_name"] = expected_first_name
    if expected_last_name: data["expected_last_name"] = expected_last_name
    if expected_address: data["expected_address"] = expected_address
    if expected_country: data["expected_country"] = expected_country

    async with httpx.AsyncClient() as client:
        try:
            didit_response = await client.post(DIDIT_POA_ENDPOINT, headers=headers, files=files, data=data, timeout=30.0)
            didit_response.raise_for_status()
            poa_result = didit_response.json()

            # Store the result in MongoDB
            verification_record = {
                "filename": document.filename,
                "user_id": "some_user_id", # Replace with actual user ID from your system
                "timestamp": datetime.utcnow(),
                "didit_response": poa_result,
                "status": poa_result['poa']['status']
            }
            await app.mongodb["poa_verifications"].insert_one(verification_record)

            return {"message": "POA verification initiated and result stored.", "result": poa_result}
        except httpx.HTTPStatusError as e:
            raise HTTPException(status_code=e.response.status_code, detail=f"Didit API error: {e.response.text}")
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")

This endpoint handles the file upload, constructs the request for Didit's API, and then processes the response. Note the use of httpx.AsyncClient for non-blocking HTTP requests, which is crucial for FastAPI's performance.

2. Understanding Didit's Proof of Address Report

Didit provides a comprehensive JSON report for each PoA verification. This report includes:

  • poa.status: The overall verification status (Approved, Declined, In Review).
  • poa.document_type: Automatically detected document type (e.g., UTILITY_BILL, BANK_STATEMENT).
  • poa.issuer, poa.issue_date, poa.expiration_date: Key document details.
  • poa.name_on_document, poa.poa_address, poa.poa_formatted_address, poa.poa_parsed_address: Extracted and structured address information.
  • poa.warnings: A list of any warnings or issues detected, such as POOR_DOCUMENT_QUALITY, NAME_MISMATCH_WITH_PROVIDED, or SUSPECTED_DOCUMENT_MANIPULATION.

These detailed insights allow for sophisticated decision-making and automated handling of edge cases. Didit's configurable verification settings, such as poa_name_mismatch_action or poa_document_issues_action, allow you to define how your system reacts to specific risks, ensuring compliance and reducing manual intervention.

Storing and Managing Verification Data with MongoDB

MongoDB is an excellent choice for storing PoA verification results due to its flexible document model. You can store the entire JSON response from Didit directly, allowing for easy querying and analysis without predefined schemas. This flexibility is vital as verification requirements evolve or new data points become available.

1. Storing the Verification Record

As shown in the FastAPI example, the didit_response is stored directly in a poa_verifications collection. This approach captures all the rich data provided by Didit.

2. Querying Verification Records

You can easily query your MongoDB collection to retrieve verification statuses, documents needing review, or specific user data:

from datetime import datetime

@app.get("/poa-verifications/{user_id}")
async def get_poa_history(user_id: str):
    records = await app.mongodb["poa_verifications"].find({"user_id": user_id}).to_list(100)
    if not records:
        raise HTTPException(status_code=404, detail="No POA records found for this user.")
    # MongoDB _id is an ObjectId, convert to string for JSON serialization
    for record in records:
        record["_id"] = str(record["_id"])
    return records

@app.get("/poa-needs-review/")
async def get_poa_needs_review():
    records = await app.mongodb["poa_verifications"].find({"status": "In Review"}).to_list(100)
    for record in records:
        record["_id"] = str(record["_id"])
    return records

These endpoints allow you to fetch a user's PoA history or retrieve all verifications that require manual review, demonstrating the power of MongoDB in managing complex compliance data.

How Didit Helps

Didit provides an AI-native, developer-first identity platform that simplifies complex identity verification processes like Proof of Address. Our Proof of Address product offers comprehensive validation by extracting and verifying key information from various documents. It automatically detects document types, parses addresses into structured formats, and performs authenticity checks to identify potential manipulation. With Didit, you benefit from:

  • Modular Architecture: Easily integrate PoA verification as a standalone service or combine it with other Didit products like ID Verification and AML Screening & Monitoring to build complete KYC workflows.
  • AI-Native Accuracy: Our advanced AI and machine learning algorithms ensure high accuracy in data extraction and fraud detection, minimizing false positives and negatives.
  • Configurable Workflows: Define custom rules and actions for different risk scenarios, such as name mismatches, document quality issues, or suspected manipulation, directly through our APIs or no-code Business Console.
  • Developer-First Experience: With an instant sandbox, comprehensive public documentation, and clean APIs, developers can integrate Didit quickly and efficiently.
  • Cost-Effective Scaling: Didit offers Free Core KYC and a pay-per-successful-check model, eliminating setup fees and ensuring you only pay for what you use, making it ideal for scalable operations.

By leveraging Didit, businesses can automate trust, streamline compliance, and deliver a superior user onboarding experience without the burden of complex infrastructure or manual review.

Ready to Get Started?

Ready to see Didit in action? Get a free demo today.

Start verifying identities for free with Didit's free tier.

Infrastructure for identity and fraud.

One API for KYC, KYB, Transaction Monitoring, and Wallet Screening. Integrate in 5 minutes.

Ask an AI to summarise this page
Didit Proof of Address: FastAPI & MongoDB Integration.