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
- AML screening (sanctions/PEP checks)
- Optional ongoing monitoring
- 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 transaction 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: Email or phone number for notification
- Transaction details: Amount, currency, purpose
- Package support: Ongoing monitoring requires package support (if enabled)
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.email OR params.subject.phoneNumber | string | Contact method for consumer notification |
params.transactionAmount | Money | Transaction amount (structured object with currencyCode and units) |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
params.subject.otherNames | string | - | Middle names |
params.subject.dateOfBirth | Date | - | Date of birth (structured object: {year, month, day}) |
params.transactionPurpose | string | - | Purpose of the transaction (e.g., "Property purchase") |
params.enableOngoingMonitoring | bool | false | Continuous AML screening monitoring |
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",
"email": "john.smith@example.com",
"dateOfBirth": {
"year": 1985,
"month": 6,
"day": 15
}
},
"transactionAmount": {
"currencyCode": "GBP",
"units": 500000
},
"transactionPurpose": "Property purchase",
"enableOngoingMonitoring": true
}
}'
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",
"ongoingMonitoring": {
"enabled": true,
"activeUntil": null
},
...
}
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"
},
"documentVerificationResult": { ... },
"screeningCheckResult": { ... },
"providedSubjectData": { ... },
"transactionDetails": { ... }
},
"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.documentVerificationResult | Document verification results - always included |
payload.screeningCheckResult | AML screening results (sanctions/PEP) - always included |
payload.providedSubjectData | Echo of the subject data you provided |
payload.transactionDetails | Transaction amount and purpose |
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 |
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 complete URLs from
reportUrlandsummaryReportUrlfields directly - 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",
"email": "john.smith@example.com"
},
"transactionAmount": {
"currencyCode": "GBP",
"units": 500000
}
}
}
With Transaction Purpose
Provide context about the transaction:
{
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams",
"subject": { ... },
"transactionAmount": {
"currencyCode": "GBP",
"units": 500000
},
"transactionPurpose": "Property purchase at 123 High Street, London"
}
}
With Ongoing Monitoring
Enable continuous sanctions monitoring:
{
"params": {
"@type": "type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams",
"subject": { ... },
"transactionAmount": { ... },
"enableOngoingMonitoring": true
}
}
Transaction Amount Format
The transactionAmount field uses the Money type:
{
"transactionAmount": {
"currencyCode": "GBP",
"units": 500000
}
}
Fields:
currencyCode- ISO 4217 currency code (e.g., "GBP", "USD", "EUR")units- Amount in the smallest currency unit (e.g., pence for GBP, cents for USD)
Examples:
- £500,000 =
{"currencyCode": "GBP", "units": 50000000}(500,000 × 100 pence) - $250,000 =
{"currencyCode": "USD", "units": 25000000}(250,000 × 100 cents) - €100,000 =
{"currencyCode": "EUR", "units": 10000000}(100,000 × 100 cents)
Best Practices
Provide Transaction Context
Help the consumer by providing clear transaction details:
{
"displayName": "Source of funds for property purchase at 123 High Street",
"transactionAmount": {
"currencyCode": "GBP",
"units": 50000000
},
"transactionPurpose": "Property purchase at 123 High Street, London SW1A 1AA"
}
Consumer Notifications
- Provide either
emailorphoneNumber(or both) - Email notifications include a magic link to open the app
- 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
transactionAmountincludes bothcurrencyCodeandunits - Ensure either
emailorphoneNumberis provided
400 Bad Request - "invalid amount"
- Verify
unitsis in smallest currency unit (pence/cents, not pounds/dollars) - Check
currencyCodeis valid ISO 4217 code
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.