Identity verification is the kind of infrastructure problem that looks simple until you try to build it. A financial agent needs to onboard a user in Brazil, verify their age in Germany, and check sanctions lists in real time. Each jurisdiction has different providers, different document formats, and different regulatory requirements. Most teams end up with seven integrations, three compliance consultants, and a verification flow that drops 40% of legitimate users.
Didit positions itself as “Stripe for Identity Verification,” consolidating KYC (Know Your Customer), AML (Anti-Money Laundering), biometric checks, fraud prevention, and authentication into a single API. The Launch HN post on March 10, 2026 drew 77 points and 66 comments, with engineers asking the right questions: how do you handle state when a biometric check fails mid-flow? What happens when an AML provider times out? How do you cache identity checks without violating GDPR?
The core challenge is building orchestration plumbing that makes identity verification agent-callable without leaking provider-specific complexity or creating compliance landmines.
The Fragmentation Problem
Most identity verification stacks look like this:
- US driver’s licenses: One provider with OCR tuned for state-specific formats
- European NFC chip extraction: Different provider, different SDK, different error codes
- AML screening: Third provider with batch APIs and 2-second latency
- Government database validation: Brazil has one API, India has another, each with unique auth flows
- Liveness detection: Fourth provider, optimized for iPhone 14, breaks on Android 9
- Biometric authentication: Fifth provider with proprietary matching algorithms
Each integration has its own retry logic, rate limits, webhook formats, and failure modes. When an agent tries to onboard a user, it has to orchestrate all of these in sequence, handle partial failures, and decide whether to block the transaction or degrade gracefully.
The alternative is a unified API that abstracts the provider layer. The trade-off is that you now have a single point of failure and a black box that makes debugging harder.
Orchestration Flow for Agent-Driven Verification
Here’s what a typical agent-driven identity check looks like:
- Document capture: User submits a photo of their ID
- OCR extraction: Parse name, DOB, document number
- Liveness check: Verify the person is physically present
- Biometric match: Compare selfie to ID photo
- AML screening: Check sanctions lists and PEP databases
- Government validation: Query official registries (if available)
- Fraud signals: Device fingerprinting, velocity checks, behavioral analysis
- Decision: Approve, reject, or flag for manual review
Each step can fail independently. The orchestration layer needs to decide:
- Do we retry the liveness check if it times out?
- Do we proceed with a partial match if biometric confidence is 85% instead of 95%?
- Do we cache the AML result for 24 hours or re-check on every transaction?
- Do we block the entire flow if one provider is down, or fall back to a secondary?
A unified API hides this complexity but introduces new questions: how do you expose enough control for agents to make intelligent decisions without leaking provider-specific details?
State Synchronization Across Jurisdictions
The hardest part is not calling the APIs. The hardest part is managing state when different jurisdictions have different requirements.
Example: A user in Germany submits a passport. GDPR requires that biometric data be deleted after verification unless the user consents to storage. But if the same user later tries to authenticate from France, you need to re-run the biometric check because you can’t retrieve the stored template. Meanwhile, a user in the US might expect their biometric to be cached for faster login.
The orchestration layer needs to track:
- Which data points are stored and where
- Which checks have been completed and when they expire
- Which jurisdictions allow caching and which require fresh checks
- Which providers are approved in which regions
This is a state machine problem. The naive approach is to store everything in a relational database with a verifications table and a status column. The problem is that status is not a single value. A verification can be:
- Pending document upload
- Document uploaded, OCR in progress
- OCR complete, liveness check pending
- Liveness failed, retry available
- Liveness passed, AML screening in progress
- AML flagged, manual review required
- Approved with conditions (e.g., transaction limits until secondary verification)
Each state transition has different retry logic, timeout behavior, and fallback options. A unified API needs to expose this state in a way that agents can consume without coupling to the underlying provider state machines.
Retry and Fallback Logic for Biometric Failures
Biometric verification fails more often than you think. Poor lighting, camera quality, user confusion, and network latency all contribute to false negatives. The orchestration layer needs to decide:
- Immediate retry: Ask the user to try again right now
- Deferred retry: Allow the user to proceed with limited access and retry later
- Fallback to manual review: Queue the verification for a human operator
- Fallback to alternative method: Switch from facial recognition to document-only verification
The decision depends on context. If an agent is onboarding a new user, you might allow three retries before falling back to manual review. If an agent is authorizing a $10,000 wire transfer, you might require a fresh biometric check with no fallback.
Here’s what the retry logic might look like in pseudocode:
async def verify_biometric(user_id, selfie_image, max_retries=3):
for attempt in range(max_retries):
try:
# Provider adapter normalizes error codes to standard strings
result = await biometric_provider.verify(user_id, selfie_image)
if result.status == "PASS":
return {"approved": True, "confidence": result.confidence}
# "POOR_LIGHTING" is normalized by adapter layer, not raw provider response
if result.status == "FAIL" and result.reason == "POOR_LIGHTING":
if attempt < max_retries - 1:
await notify_user("Please try again in better lighting")
continue
if result.status == "TIMEOUT":
# Fallback to secondary provider with different matching algorithm
result = await fallback_provider.verify(user_id, selfie_image)
if result.status == "PASS":
return {"approved": True, "confidence": result.confidence}
except Exception as e:
# Log provider errors but don't expose to agent
await log_error(f"Biometric verification failed: {e}")
if attempt == max_retries - 1:
break
# Exhausted retries, escalate to manual review
await queue_manual_review(user_id, selfie_image)
return {"approved": False, "reason": "MANUAL_REVIEW_REQUIRED"}
The key is that the agent doesn’t see the provider-specific error codes. It sees a normalized response with a clear decision and a reason code it can act on.
Rate Limits and Caching for Agent Workflows
An agent might call the identity API hundreds of times during account opening or transaction approval. If you’re running a lending agent that checks AML status before every disbursement, you’ll hit rate limits fast.
The caching strategy depends on the check type:
| Check Type | Cache Duration | Invalidation Trigger | Cost per Call |
|---|---|---|---|
| AML screening | 24 hours* | Sanctions list update | $0.50-$2.00 |
| Biometric match | Session-only** | User logout | $0.10-$0.30 |
| Document OCR | Permanent (until re-upload) | User submits new document | $0.05-$0.15 |
| Liveness detection | No cache | N/A | $0.20-$0.50 |
| Government DB lookup | 7 days | Manual refresh request | $1.00-$5.00 |
*EU biometric data cannot be cached without explicit consent per GDPR Article 9. CCPA grants California users deletion rights that override standard cache policies. AML screening duration varies by jurisdiction: some require real-time checks for high-risk transactions.
**Session-only caching for biometric matches reflects GDPR’s requirement to minimize biometric data retention. US-based services may cache longer with user consent.
The orchestration layer needs to balance cost, compliance, and latency. Caching AML results for 24 hours saves money but introduces risk if a user appears on a sanctions list mid-session. Not caching biometric matches improves security but degrades user experience.
A unified API can enforce intelligent caching policies based on risk profile. For example:
- Low-risk users (small transactions, established history): Cache AML for 7 days
- Medium-risk users (new accounts, moderate transactions): Cache AML for 24 hours
- High-risk users (large transactions, flagged behavior): No cache, fresh check every time
The agent can override these defaults by passing a cache_policy parameter, but the API enforces minimum refresh intervals based on regulatory requirements.
Security Boundaries and Observability
The biggest risk with a unified identity API is that it becomes a single point of failure. If the API goes down, every agent that depends on it is blocked. If the API is compromised, every user’s biometric data is exposed.
Security boundaries to enforce:
- API key scoping: Separate keys for sandbox, staging, and production
- Rate limiting per tenant: Prevent one agent from exhausting quota
- Webhook signature verification: HMAC-SHA256 signatures on all callbacks to prevent spoofing
- Data residency controls: Store EU user data in EU regions
- Audit logging: Track every verification attempt with user ID, timestamp, and result
Observability is critical. The orchestration layer needs to expose:
- Latency per provider: Which AML provider is slow today?
- Success rate per check type: Is liveness detection failing more than usual?
- Fallback frequency: How often are we using secondary providers?
- Manual review queue depth: Are we overwhelming human operators?
A good unified API exposes these metrics via a dashboard and webhooks so agents can adapt in real time. If the primary AML provider is down, the agent can switch to a secondary or delay non-critical checks.
Deployment Shape and Failure Modes
A unified identity API typically runs as a multi-region service with the following components:
- API gateway: Routes requests to the appropriate provider based on jurisdiction
- Orchestration engine: Manages state transitions and retry logic
- Provider adapters: Normalize responses from different vendors
- Cache layer: Redis or similar for short-lived results
- Webhook dispatcher: Sends async notifications to agents
- Manual review queue: Postgres or similar for flagged verifications
Failure modes to plan for:
- Provider outage: Primary AML provider is down, fall back to secondary
- Partial failure: Document OCR succeeds but liveness check times out
- Data inconsistency: User’s name on ID doesn’t match government database
- Rate limit exhaustion: Agent hits daily quota mid-flow
- Webhook delivery failure: Agent’s callback endpoint is unreachable
The orchestration layer needs to handle each of these gracefully. For example, if a webhook delivery fails, the API should retry with exponential backoff and eventually store the result for the agent to poll.
Technical Verdict
Use a unified identity API when:
- You’re processing identity verifications across 3+ jurisdictions with different regulatory requirements. The compliance burden of managing GDPR, CCPA, and local data residency rules across multiple direct integrations exceeds the cost of a unified abstraction layer.
- Your agent workflow requires deterministic latency budgets. Unified APIs add orchestration overhead (typically 200-500ms), but eliminate the serial waterfall of calling 5+ providers yourself, which introduces unpredictable tail latency.
- You lack in-house regulatory expertise for jurisdictions like Brazil’s government database APIs, India’s Aadhaar integration, or EU GDPR biometric consent flows. The compliance risk of getting these wrong is high.
- Your engineering team is small and verification is not your core competency. Building and maintaining provider adapters, retry logic, and fallback orchestration is a multi-month project.
Avoid a unified identity API when:
- Your latency SLA is under 100ms for fraud scoring or real-time transaction approval. Unified APIs introduce network hops and orchestration delays that make sub-100ms impossible. Build direct integrations with regional providers instead.
- You require explainable AI for regulatory audits. Most unified APIs use proprietary risk scoring models that don’t expose feature weights or decision trees. If you need to explain to a regulator why a user was flagged, you need full control over the verification logic.
- Your verification volume is under 100 checks per month. The fixed cost of API integration, testing, and monitoring outweighs the savings from consolidation. Use manual review or a single regional provider.
- You operate in a single jurisdiction with stable regulatory requirements. If you’re only verifying US driver’s licenses, a direct integration with a specialized OCR provider will be faster and cheaper than a multi-jurisdictional orchestration layer.
The real value is not the API itself. The real value is the orchestration layer that handles state synchronization, retry logic, caching, and fallback across dozens of providers. If you’re building an agent that needs to verify identities at scale, you’re either building this orchestration layer yourself or paying someone else to do it.
Source Links
- Launch HN: Didit (YC W26) - Stripe for Identity Verification (77 points, 66 comments, March 10, 2026)
- Didit Demo Video