Source of Funds
Verify the source of funds for a transaction. The consumer provides supporting documents via the Thirdfort mobile app.
Standalone source of funds checks are in preview and are available in the v1alpha2 API.
Overview
Use Case: Verify where funds are coming from for a specific transaction, typically required for anti-money laundering compliance.
Key Features:
- Consumer uploads supporting documents (bank statements, sale agreements, etc.)
- Document analysis and verification
- Optional proof of address document requirement
- Optional OCR-based document extraction
- Consumer completes tasks via mobile app
Subject Type: Individual
Template ID: checkTemplates/source-of-funds-check-v1-0-0
When to Use This Check
✅ Good for:
- Verifying source of funds for property transactions
- AML compliance for large transactions
- Standalone SOF verification without full identity check
- Situations where you need document evidence of funds
❌ Not suitable for:
- Full identity verification (use Identity Verification instead)
- Quick screening without documents (use Client-Only Verification instead)
- Business verification (use KYB Verification instead)
Consumer Journey
- Client creates check via API with subject and persona details
- Consumer receives notification (email/SMS with magic link)
- Consumer opens Thirdfort app via magic link
- Consumer uploads documents (bank statements, sale agreements, inheritance documents, etc.)
- Consumer provides additional context (explanations, transaction details)
- Check processes (document verification, AML screening)
- Results available via API
Typical completion time: 10-30 minutes (depends on consumer and document availability)
Prerequisites
- Thirdfort account with API access
- Client credentials (Client ID and Secret)
- Consumer contact details: Phone number (required) and optionally email for notification
- Persona: The role of the subject in the transaction (e.g., purchaser, giftor)
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/source-of-funds-check-v1-0-0 |
params.@type | string | Must be type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams |
params.subject.givenName | string | First name of the individual |
params.subject.familyName | string | Last name of the individual |
params.subject.phoneNumber | string | Phone number in E.164 format (e.g., +447700900123) |
params.persona | string | The role of the subject in the transaction. Valid values: "purchaser", "giftor", "propertyOther" |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
params.subject.email | string | - | Email address of the individual |
params.industry | string | - | The industry the check is being performed in (informational only) |
params.requireProofOfAddressDocument | bool | false | Whether to require proof of address document |
params.enableOcr | bool | false | Enable OCR-based extraction for uploaded documents (requires org-level sof-ocr feature flag) |
Complete Example
Create Check Request
curl -X POST "https://api.thirdfort.dev/client/api/v1alpha2/organizations/{org_id}/teams/{team_id}/checks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"displayName": "Source of funds for John Smith property purchase",
"clientReference": "transaction-67890",
"template": "checkTemplates/source-of-funds-check-v1-0-0",
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams",
"subject": {
"givenName": "John",
"familyName": "Smith",
"phoneNumber": "+447700900123",
"email": "john.smith@example.com"
},
"persona": "purchaser",
"industry": "property"
}
}'
Note: The endpoint includes the parent (team) in the URL path. Replace {org_id} and {team_id} with your actual organization and team IDs.
Response
{
"name": "organizations/NT6bqXp6k47SbagGAUHHG7/teams/gZzg3caveKLhe3VXjRiyXL/checks/eaa99a49-7c7c-43e0-a929-ec2dddec8a85",
"displayName": "Source of funds for John Smith property purchase",
"clientReference": "transaction-67890",
"state": "ACTIVE",
"createTime": "2026-03-06T14:06:59.758655Z",
"updateTime": null,
"template": "checkTemplates/source-of-funds-check-v1-0-0",
"params": { ... },
"relatedSubjects": [ ... ],
"creator": "partners/thirdfort/integrations/4",
...
}
Key Response Fields:
name- Resource name of the check (use for subsequent API calls)state- Current check state (see Check States below)
Summary Response
{
"name": "organizations/.../teams/.../checks/.../checkSummary",
"createTime": "2026-03-06T14:07:00.537001Z",
"payload": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckSummary",
"overallRecommendation": {
"recommendation": "CLEAR",
"description": "No concerning issues found"
},
"sourceOfFundsCheckResult": { ... },
"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
Report URLs are available at two levels: on the top-level CheckSummary resource (shared across all check types) and within the SOF-specific payload. Both contain the same URLs.
Top-level fields (on CheckSummary):
| Field | Description |
|---|---|
reportUrl | Download URL for the full PDF report |
summaryReportUrl | Download URL for the summary PDF report |
sourceFindings | Array of finding resource names that contributed to this summary |
Payload fields (SOF-specific, inside payload):
| Field | Description |
|---|---|
payload.overallRecommendation | Overall check recommendation object with recommendation and description |
payload.sourceOfFundsCheckResult | Source of funds check results |
payload.providedSubjectData | Summary of the subject data provided during the check (given name, other names, family name, date of birth) |
payload.pdfReportUrl | Download URL for the full PDF report |
payload.summaryPdfReportUrl | Download URL for the summary PDF report |
payload.addressVerificationCheckResult | Address verification results (only populated when requireProofOfAddressDocument is true) |
Recommendation Values
CLEAR: No concerning issues found - proceed with confidenceCONSIDER: 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 sof-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 sof-summary.pdf
Note:
- PDF downloads require the same OAuth 2.0 access token used for API calls
- Use the URLs from either the top-level
reportUrl/summaryReportUrlfields or the payload'spdfReportUrl/summaryPdfReportUrlfields — both contain the same URLs - URLs include
/objects/in the path
Common Configurations
Basic Source of Funds
Minimal configuration for SOF verification:
{
"displayName": "Source of funds for John Smith",
"clientReference": "transaction-67890",
"template": "checkTemplates/source-of-funds-check-v1-0-0",
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams",
"subject": {
"givenName": "John",
"familyName": "Smith",
"phoneNumber": "+447700900123"
},
"persona": "purchaser"
}
}
With Proof of Address
Require the consumer to provide a proof of address document:
{
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams",
"subject": { ... },
"persona": "purchaser",
"requireProofOfAddressDocument": true
}
}
With OCR Extraction
Enable OCR-based extraction for uploaded documents (requires the sof-ocr feature flag on the organization):
{
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams",
"subject": { ... },
"persona": "purchaser",
"enableOcr": true
}
}
Best Practices
Provide Clear Display Names
Help identify checks easily by including relevant context in the display name:
{
"displayName": "Source of funds for John Smith - property sale at 123 High Street"
}
Consumer Notifications
phoneNumberis always required (E.164 format)- Optionally provide
emailfor additional notification - SMS notifications include a link to download the app
- Consumers can upload documents from any device
Document Requirements
The consumer will be prompted to upload:
- Bank statements showing source of funds
- Sale agreements (if funds from property sale)
- Inheritance documents (if inherited funds)
- Gift letters (if gifted funds)
- Other supporting evidence
Monitoring Check Progress
Source of funds checks require consumer interaction. Monitor progress using webhooks or polling.
Polling (Simple Approach)
Poll the check status periodically:
# Check every 30 seconds
while true; do
curl -X GET "https://api.thirdfort.dev/client/api/v1alpha2/organizations/{org_id}/teams/{team_id}/checks/{check_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
sleep 30
done
Webhooks (Recommended)
Configure webhooks to receive real-time notifications when check state changes. Contact api@thirdfort.com to set up webhooks.
Troubleshooting
Common Issues
Consumer didn't receive notification
- Verify email/phone number is correct
- Check spam folder (for email)
- Resend notification via API (if supported)
Check stuck in ACTIVE state
- Consumer may not have uploaded all required documents
- Check consumer's progress via mobile app
- Consider cancelling and creating new check
400 Bad Request - "field required"
- Ensure
displayNameandclientReferenceare included - Verify
@typefield is present inparams - Check that
phoneNumberis provided in E.164 format - Ensure
personais provided with a valid value
404 Not Found
- Verify the endpoint includes parent in URL:
/v1alpha2/{parent}/checks - Check that organization and team IDs are correct
- Ensure endpoint is
/checkSummarynot/summary
ACTIVE: The check is actively processing or waiting for consumer to upload documentsINACTIVE: The check has completed and results are availableCANCELLED: The check has been permanently cancelledDELETED: The check has been soft-deleted
For source of funds checks: Checks remain in ACTIVE state until the consumer uploads all required documents and processing finishes.
Understanding Results
Get Check Summary
curl -X GET "https://api.thirdfort.dev/client/api/v1alpha2/organizations/{org_id}/teams/{team_id}/checks/{check_id}/checkSummary" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Note: The endpoint is /checkSummary (camelCase), not /summary.