Skip to main content

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:


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​

ParameterTypeDescription
displayNamestringHuman-readable name for the check
clientReferencestringYour own reference ID for tracking
templatestringMust be checkTemplates/identity-document-verification-check-v1-0-0
params.@typestringMust be type.googleapis.com/thirdfort.client.checks.type.v1.IdentityDocumentVerificationCheckParams
params.subject.givenNamestringFirst name from the document
params.subject.familyNamestringLast name from the document
params.document.documentTypeenumOne of PASSPORT, DRIVING_LICENCE, NATIONAL_IDENTITY_CARD, RESIDENCE_PERMIT, OTHER
params.document.filesarrayThe 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​

ParameterTypeDefaultDescription
params.subject.otherNamesstring-Middle names from the document
params.relationshipTypestring-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.

EnvironmentUpload endpoint
Nonproductionhttps://files.thirdfort.dev/client/uploads
Productionhttps://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 keyValue
fileNameThe file name, including its extension. The extension sets the file type, so use .jpg, .jpeg, .png or .pdf
relatedResourceNameThe 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
objectTypeIDV_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​

FieldDescription
payload.overallRecommendationOverall check recommendation object with recommendation and description
payload.identityDocumentVerificationCheckResultDocument verification results, with a recommendation and the sourceFindings that produced it
payload.providedSubjectDataEcho of the subject data you provided
payload.pdfReportUrlDownload link for the full PDF report
payload.summaryPdfReportUrlDownload link for the summary PDF report
reportUrlDownload link for full PDF report (top-level field)
summaryReportUrlDownload link for summary PDF report (top-level field)
sourceFindingsArray 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 them
  • CONSIDER: Anomalies detected that may be explainable - review findings
  • FAIL: 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 reportUrl and summaryReportUrl fields directly
  • URLs include /objects/ in the path

Document Requirements​

Supported Document Types​

documentTypeFiles required
PASSPORTFRONT (photo page)
DRIVING_LICENCEFRONT and BACK
NATIONAL_IDENTITY_CARDFRONT and BACK
RESIDENCE_PERMITFRONT and BACK
OTHERFRONT 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:

CodeMeaning
INVALID_MIME_TYPEThe file is not JPEG, PNG or PDF
FILE_TOO_SMALLThe file is smaller than 32 KB
FILE_TOO_LARGEThe file is larger than 10 MB
IMAGE_RESOLUTION_TOO_HIGHThe image is larger than 64 megapixels
MISSING_DOCUMENT_DATAThe file is empty
CUT_OFFPart of the document is cut off
BLURThe document is blurred
DOCUMENT_NOT_DETECTEDNo document was found in the image
UNSPECIFIEDThe 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.jpg
  • driving-licence-front.jpg
  • driving-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 displayName and clientReference are included
  • Verify @type field is present in params
  • Check that document.documentType is set and document.files includes a FRONT file
  • Include a BACK file for every document type except PASSPORT
  • Ensure subject name fields are provided

400 Bad Request on upload - "relatedResourceName is required in metadata"

  • Include fileName, relatedResourceName and objectType in the Upload-Metadata header
  • Base64-encode each metadata value

FAILED_PRECONDITION - "document validation failed"

  • Read the violation type codes 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 /checkSummary not /summary

Check States​

  • ACTIVE: The check is actively processing documents
  • INACTIVE: The check has completed and results are available
  • CANCELLED: The check has been permanently cancelled
  • DELETED: 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.