Didit ID Verification API
Overview
Verifies identity documents by submitting images of the front and back sides. Performs OCR extraction, MRZ parsing, authenticity checks, and document liveness detection.
Key constraints:
- Supported formats: JPEG, PNG, WebP, TIFF
- Maximum file size: 5MB per image
- All document corners must be visible, full-color, no glare/shadows
- Original real-time photos only (no screenshots, scans, or digital copies)
Coverage: 4,000+ document types, 220+ countries, 130+ languages. Supports passports, national ID cards, driver's licenses, and residence permits.
Processing pipeline:
- Intelligent capture & document type detection
- OCR text extraction + MRZ/barcode parsing
- Template matching, security feature validation, tamper detection
- Document liveness (detects screen captures, printed copies, portrait manipulation)
API Reference: https://docs.didit.me/standalone-apis/id-verification
Feature Guide: https://docs.didit.me/core-technology/id-verification/overview
Supported Documents: https://docs.didit.me/core-technology/id-verification/supported-documents-id-verification
Authentication
All requests require x-api-key header. Get your key from Didit Business Console → API & Webhooks, or via programmatic registration (see below).
Getting Started (No Account Yet?)
If you don't have a Didit API key, create one in 2 API calls:
- Register:
POST https://apx.didit.me/auth/v2/programmatic/register/ with {"email": "you@gmail.com", "password": "MyStr0ng!Pass"}
- Check email for a 6-character OTP code
- Verify:
POST https://apx.didit.me/auth/v2/programmatic/verify-email/ with {"email": "you@gmail.com", "code": "A3K9F2"} → response includes api_key
To add credits: GET /v3/billing/balance/ to check, POST /v3/billing/top-up/ with {"amount_in_dollars": 50} for a Stripe checkout link.
See the didit-verification-management skill for full platform management (workflows, sessions, users, billing).
Endpoint
POST https://verification.didit.me/v3/id-verification/
Headers
| Header |
Value |
Required |
x-api-key |
Your API key |
Yes |
Content-Type |
multipart/form-data |
Yes |
Request Parameters (multipart/form-data)
| Parameter |
Type |
Required |
Default |
Constraints |
Description |
front_image |
file |
Yes |
— |
JPEG/PNG/WebP/TIFF, max 5MB |
Front image of ID document |
back_image |
file |
No |
— |
Same as above |
Back image (when applicable) |
save_api_request |
boolean |
No |
true |
— |
Save in Business Console Manual Checks |
vendor_data |
string |
No |
— |
— |
Your identifier for session tracking |
Example
import requests
response = requests.post(
"https://verification.didit.me/v3/id-verification/",
headers={"x-api-key": "YOUR_API_KEY"},
files={
"front_image": ("front.jpg", open("front.jpg", "rb"), "image/jpeg"),
"back_image": ("back.jpg", open("back.jpg", "rb"), "image/jpeg"),
},
data={"vendor_data": "user-123"},
)
const formData = new FormData();
formData.append("front_image", frontImageFile);
formData.append("back_image", backImageFile);
formData.append("vendor_data", "user-123");
const response = await fetch("https://verification.didit.me/v3/id-verification/", {
method: "POST",
headers: { "x-api-key": "YOUR_API_KEY" },
body: formData,
});
Response (200 OK)
{
"request_id": "a1b2c3d4-...",
"id_verification": {
"status": "Approved",
"document_type": "Identity Card",
"document_number": "YZA123456",
"personal_number": "X9876543L",
"first_name": "Elena",
"last_name": "Martínez Sánchez",
"full_name": "Elena Martínez Sánchez",
"date_of_birth": "1985-03-15",
"age": 40,
"gender": "F",
"nationality": "ESP",
"issuing_state": "ESP",
"issuing_state_name": "Spain",
"expiration_date": "2030-08-21",
"date_of_issue": "2020-08-21",
"address": "Calle Mayor 10, Madrid",
"formatted_address": "Calle Mayor 10, 28013 Madrid, Spain",
"place_of_birth": "Valencia",
"portrait_image": "<base64>",
"front_document_image": "<base64>",
"back_document_image": "<base64>",
"mrz": {
"surname": "MARTINEZ SANCHEZ",
"given_name": "ELENA",
"document_type": "I",
"document_number": "YZA123456",
"country": "ESP",
"nationality": "ESP",
"birth_date": "850315",
"expiry_date": "300821",
"sex": "F"
},
"parsed_address": {"city": "Madrid", "region": "...", "postal_code": "28013", "country": "ES"},
"warnings": []
},
"created_at": "2025-05-01T13:11:07.977806Z"
}
Status Values
| Status |
Meaning |
"Approved" |
Document verified successfully |
"Declined" |
Verification failed (see warnings) |
"In Review" |
Requires manual review |
Error Responses
| Code |
Meaning |
Action |
400 |
Invalid request |
Check file format, size, parameters |
401 |
Invalid API key |
Verify x-api-key header |
403 |
Insufficient credits |
Top up at business.didit.me |
Response Field Reference
| Field |
Type |
Description |
status |
string |
"Approved", "Declined", "In Review" |
document_type |
string |
"Passport", "Identity Card", "Driver's License", "Residence Permit" |
document_number |
string |
Document ID number |
personal_number |
string |
Personal/national ID number |
first_name, last_name, full_name |
string |
Extracted name fields |
date_of_birth |
string |
YYYY-MM-DD |
age |
integer |
Calculated age |
gender |
string |
"M", "F", "U" |
nationality, issuing_state |
string |
ISO 3166-1 alpha-3 |
expiration_date, date_of_issue |
string |
YYYY-MM-DD |
portrait_image |
string |
Base64-encoded portrait from document |
mrz |
object |
Machine Readable Zone data |
parsed_address |
object |
Geocoded address: {city, region, postal_code, country, street_1} |
warnings |
array |
{risk, log_type, short_description, long_description} |
Warning Tags
Auto-Decline (always)
| Tag |
Description |
ID_DOCUMENT_IN_BLOCKLIST |
Document in blocklist (previously flagged) |
PORTRAIT_IMAGE_NOT_DETECTED |
No portrait found on document |
DOCUMENT_EXPIRED |
Document expiration date has passed |
DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION |
Document type not accepted |
Configurable (Decline / Review / Approve)
| Category |
Tags |
| Document liveness |
SCREEN_CAPTURE_DETECTED, PRINTED_COPY_DETECTED, PORTRAIT_MANIPULATION_DETECTED |
| MRZ issues |
MRZ_NOT_DETECTED, MRZ_VALIDATION_FAILED, MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME |
| Data issues |
NAME_NOT_DETECTED, DATE_OF_BIRTH_NOT_DETECTED, DOCUMENT_NUMBER_NOT_DETECTED, DATA_INCONSISTENT |
| Duplicates |
POSSIBLE_DUPLICATED_USER |
| Expected mismatch |
FULL_NAME_MISMATCH_WITH_PROVIDED, DOB_MISMATCH_WITH_PROVIDED, GENDER_MISMATCH_WITH_PROVIDED |
| Geolocation |
DOCUMENT_COUNTRY_MISMATCH |
Common Workflows
Basic ID Verification
1. POST /v3/id-verification/ → front_image (+ back_image if applicable)
2. If "Approved" → extract first_name, last_name, date_of_birth, document_number
If "Declined" → check warnings:
DOCUMENT_EXPIRED → ask for valid document
SCREEN_CAPTURE_DETECTED → ask for real photo of physical document
MRZ_VALIDATION_FAILED → ask for clearer image
Full Identity Verification Pipeline
1. POST /v3/id-verification/ → verify document
2. POST /v3/passive-liveness/ → verify real person
3. POST /v3/face-match/ → compare selfie to document portrait
4. POST /v3/aml/ → screen extracted name/DOB/nationality
5. All Approved → fully verified identity
Utility Scripts
export DIDIT_API_KEY="your_api_key"
python scripts/verify_id.py front.jpg
python scripts/verify_id.py front.jpg back.jpg --vendor-data user-123
1---2name: didit-id-document-verification3description: Verifies identity documents via the Didit standalone API. Use when verifying a passport, ID card, driver's license, or residence permit, performing OCR extraction, MRZ parsing, document authenticity checks, or KYC document validation. Supports 4000+ document types across 220+ countries.4---5
6# Didit ID Verification API
7
8## Overview
9
10Verifies identity documents by submitting images of the front and back sides. Performs OCR extraction, MRZ parsing, authenticity checks, and document liveness detection.
11
12**Key constraints:**
13- Supported formats: **JPEG, PNG, WebP, TIFF**
14- Maximum file size: **5MB** per image
15- All document corners must be visible, full-color, no glare/shadows
16- Original real-time photos only (no screenshots, scans, or digital copies)
17
18**Coverage:** 4,000+ document types, 220+ countries, 130+ languages. Supports passports, national ID cards, driver's licenses, and residence permits.
19
20**Processing pipeline:**
211. Intelligent capture & document type detection
222. OCR text extraction + MRZ/barcode parsing
233. Template matching, security feature validation, tamper detection
244. Document liveness (detects screen captures, printed copies, portrait manipulation)
25
26**API Reference:** https://docs.didit.me/standalone-apis/id-verification
27**Feature Guide:** https://docs.didit.me/core-technology/id-verification/overview
28**Supported Documents:** https://docs.didit.me/core-technology/id-verification/supported-documents-id-verification
29
30---
31
32## Authentication
33
34All requests require `x-api-key` header. Get your key from [Didit Business Console](https://business.didit.me) → API & Webhooks, or via programmatic registration (see below).
35
36## Getting Started (No Account Yet?)
37
38If you don't have a Didit API key, create one in 2 API calls:
39
401. **Register:** `POST https://apx.didit.me/auth/v2/programmatic/register/` with `{"email": "you@gmail.com", "password": "MyStr0ng!Pass"}`
412. **Check email** for a 6-character OTP code
423. **Verify:** `POST https://apx.didit.me/auth/v2/programmatic/verify-email/` with `{"email": "you@gmail.com", "code": "A3K9F2"}` → response includes `api_key`
43
44**To add credits:** `GET /v3/billing/balance/` to check, `POST /v3/billing/top-up/` with `{"amount_in_dollars": 50}` for a Stripe checkout link.
45
46See the **didit-verification-management** skill for full platform management (workflows, sessions, users, billing).
47
48---
49
50## Endpoint
51
52```
53POST https://verification.didit.me/v3/id-verification/
54```
55
56### Headers
57
58| Header | Value | Required |
59|---|---|---|
60| `x-api-key` | Your API key | **Yes** |
61| `Content-Type` | `multipart/form-data` | **Yes** |
62
63### Request Parameters (multipart/form-data)
64
65| Parameter | Type | Required | Default | Constraints | Description |
66|---|---|---|---|---|---|
67| `front_image` | file | **Yes** | — | JPEG/PNG/WebP/TIFF, max 5MB | Front image of ID document |
68| `back_image` | file | No | — | Same as above | Back image (when applicable) |
69| `save_api_request` | boolean | No | `true` | — | Save in Business Console Manual Checks |
70| `vendor_data` | string | No | — | — | Your identifier for session tracking |
71
72### Example
73
74```python
75import requests
76
77response = requests.post(
78 "https://verification.didit.me/v3/id-verification/",
79 headers={"x-api-key": "YOUR_API_KEY"},
80 files={
81 "front_image": ("front.jpg", open("front.jpg", "rb"), "image/jpeg"),
82 "back_image": ("back.jpg", open("back.jpg", "rb"), "image/jpeg"),
83 },
84 data={"vendor_data": "user-123"},
85)
86```
87
88```typescript
89const formData = new FormData();
90formData.append("front_image", frontImageFile);
91formData.append("back_image", backImageFile);
92formData.append("vendor_data", "user-123");
93
94const response = await fetch("https://verification.didit.me/v3/id-verification/", {
95 method: "POST",
96 headers: { "x-api-key": "YOUR_API_KEY" },
97 body: formData,
98});
99```
100
101### Response (200 OK)
102
103```json
104{
105 "request_id": "a1b2c3d4-...",
106 "id_verification": {
107 "status": "Approved",
108 "document_type": "Identity Card",
109 "document_number": "YZA123456",
110 "personal_number": "X9876543L",
111 "first_name": "Elena",
112 "last_name": "Martínez Sánchez",
113 "full_name": "Elena Martínez Sánchez",
114 "date_of_birth": "1985-03-15",
115 "age": 40,
116 "gender": "F",
117 "nationality": "ESP",
118 "issuing_state": "ESP",
119 "issuing_state_name": "Spain",
120 "expiration_date": "2030-08-21",
121 "date_of_issue": "2020-08-21",
122 "address": "Calle Mayor 10, Madrid",
123 "formatted_address": "Calle Mayor 10, 28013 Madrid, Spain",
124 "place_of_birth": "Valencia",
125 "portrait_image": "<base64>",
126 "front_document_image": "<base64>",
127 "back_document_image": "<base64>",
128 "mrz": {
129 "surname": "MARTINEZ SANCHEZ",
130 "given_name": "ELENA",
131 "document_type": "I",
132 "document_number": "YZA123456",
133 "country": "ESP",
134 "nationality": "ESP",
135 "birth_date": "850315",
136 "expiry_date": "300821",
137 "sex": "F"
138 },
139 "parsed_address": {"city": "Madrid", "region": "...", "postal_code": "28013", "country": "ES"},
140 "warnings": []
141 },
142 "created_at": "2025-05-01T13:11:07.977806Z"
143}
144```
145
146### Status Values
147
148| Status | Meaning |
149|---|---|
150| `"Approved"` | Document verified successfully |
151| `"Declined"` | Verification failed (see `warnings`) |
152| `"In Review"` | Requires manual review |
153
154### Error Responses
155
156| Code | Meaning | Action |
157|---|---|---|
158| `400` | Invalid request | Check file format, size, parameters |
159| `401` | Invalid API key | Verify `x-api-key` header |
160| `403` | Insufficient credits | Top up at business.didit.me |
161
162---
163
164## Response Field Reference
165
166| Field | Type | Description |
167|---|---|---|
168| `status` | string | `"Approved"`, `"Declined"`, `"In Review"` |
169| `document_type` | string | `"Passport"`, `"Identity Card"`, `"Driver's License"`, `"Residence Permit"` |
170| `document_number` | string | Document ID number |
171| `personal_number` | string | Personal/national ID number |
172| `first_name`, `last_name`, `full_name` | string | Extracted name fields |
173| `date_of_birth` | string | `YYYY-MM-DD` |
174| `age` | integer | Calculated age |
175| `gender` | string | `"M"`, `"F"`, `"U"` |
176| `nationality`, `issuing_state` | string | ISO 3166-1 alpha-3 |
177| `expiration_date`, `date_of_issue` | string | `YYYY-MM-DD` |
178| `portrait_image` | string | Base64-encoded portrait from document |
179| `mrz` | object | Machine Readable Zone data |
180| `parsed_address` | object | Geocoded address: `{city, region, postal_code, country, street_1}` |
181| `warnings` | array | `{risk, log_type, short_description, long_description}` |
182
183---
184
185## Warning Tags
186
187### Auto-Decline (always)
188
189| Tag | Description |
190|---|---|
191| `ID_DOCUMENT_IN_BLOCKLIST` | Document in blocklist (previously flagged) |
192| `PORTRAIT_IMAGE_NOT_DETECTED` | No portrait found on document |
193| `DOCUMENT_EXPIRED` | Document expiration date has passed |
194| `DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` | Document type not accepted |
195
196### Configurable (Decline / Review / Approve)
197
198| Category | Tags |
199|---|---|
200| **Document liveness** | `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED` |
201| **MRZ issues** | `MRZ_NOT_DETECTED`, `MRZ_VALIDATION_FAILED`, `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` |
202| **Data issues** | `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`, `DOCUMENT_NUMBER_NOT_DETECTED`, `DATA_INCONSISTENT` |
203| **Duplicates** | `POSSIBLE_DUPLICATED_USER` |
204| **Expected mismatch** | `FULL_NAME_MISMATCH_WITH_PROVIDED`, `DOB_MISMATCH_WITH_PROVIDED`, `GENDER_MISMATCH_WITH_PROVIDED` |
205| **Geolocation** | `DOCUMENT_COUNTRY_MISMATCH` |
206
207---
208
209## Common Workflows
210
211### Basic ID Verification
212
213```
2141. POST /v3/id-verification/ → front_image (+ back_image if applicable)
2152. If "Approved" → extract first_name, last_name, date_of_birth, document_number
216 If "Declined" → check warnings:
217 DOCUMENT_EXPIRED → ask for valid document
218 SCREEN_CAPTURE_DETECTED → ask for real photo of physical document
219 MRZ_VALIDATION_FAILED → ask for clearer image
220```
221
222### Full Identity Verification Pipeline
223
224```
2251. POST /v3/id-verification/ → verify document
2262. POST /v3/passive-liveness/ → verify real person
2273. POST /v3/face-match/ → compare selfie to document portrait
2284. POST /v3/aml/ → screen extracted name/DOB/nationality
2295. All Approved → fully verified identity
230```
231
232---
233
234## Utility Scripts
235
236```bash
237export DIDIT_API_KEY="your_api_key"
238
239python scripts/verify_id.py front.jpg
240python scripts/verify_id.py front.jpg back.jpg --vendor-data user-123
241```