Onboard individual customers to enable cross-border payments and payouts through Fin.com’s platform. This guide walks you through creating individual customer profiles, uploading verification documents, and managing the compliance workflow using the V2 API.Prerequisites
Before you begin, ensure you have:Onboarding Steps
| Step | Endpoint | Description |
|---|
| 1. Fetch Catalogue Data | GET /v1/occupations, GET /v1/purposes?type=INDIVIDUAL, GET /v1/source-of-funds?type=INDIVIDUAL | Retrieve valid IDs for occupations, purposes, and fund sources |
| 2. Create Customer | POST /v2/customers/individual | Submit personal details, address, and financial profile |
| 3. Upload Documents | POST /v1/customers/upload | Upload identity, selfie, and address proof files |
| 4. Attach Documents | Link uploaded documents to the customer (processed asynchronously) | |
| 5. Monitor Status | Webhooks: customer.status | Track verification progress (INCOMPLETE → REVIEWING → APPROVED) |
Request Body Structure
Verification Type (Required)
Verification type determines how customer identity is validated. STANDARD uses traditional document verification. On RELIANCE, Fin.com relies on your KYC. Please contact our compliance team to know more.
{
"verification_type": "STANDARD"
}
RELIANCE verification must be explicitly enabled for your client. If not available, you’ll receive a 423 error with the message: "RELIANCE is not available for your client"
Personal details exactly as shown on identity documents. All fields must use only English (Latin) characters. If any field contains non-ASCII characters, provide a transliterated value in the corresponding _en field.
Fields:| Field | Type | Required | Description | Example |
|---|
first_name | string | Yes | Legal first name as shown on ID | "María" |
first_name_en | string | Conditional | English transliteration. Required if first_name contains non-ASCII characters. | "Maria" |
middle_name | string | No | Middle name | "Elena" |
middle_name_en | string | Conditional | English transliteration. Required if middle_name contains non-ASCII characters. | "Elena" |
last_name | string | Yes | Legal last name as shown on ID | "García" |
last_name_en | string | Conditional | English transliteration. Required if last_name contains non-ASCII characters. | "Garcia" |
dob | string (date) | Yes | Date of birth in YYYY-MM-DD format. Age must be between 18 and 120. | "1990-04-15" |
email | string (email) | Yes | Personal email address - must be all lowercase | "maria.garcia@example.com" |
phone | string | Yes | Phone number in E.164 format | "+14155552671" |
country_of_residence | string | Yes | ISO Alpha-3 country code where person resides | "USA" |
primary_nationality | string | Yes | ISO Alpha-3 country code of primary citizenship | "USA" |
secondary_nationality | string | No | ISO Alpha-3 country code of secondary citizenship | "MEX" |
gender | string | No | MALE or FEMALE | "FEMALE" |
tax_info | array | Yes | Tax identification documents (see below) | — |
Email must be all lowercase or validation will fail. Convert to lowercase before sending: maria.garcia@example.com ✓ not Maria.Garcia@Example.com ✗
Tax Info Array
Each entry in tax_info must have a unique document_id.| Field | Type | Required | Description | Example |
|---|
country_code | string | Yes | ISO Alpha-3 country code | "USA" |
document_type | string | Yes | Tax document type (e.g., SSN, TIN) | "SSN" |
document_id | string | Yes | Tax identification number | "123-45-6789" |
TIN Format by Country:
- USA: Social Security Number in format
xxx-xx-xxxx (e.g., 123-45-6789)
- Other countries: Must use the country’s official Tax Identification Number format
V2 Change: tax_info replaces tin. V1 used a single tin string field. V2 uses a tax_info array, which supports multiple tax documents across different countries.
Example:{
"basic_info": {
"first_name": "Maria",
"middle_name": "Elena",
"last_name": "Garcia",
"dob": "1990-04-15",
"email": "maria.garcia@example.com",
"phone": "+14155552671",
"country_of_residence": "USA",
"primary_nationality": "USA",
"secondary_nationality": "MEX",
"gender": "FEMALE",
"tax_info": [
{
"country_code": "USA",
"document_type": "SSN",
"document_id": "123-45-6789"
}
]
}
}
Address (Required)
Current residential address of the customer. The country field must match basic_info.country_of_residence.
Fields:| Field | Type | Required | Description | Example |
|---|
street_line_1 | string | Yes | Primary street address | "123 Market Street" |
street_line_1_en | string | Conditional | English transliteration. Required if street_line_1 contains non-ASCII characters. | "123 Market Street" |
street_line_2 | string | No | Apartment, suite, unit, etc. | "Apt 4B" |
street_line_2_en | string | Conditional | English transliteration. Required if street_line_2 contains non-ASCII characters. | "Apt 4B" |
city | string | Yes | City name | "San Francisco" |
subdivision_code | string | Yes | ISO 3166-2 subdivision code | "US-CA" |
postal_code | string | Yes | Postal or ZIP code | "94103" |
country | string | Yes | ISO Alpha-3 country code. Must match country_of_residence. | "USA" |
Subdivision Code Format: Use ISO 3166-2 codes from the catalogue API. For example, use US-CA instead of CA for California, or GB-ENG instead of England. Fetch valid codes from /v1/countries//subdivisions. V2 Change: Address fields. V1 used a single street field. V2 splits this into street_line_1 and street_line_2. The state field has been renamed to subdivision_code.
Example:{
"address": {
"street_line_1": "123 Market Street",
"street_line_2": "Apt 4B",
"city": "San Francisco",
"subdivision_code": "US-CA",
"postal_code": "94103",
"country": "USA"
}
}
Financial Profile (Required)
Describes employment status, occupation, transaction purpose, volume, and fund sources. Use catalogue endpoints to fetch valid IDs.
Fields:| Field | Type | Required | Description | How to Get Value |
|---|
employment_status | string | Yes | One of: EMPLOYED, SELF_EMPLOYED, RETIRED, STUDENT, UNEMPLOYED | Select from enum |
occupation_id | integer | Yes | Customer’s occupation | GET /v1/occupations |
purpose_id | integer | Yes | Purpose of using the service | GET /v1/purposes?type=INDIVIDUAL |
purpose_remarks | string | No | Free-text description of the purpose | User input |
source_of_fund_ids | integer[] | Yes | Source(s) of funds (supports multiple) | GET /v1/source-of-funds?type=INDIVIDUAL |
source_of_funds_description | string | No | Free-text description of fund sources | User input |
monthly_volume_usd | integer | Yes | Expected monthly transaction volume in USD (not cents). Accepts 0. | User estimate: 5000 |
When fetching catalogue data for individual customers, use the ?type=INDIVIDUAL query parameter to get the correct options for purpose_id and source_of_fund_ids.
V2 Change: Multiple fund sources. V1 accepted a single source_of_fund_id integer. V2 uses source_of_fund_ids as an array, allowing multiple sources. V2 also adds employment_status (required), purpose_remarks, and source_of_funds_description.
Example:{
"financial_profile": {
"employment_status": "EMPLOYED",
"occupation_id": 42,
"purpose_id": 3,
"purpose_remarks": "Personal remittances to family",
"source_of_fund_ids": [1, 5],
"source_of_funds_description": "Monthly salary from employment",
"monthly_volume_usd": 5000
}
}
Custom key-value pairs for internal tracking:{
"meta_data": {
"reference": "client-ref-abc-001"
}
}
Document Upload & Attachment
After creating the individual customer, you must upload and attach verification documents.Step 1: Upload Documents
Upload files using multipart/form-data:curl --request POST \
--url https://sandbox.api.fin.com/v1/customers/upload \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'Content-Type: multipart/form-data' \
--form 'customer_id=55bd6b4e-c20a-4cc8-9535-91d5557a67d9' \
--form 'file1=@/path/to/selfie.jpg' \
--form 'file2=@/path/to/license_front.pdf' \
--form 'file3=@/path/to/license_back.pdf' \
--form 'file4=@/path/to/bank_statement.pdf'
Allowed file types: PDF, JPG, JPEG, PNGResponse:{
"data": {
"files": [
{"file1": "/AbAcQ4hn_0652746727637.pdf"},
{"file2": "/AbAcQ4hn_0652746727638.pdf"},
{"file3": "/XyZ123mn_0652746727639.pdf"},
{"file4": "/PoAdef45_0652746727640.pdf"}
]
}
}
Save these URIs - you’ll use them in the attachment request.
Step 2: Attach Documents
In V2, the customer_id moves to the URL path. The request body uses identifying_documents and address_documents arrays instead of V1’s proof_of_identity and proof_of_address objects.
- The customer must be in
INCOMPLETE or ACTION_REQUIRED status. Only one attach request can be in flight per customer. A second concurrent request returns 409.
- The
tos_policies_value should be parsed from the tos_policies_url query parameter returned when creating the customer. Providing this value signifies that the customer was shown the terms and accepted them.
curl --request POST \
--url https://sandbox.api.fin.com/v2/customers/55bd6b4e-c20a-4cc8-9535-91d5557a67d9/individual/attach \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"identifying_documents": [
{
"type": "SELFIE",
"files": [
{"uri": "/AbAcQ4hn_0652746727637.pdf"}
]
},
{
"type": "DRIVERS_LICENSE",
"number": "DL987654321",
"country": "USA",
"state": "US-CA",
"issue_date": "2019-06-01",
"expiry_date": "2029-06-01",
"files": [
{"side": "FRONT", "uri": "/AbAcQ4hn_0652746727638.pdf"},
{"side": "BACK", "uri": "/XyZ123mn_0652746727639.pdf"}
]
}
],
"address_documents": [
{
"type": "BANK_STATEMENT",
"country": "USA",
"files": [
{"uri": "/PoAdef45_0652746727640.pdf"}
]
}
],
"tos_policies_value": "e9414388-fbdf-4407-b5c2-bc39eae3645b"
}'
Response (200 - queued for async processing):{
"data": {
"customer_id": "55bd6b4e-c20a-4cc8-9535-91d5557a67d9"
},
"meta": null
}
V2 document attachment is asynchronous. A 200 response means the request is validated and queued, not that processing is complete. Listen for customer.status webhooks to track progress.
Identity Document Types & Side Requirements
| Type | Files | Sides Required | state field |
|---|
PASSPORT | 1 | Optional | Forbidden |
NATIONAL_ID | 2 | One FRONT + one BACK | Forbidden |
DRIVERS_LICENSE | 2 | One FRONT + one BACK | Required if country is USA, optional otherwise |
RESIDENCE_PERMIT | 2 | One FRONT + one BACK | Forbidden |
SELFIE | 1 | Optional | N/A |
At most one non-SELFIE identity document may be included per request. A SELFIE entry may be required depending on your client configuration. When required, include exactly one SELFIE entry with at least one file.
Address Proof Types
| Type | Description |
|---|
UTILITY_BILL | Recent utility bill (gas, electric, water) |
BANK_STATEMENT | Bank statement (within the last 3 months) |
GOVERNMENT_LETTER | Official government correspondence |
Exactly one address_documents entry is required. The country on the address document must match the customer’s country_of_residence.Proof of Address Requirements:
- Document must show the customer’s full name and complete address
- Address must match the
address provided in the customer creation request
- Document should be issued within the last 90 days (for utility bills, bank statements, and government letters)
Key Rules
- File URIs must be unique across the entire reques and must belong to this customer.
expiry_date is required for all identity document types except SELFIE and must be in the future.
Customer Status & Webhooks
After document submission, customers go through a verification workflow:Status Lifecycle:| Status | Description |
|---|
INCOMPLETE | Customer created but documents not yet attached |
REVIEWING | Documents submitted and under compliance review |
APPROVED | Verification complete, customer can transact |
ACTION_REQUIRED | Additional documents or corrections needed (re-attach allowed) |
ON_HOLD | Additional information required via RFI |
REJECTED | Verification failed, see rejection reason |
Webhook Events:
customer.created - Fired when a customer is created
customer.status - Fired when status changes
Subscribe to webhooks to automate your onboarding flow. See Verifying Webhooks for setup.
Error Response Examples
Email validation error (not lowercase):{
"message": "Validation failed",
"errors": {
"basic_info.email": ["Email must be all lowercase"]
}
}
RELIANCE not enabled:{
"message": "RELIANCE is not available for your client"
}
Address country mismatch:{
"message": "Validation failed",
"errors": {
"address.country": ["Must match basic_info.country_of_residence"]
}
}
Concurrent attach conflict (409):{
"error": {
"code": "conflict",
"message": "An attach request is already in progress for this customer"
}
}
Customer not eligible for attach (403):{
"error": {
"code": "forbidden",
"message": "Customer is not eligible for this operation"
}
}
What’s Next?
You’ve successfully created an individual customer using V2. Here’s what to do next:1. Monitor Verification Status
Listen for webhook events to track verification progress:
- Subscribe to
customer.created and customer.status webhooks
- Handle status transitions:
INCOMPLETE → REVIEWING → APPROVED
- For
ACTION_REQUIRED statuses, re-submit corrected documents via the attach endpoint
- For
ON_HOLD statuses, respond to RFIs (Requests for Information) via email or Slack with additional documents
- See Webhook Verification for implementation details
2. Test Edge Cases
Validate your integration handles common errors:
- ✓ Email with uppercase characters
- ✓
address.country not matching country_of_residence
- ✓ Non-ASCII characters without
_en transliteration fields
- ✓ Missing required fields
- ✓ RELIANCE verification when not enabled
- ✓ Concurrent attach requests (409)
- ✓ Expired identity documents
- ✓ Duplicate file URIs across documents
3. Production Checklist
Before going live, ensure you have:
- Implemented webhook handling for status updates
- Added proper error handling for all failure scenarios (400, 401, 403, 409, 422)
- Client-side validation for email lowercase and tax document format
- Fetched and cached catalogue data (occupations, purposes, source-of-funds)
- Implemented document upload UI/flow including selfie capture
- Set up monitoring for failed verifications
- Tested the complete workflow end-to-end
4. Create Beneficiaries
Once your individual customer is approved, you can create beneficiaries for payouts:
V1 to V2 Migration Summary
| Area | V1 | V2 |
|---|
| Create endpoint | POST /v1/customers/individual | POST /v2/customers/individual |
verification_type | Optional (defaults to STANDARD) | Required |
| Name fields | first_name, last_name | Adds middle_name + _en transliteration fields |
| Nationality | nationality | primary_nationality + optional secondary_nationality |
| Gender | Not supported | Optional gender field |
| Tax ID | Single tin string | tax_info array with country_code, document_type, document_id |
| Address street | Single street field | street_line_1 + street_line_2 + _en fields |
| Address state | state | subdivision_code |
| Address country | No validation against residence | Must match country_of_residence |
| Employment | Not supported | Required employment_status enum |
| Source of funds | Single source_of_fund_id | Array source_of_fund_ids + source_of_funds_description |
| Purpose | purpose_id only | purpose_id + optional purpose_remarks |
| Attach endpoint | POST /v1/customers/individual/attach | POST /v2/customers/{customer_id}/individual/attach |
| Attach body | customer_id in body | customer_id in URL path |
| Identity docs | proof_of_identity object | identifying_documents array |
| Address docs | proof_of_address object | address_documents array (max 1 entry) |
| Selfie | Not supported | SELFIE type in identifying_documents |
| Residence permit | Not supported as ID type | RESIDENCE_PERMIT type supported |
| Address proof types | 8 types | 3 types: UTILITY_BILL, BANK_STATEMENT, GOVERNMENT_LETTER |
tos_policies_value | Required in attach body | Not required in attach body |
| Processing | Synchronous | Asynchronous (200 = queued) |
| Concurrency | No guard | 409 if attach already in flight |
Common Pitfalls & Solutions
| Pitfall | Solution |
|---|
| Email validation fails | Ensure email is all lowercase before sending: maria.garcia@example.com ✓ not Maria.Garcia@Example.com ✗ |
| Address country mismatch | address.country must exactly match basic_info.country_of_residence. |
| RELIANCE 423 error | RELIANCE verification must be enabled for your client. Contact support or use STANDARD. |
Non-ASCII without _en field | If name or address contains non-Latin characters, provide the transliterated value in the _en counterpart field. |
| Subdivision code validation fails | |
| Phone format rejected | Use E.164 format with country code: +14155552671, not (415) 555-2671. |
| Monthly volume rejected | Provide amount in USD as integer (not cents): 5000 for $5,000, not 500000. |
| Missing document sides | For NATIONAL_ID, DRIVERS_LICENSE, and RESIDENCE_PERMIT, include both FRONT and BACK files. |
| Concurrent attach fails (409) | Only one attach per customer at a time. Wait for the first to complete before retrying. |
| Expired identity document | expiry_date must be in the future. Ensure documents are not expired before submitting. |
| Selfie missing | If your client requires selfie, include exactly one SELFIE entry in identifying_documents. |
| Duplicate file URIs | File URIs must be unique across the request (SELFIE excluded). Don’t reuse the same URI for identity and address docs. |
Onboard individual customers to enable cross-border payments and payouts through Fin.com’s platform. This guide walks you through creating individual customer profiles, uploading verification documents, and managing the compliance workflow.Prerequisites
Before you begin, ensure you have:Onboarding Steps
| Step | Endpoint | Description |
|---|
| 1. Fetch Catalogue Data | GET /v1/occupations, GET /v1/purposes?type=INDIVIDUAL, GET /v1/source-of-funds?type=INDIVIDUAL | Retrieve valid IDs for occupations, purposes, and fund sources |
| 2. Create Customer | POST /v1/customers/individual | Submit personal details, address, and financial profile |
| 3. Upload Documents | POST /v1/customers/upload | Upload identity and address proof files |
| 4. Attach Documents | POST /v1/customers/individual/attach | Link uploaded documents to customer with TOS acceptance |
| 5. Monitor Status | Webhooks: customer.status | Track verification progress (INCOMPLETE → REVIEWING → APPROVED) |
Request Body Structure
Verification Type (Optional)
Verification type determines how customer identity is validated. STANDARD uses traditional document verification (default). RELIANCE leverages third-party KYC data when enabled for your client.
{
"verification_type": "STANDARD"
}
The verification_type field is optional and defaults to STANDARD if omitted.RELIANCE verification must be explicitly enabled for your client. If not available, you’ll receive a 423 error with message: "RELIANCE is not available for your client"
Personal details exactly as shown on identity documents. All fields must use only English (Latin) characters.
Fields:| Field | Type | Description | Example |
|---|
first_name | string | Legal first name as shown on ID | "John" |
last_name | string | Legal last name as shown on ID | "Doe" |
dob | string (date) | Date of birth in YYYY-MM-DD format | "1990-01-15" |
email | string (email) | Personal email address - must be all lowercase | "john.doe@example.com" |
phone | string | Phone number in E.164 format | "+14155552671" |
country_of_residence | string | ISO Alpha-3 country code where person resides | "USA" |
nationality | string | ISO Alpha-3 country code of citizenship | "USA" |
tin | string | Tax Identification Number | "123-45-6789" |
Email must be all lowercase or validation will fail. Convert to lowercase before sending: john.doe@example.com ✓ not John.Doe@Example.com ✗
TIN Format by Country:
- USA: Social Security Number in format
xxx-xx-xxxx (e.g., 123-45-6789)
- Other countries: Must use the country’s official Tax Identification Number format
Example:{
"basic_info": {
"first_name": "John",
"last_name": "Doe",
"dob": "1990-01-15",
"email": "john.doe@example.com",
"phone": "+14155552671",
"country_of_residence": "USA",
"nationality": "USA",
"tin": "123-45-6789"
}
}
Address (Required)
Current residential address of the customer. This must match the address on proof of address documents.
Fields:| Field | Type | Description | Example |
|---|
street | string | Full street address including apartment/unit number | "123 Main Street Apt 4B" |
city | string | City name | "San Francisco" |
state | string | "US-CA" | |
postal_code | string | Postal or ZIP code | "94103" |
country | string | ISO Alpha-3 country code | "USA" |
State Code Format: Use subdivision codes from the catalogue API, not abbreviations. For example, use US-CA instead of CA for California, or GB-ENG instead of England.
Example:{
"address": {
"street": "123 Main Street Apt 4B",
"city": "San Francisco",
"state": "US-CA",
"postal_code": "94103",
"country": "USA"
}
}
Financial Profile (Required)
Describes occupation, transaction purpose, volume, and fund sources. Use catalogue endpoints to fetch valid IDs.
Fields:| Field | Type | Description | How to Get Value |
|---|
occupation_id | integer | Customer’s occupation | GET /v1/occupations |
source_of_fund_id | integer | Source of funds | GET /v1/source-of-funds?type=INDIVIDUAL |
purpose_id | integer | Purpose of using the service | GET /v1/purposes?type=INDIVIDUAL |
monthly_volume_usd | integer | Expected monthly transaction volume in USD (not cents). Accepts 0. | User estimate: 5000 |
When fetching catalogue data for individual customers, use the ?type=INDIVIDUAL query parameter to get the correct options for source_of_fund_id and purpose_id.
Example:{
"financial_profile": {
"occupation_id": 1,
"source_of_fund_id": 1,
"purpose_id": 1,
"monthly_volume_usd": 5000
}
}
In this example: occupation_id: 1 = Software Engineer, source_of_fund_id: 1 = Employment income, purpose_id: 1 = Personal remittance, monthly_volume_usd: 5000 = $5,000 USD per month.Custom key-value pairs for internal tracking:{
"meta_data": {
"customer_reference": "REF-20250123-JOHN",
"internal_notes": "Premium tier customer",
"referral_code": "FRIEND2025"
}
}
Document Upload & Attachment
After creating the individual customer, you must upload and attach verification documents.Step 1: Upload Documents
Upload files using multipart/form-data:curl --request POST \
--url https://sandbox.api.fin.com/v1/customers/upload \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'Content-Type: multipart/form-data' \
--form 'customer_id=55bd6b4e-c20a-4cc8-9535-91d5557a67d9' \
--form 'file1=@/path/to/passport_front.pdf' \
--form 'file2=@/path/to/utility_bill.pdf'
Allowed file types: PDF, JPG, JPEG, PNGResponse:{
"data": {
"files": [
{"file1": "/AbAcQ4hn_0652746727637.pdf"},
{"file2": "/XyZ123mn_0652746727638.pdf"}
]
}
}
Save these URIs - you’ll use them in the attachment request.Step 2: Attach Documents
Link identity and address proof documents to the customer:curl --request POST \
--url https://sandbox.api.fin.com/v1/customers/individual/attach \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"customer_id": "55bd6b4e-c20a-4cc8-9535-91d5557a67d9",
"proof_of_identity": {
"type": "PASSPORT",
"number": "A12345678",
"country": "USA",
"issue_date": "2020-01-15",
"expiry_date": "2030-01-15",
"files": [
{"uri": "/AbAcQ4hn_0652746727637.pdf"}
]
},
"proof_of_address": {
"type": "UTILITY_BILL",
"country": "USA",
"files": [
{"uri": "/XyZ123mn_0652746727638.pdf"}
]
},
"tos_policies_value": "e9414388-fbdf-4407-b5c2-bc39eae3645b"
}'
The tos_policies_value should be parsed from the tos_policies_url query parameter returned when creating the customer. Providing this value signifies that the customer was shown the terms and accepted them.
For NATIONAL_ID and DRIVERS_LICENSE, you must provide both FRONT and BACK images using the side field. For PASSPORT, the side field is optional.
Example with National ID (requires front and back):{
"proof_of_identity": {
"type": "NATIONAL_ID",
"number": "A12345678",
"country": "USA",
"issue_date": "2020-01-15",
"expiry_date": "2030-01-15",
"files": [
{"side": "FRONT", "uri": "/id_front_0652746727640.pdf"},
{"side": "BACK", "uri": "/id_back_0652746727641.pdf"}
]
}
}
Identity Document Types:| Type | Description | Side Required |
|---|
PASSPORT | Passport | No (optional) |
NATIONAL_ID | National ID card | Yes (FRONT + BACK) |
DRIVERS_LICENSE | Driver’s license | Yes (FRONT + BACK) |
Address Proof Types:| Type | Description |
|---|
UTILITY_BILL | Recent utility bill (gas, electric, water) |
BANK_STATEMENT | Bank statement (within last 3 months) |
GOVERNMENT_LETTER | Official government correspondence |
RESIDENCE_PERMIT | Residence permit document |
PASSPORT | Passport showing address |
NATIONAL_ID | National ID showing address |
DRIVERS_LICENSE | Driver’s license showing address |
COMPANY_DOC | Company document showing address |
Proof of Address Requirements:
- Document must show the customer’s full name and complete address
- Address must match the
address provided in the customer creation request
- Document should be issued within the last 90 days (for utility bills, bank statements, and government letters)
Customer Status & Webhooks
After document submission, customers go through a verification workflow:Status Lifecycle:INCOMPLETE → REVIEWING → APPROVED
↓
ON_HOLD / REJECTED
| Status | Description |
|---|
INCOMPLETE | Customer created but documents not yet attached |
REVIEWING | Documents submitted and under compliance review |
APPROVED | Verification complete, customer can transact |
ON_HOLD | Additional information or documents required |
REJECTED | Verification failed, see rejection reason |
Webhook Events:
customer.created - Fired when customer is created
customer.status - Fired when status changes
Subscribe to webhooks to automate your onboarding flow. See Verifying Webhooks for setup.Error Response Examples
Email validation error (not lowercase):{
"message": "Validation failed",
"errors": {
"basic_info.email": ["Email must be all lowercase"]
}
}
RELIANCE not enabled:{
"message": "RELIANCE is not available for your client"
}
TIN format validation (USA):{
"message": "Validation failed",
"errors": {
"basic_info.tin": ["TIN must be in SSN format (xxx-xx-xxxx) for USA customers"]
}
}
Missing required field:{
"message": "Validation failed",
"errors": {
"financial_profile.occupation_id": ["occupation_id is required"]
}
}
What’s Next?
You’ve successfully created an individual customer. Here’s what to do next:1. Monitor Verification Status
Listen for webhook events to track verification progress:
- Subscribe to
customer.created and customer.status webhooks
- Handle status transitions:
INCOMPLETE → REVIEWING → APPROVED
- For
ON_HOLD statuses, respond to RFIs (Requests for Information) via email or Slack with additional documents
- See Webhook Verification for implementation details
2. Test Edge Cases
Validate your integration handles common errors:
- ✓ Email with uppercase characters
- ✓ TIN in wrong format for country
- ✓ Non-Latin characters in text fields
- ✓ Missing required fields
- ✓ RELIANCE verification when not enabled
- ✓ Invalid state codes
3. Production Checklist
Before going live, ensure you have:
- Implemented webhook handling for status updates
- Added proper error handling for all failure scenarios
- Client-side validation for email lowercase and TIN format
- Fetched and cached catalogue data (occupations, purposes, source-of-funds)
- Implemented document upload UI/flow
- Set up monitoring for failed verifications
- Tested the complete workflow end-to-end
4. Create Beneficiaries
Once your individual customer is approved, you can create beneficiaries for payouts:
Common Pitfalls & Solutions
| Pitfall | Solution |
|---|
| Email validation fails | Ensure email is all lowercase before sending: john.doe@example.com ✓ not John.Doe@Example.com ✗ |
| RELIANCE 423 error | RELIANCE verification must be enabled for your client. Contact support or use STANDARD verification type. |
| TIN format rejected | TIN must follow the country’s official format. For USA, use SSN format xxx-xx-xxxx. |
| Non-Latin character rejection | All text fields accept only English (Latin) characters. Transliterate or romanize names (e.g., Jose not Jose). |
| State code validation fails | |
| Phone format rejected | Use E.164 format with country code: +14155552671, not (415) 555-2671. |
| Monthly volume rejected | Provide amount in USD as integer (not cents): 5000 for $5,000, not 500000. |
| Document side missing | For NATIONAL_ID and DRIVERS_LICENSE, include side: "FRONT" and side: "BACK" in the files array. |
| Address mismatch | Ensure proof of address document shows the same address provided in the address object. |