Identity Document Verification
Verify identity documents provided by the client (not the consumer). Useful when you already have document images and need verification without consumer interaction.
Overview
Use Case: Verify identity documents when the client has already collected them and needs verification without involving the consumer in the flow.
Key Features:
- Client uploads document files to Thirdfort's secure file storage
- Document authenticity verification and data extraction
- No consumer interaction required
- Completes once documents are uploaded and processed
Subject Type: Individual
Template ID: checkTemplates/identity-document-verification-check-v1-0-0
When to Use This Check
✅ Good for:
- Verifying documents already collected by the client
- Batch processing of existing document images
- Situations where consumer cannot use mobile app
- Integration with existing document collection systems
❌ Not suitable for:
- Full identity verification with consumer in the flow (use Identity Verification instead)
- AML screening (sanctions/PEP) of the subject (use Client-Only Verification or Identity Verification instead)
- Source of funds verification (use Source of Funds instead)
Prerequisites
- Thirdfort account with API access
- Client credentials (Client ID and Secret)
- Document files: Images or PDFs of an identity document (see Document Requirements)
- Subject data: The subject's name as it appears on the document
Parameters Reference
Required Parameters
| Parameter | Type | Description |
|---|---|---|
displayName | string | Human-readable name for the check |
clientReference | string | Your own reference ID for tracking |
template | string | Must be checkTemplates/identity-document-verification-check-v1-0-0 |
params.@type | string | Must be type.googleapis.com/thirdfort.client.checks.type.v1.IdentityDocumentVerificationCheckParams |
params.subject.givenName | string | First name from the document |
params.subject.familyName | string | Last name from the document |
params.document.documentType | enum | One of PASSPORT, DRIVING_LICENCE, NATIONAL_IDENTITY_CARD, RESIDENCE_PERMIT, OTHER |
params.document.files | array | The uploaded files that make up the document. Each entry has a side (FRONT or BACK) and a documentUploadId |
A FRONT file is always required. A BACK file is also required for every document type except PASSPORT, which is single-sided.
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
params.subject.otherNames | string | - | Middle names from the document |
params.relationshipType | string | - | Free-form description of your relationship with the subject |
Document Upload Flow
Step 1: Upload Document Files
Upload each side of the document to Thirdfort's secure file storage before creating the check. The upload endpoint implements the tus resumable upload protocol. Any tus client library works, or you can make the requests directly.
| Environment | Upload endpoint |
|---|---|
| Nonproduction | https://files.thirdfort.dev/client/uploads |
| Production | https://files.thirdfort.com/client/uploads |
Authenticate with the same OAuth 2.0 access token you use for API calls. Every upload must carry fileName and relatedResourceName, and the upload is rejected with 400 without them. Also set objectType: the upload succeeds without it, but Thirdfort uses it to categorise the file and to clean up uploads that are never attached to a check.
| Metadata key | Value |
|---|---|
fileName | The file name, including its extension. The extension sets the file type, so use .jpg, .jpeg, .png or .pdf |
relatedResourceName | The team the check will be created in, e.g. organizations/{org_id}/teams/{team_id}. The check does not exist yet. Once it is created, Thirdfort re-associates the files with it |
objectType | IDV_DOCUMENT |
First, create the upload. tus requires each metadata value to be base64-encoded:
curl -i -X POST "https://files.thirdfort.dev/client/uploads" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Tus-Resumable: 1.0.0" \
-H "Upload-Length: $(wc -c < passport-front.jpg | tr -d ' ')" \
-H "Upload-Metadata: fileName $(printf 'passport-front.jpg' | base64),relatedResourceName $(printf 'organizations/{org_id}/teams/{team_id}' | base64),objectType $(printf 'IDV_DOCUMENT' | base64)"
The response is 201 Created. Its Location header is the upload URL, which ends in objects/{object_id}.
Then send the file content to that URL:
curl -X PATCH "UPLOAD_URL_FROM_LOCATION_HEADER" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Tus-Resumable: 1.0.0" \
-H "Upload-Offset: 0" \
-H "Content-Type: application/offset+octet-stream" \
--data-binary @passport-front.jpg
The upload is complete when the server returns 204 No Content. Use the last two path segments of the upload URL, objects/{object_id}, as the file's documentUploadId.
Step 2: Create Check with Document References
curl -X POST "https://api.thirdfort.dev/client/api/v1/organizations/{org_id}/teams/{team_id}/checks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"displayName": "Document verification for Jane Smith",
"clientReference": "doc-verify-12345",
"template": "checkTemplates/identity-document-verification-check-v1-0-0",
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1.IdentityDocumentVerificationCheckParams",
"subject": {
"givenName": "Jane",
"familyName": "Smith"
},
"document": {
"documentType": "DRIVING_LICENCE",
"files": [
{ "side": "FRONT", "documentUploadId": "objects/3f6d2a1e-5b7c-4e8f-9a0b-1c2d3e4f5a6b" },
{ "side": "BACK", "documentUploadId": "objects/7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d" }
]
}
}
}'
Note: The endpoint includes the parent (team) in the URL path. Replace {org_id} and {team_id} with your actual organization and team IDs.
Thirdfort validates the uploaded files before the check is created. If a file fails validation, the request fails with FAILED_PRECONDITION and the check is not created. See Document validation errors.
Response
{
"name": "organizations/NT6bqXp6k47SbagGAUHHG7/teams/gZzg3caveKLhe3VXjRiyXL/checks/eaa99a49-7c7c-43e0-a929-ec2dddec8a85",
"displayName": "Document verification for Jane Smith",
"clientReference": "doc-verify-12345",
"state": "ACTIVE",
"createTime": "2026-03-06T14:06:59.758655Z",
"updateTime": null,
"template": "checkTemplates/identity-document-verification-check-v1-0-0",
"params": { ... },
"relatedSubjects": [ ... ],
"creator": "partners/thirdfort/integrations/4",
...
}
Summary Response
{
"name": "organizations/.../teams/.../checks/.../checkSummary",
"createTime": "2026-03-06T14:07:00.537001Z",
"payload": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1.IdentityDocumentVerificationCheckSummary",
"overallRecommendation": {
"recommendation": "CLEAR",
"description": "No concerning issues found"
},
"identityDocumentVerificationCheckResult": { ... },
"providedSubjectData": { ... },
"pdfReportUrl": "https://files.thirdfort.dev/client/downloads/objects/6ff46f10-ae87-42e6-8601-1f0c32ed5ba6",
"summaryPdfReportUrl": "https://files.thirdfort.dev/client/downloads/objects/8df632f9-e3f9-4e9e-88aa-ca449debf3b8"
},
"sourceFindings": [ ... ],
"reportUrl": "https://files.thirdfort.dev/client/downloads/objects/6ff46f10-ae87-42e6-8601-1f0c32ed5ba6",
"summaryReportUrl": "https://files.thirdfort.dev/client/downloads/objects/8df632f9-e3f9-4e9e-88aa-ca449debf3b8"
}
Result Fields
| Field | Description |
|---|---|
payload.overallRecommendation | Overall check recommendation object with recommendation and description |
payload.identityDocumentVerificationCheckResult | Document verification results, with a recommendation and the sourceFindings that produced it |
payload.providedSubjectData | Echo of the subject data you provided |
payload.pdfReportUrl | Download link for the full PDF report |
payload.summaryPdfReportUrl | Download link for the summary PDF report |
reportUrl | Download link for full PDF report (top-level field) |
summaryReportUrl | Download link for summary PDF report (top-level field) |
sourceFindings | Array of finding resource names that contributed to this summary |
The data extracted from the document, such as names, date of birth, document numbers, expiry date and MRZ lines, is returned as an IdentityDocumentExtractedDataFinding. Use ListFindings to retrieve it.
Recommendation Values
CLEAR: No concerning issues were found. Results should still be reviewed before you rely on themCONSIDER: Anomalies detected that may be explainable - review findingsFAIL: Serious anomalies detected, unlikely explainable - high risk
Downloading PDF Reports
Download PDF reports using the URLs from the summary:
# Download full PDF report
curl -X GET "https://files.thirdfort.dev/client/downloads/objects/6ff46f10-ae87-42e6-8601-1f0c32ed5ba6" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-o doc-verify-report.pdf
# Download summary PDF report
curl -X GET "https://files.thirdfort.dev/client/downloads/objects/8df632f9-e3f9-4e9e-88aa-ca449debf3b8" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-o doc-verify-summary.pdf
Note:
- PDF downloads require the same OAuth 2.0 access token used for API calls
- Use the complete URLs from
reportUrlandsummaryReportUrlfields directly - URLs include
/objects/in the path
Document Requirements
Supported Document Types
documentType | Files required |
|---|---|
PASSPORT | FRONT (photo page) |
DRIVING_LICENCE | FRONT and BACK |
NATIONAL_IDENTITY_CARD | FRONT and BACK |
RESIDENCE_PERMIT | FRONT and BACK |
OTHER | FRONT and BACK |
File Requirements
Each file must be:
- JPEG, PNG or PDF
- At least 32 KB and at most 10 MB
- No more than 64 megapixels, for JPEG and PNG images
For the best verification results, images should also:
- Be in focus and clearly readable
- Have good lighting (no glare or shadows)
- Show the entire document (all edges visible)
- Be in color (not black and white)
Document Validation Errors
When a file fails validation, CreateCheck returns FAILED_PRECONDITION. The error details carry one or more violations for each failing file, so read all of them. Each violation's subject is the file's documentUploadId, and its type is one of these codes:
| Code | Meaning |
|---|---|
INVALID_MIME_TYPE | The file is not JPEG, PNG or PDF |
FILE_TOO_SMALL | The file is smaller than 32 KB |
FILE_TOO_LARGE | The file is larger than 10 MB |
IMAGE_RESOLUTION_TOO_HIGH | The image is larger than 64 megapixels |
MISSING_DOCUMENT_DATA | The file is empty |
CUT_OFF | Part of the document is cut off |
BLUR | The document is blurred |
DOCUMENT_NOT_DETECTED | No document was found in the image |
UNSPECIFIED | The image is corrupted or could not be read, or the failure has no more specific code. The violation's description explains it |
Upload a corrected file and create the check again.
Best Practices
Provide Complete Subject Data
Include all available name information from the document:
{
"subject": {
"givenName": "Jane",
"otherNames": "Marie",
"familyName": "Smith"
}
}
Upload High-Quality Images
- Use original images, not photocopies
- Ensure good lighting when capturing images
- Verify images are readable before uploading
- Upload both sides of two-sided documents
Document Naming
Use clear, descriptive file names with the correct extension:
passport-photo-page.jpgdriving-licence-front.jpgdriving-licence-back.jpg
Common Configurations
Passport Verification
A passport needs only the photo page:
{
"displayName": "Document verification for Jane Smith",
"clientReference": "doc-verify-12345",
"template": "checkTemplates/identity-document-verification-check-v1-0-0",
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1.IdentityDocumentVerificationCheckParams",
"subject": {
"givenName": "Jane",
"familyName": "Smith"
},
"document": {
"documentType": "PASSPORT",
"files": [
{ "side": "FRONT", "documentUploadId": "objects/3f6d2a1e-5b7c-4e8f-9a0b-1c2d3e4f5a6b" }
]
}
}
}
Troubleshooting
Common Issues
400 Bad Request - "field required"
- Ensure
displayNameandclientReferenceare included - Verify
@typefield is present inparams - Check that
document.documentTypeis set anddocument.filesincludes aFRONTfile - Include a
BACKfile for every document type exceptPASSPORT - Ensure subject name fields are provided
400 Bad Request on upload - "relatedResourceName is required in metadata"
- Include
fileName,relatedResourceNameandobjectTypein theUpload-Metadataheader - Base64-encode each metadata value
FAILED_PRECONDITION - "document validation failed"
- Read the violation
typecodes in the error details, listed in Document validation errors - Re-upload higher quality images if needed
Check stuck in ACTIVE state
- Document processing may take time for large images
- Contact support if stuck for more than 5 minutes
404 Not Found
- Verify the endpoint includes parent in URL:
/v1/{parent}/checks - Check that organization and team IDs are correct
- Ensure endpoint is
/checkSummarynot/summary
Check States
ACTIVE: The check is actively processing documentsINACTIVE: The check has completed and results are availableCANCELLED: The check has been permanently cancelledDELETED: The check has been soft-deleted
For document verification checks: Checks typically move from ACTIVE to INACTIVE within seconds to minutes once document processing completes.
Understanding Results
Get Check Summary
curl -X GET "https://api.thirdfort.dev/client/api/v1/organizations/{org_id}/teams/{team_id}/checks/{check_id}/checkSummary" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Note: The endpoint is /checkSummary (camelCase), not /summary.