Skip to main content

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:


Consumer Journey

  1. Client creates check via API with subject and persona details
  2. Consumer receives notification (email/SMS with magic link)
  3. Consumer opens Thirdfort app via magic link
  4. Consumer uploads documents (bank statements, sale agreements, inheritance documents, etc.)
  5. Consumer provides additional context (explanations, transaction details)
  6. Check processes (document verification, AML screening)
  7. 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

ParameterTypeDescription
displayNamestringHuman-readable name for the check
clientReferencestringYour own reference ID for tracking
templatestringMust be checkTemplates/source-of-funds-check-v1-0-0
params.@typestringMust be type.googleapis.com/thirdfort.client.checks.type.v1alpha2.SourceOfFundsCheckParams
params.subject.givenNamestringFirst name of the individual
params.subject.familyNamestringLast name of the individual
params.subject.phoneNumberstringPhone number in E.164 format (e.g., +447700900123)
params.personastringThe role of the subject in the transaction. Valid values: "purchaser", "giftor", "propertyOther"

Optional Parameters

ParameterTypeDefaultDescription
params.subject.emailstring-Email address of the individual
params.industrystring-The industry the check is being performed in (informational only)
params.requireProofOfAddressDocumentboolfalseWhether to require proof of address document
params.enableOcrboolfalseEnable 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):

FieldDescription
reportUrlDownload URL for the full PDF report
summaryReportUrlDownload URL for the summary PDF report
sourceFindingsArray of finding resource names that contributed to this summary

Payload fields (SOF-specific, inside payload):

FieldDescription
payload.overallRecommendationOverall check recommendation object with recommendation and description
payload.sourceOfFundsCheckResultSource of funds check results
payload.providedSubjectDataSummary of the subject data provided during the check (given name, other names, family name, date of birth)
payload.pdfReportUrlDownload URL for the full PDF report
payload.summaryPdfReportUrlDownload URL for the summary PDF report
payload.addressVerificationCheckResultAddress verification results (only populated when requireProofOfAddressDocument is true)

Recommendation Values

  • CLEAR: No concerning issues found - proceed with confidence
  • 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 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/summaryReportUrl fields or the payload's pdfReportUrl/summaryPdfReportUrl fields — 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

  • phoneNumber is always required (E.164 format)
  • Optionally provide email for 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

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 displayName and clientReference are included
  • Verify @type field is present in params
  • Check that phoneNumber is provided in E.164 format
  • Ensure persona is 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 /checkSummary not /summary

  • ACTIVE: The check is actively processing or waiting for consumer to upload 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 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.