Customer Onboarding via API
If you haven't already, Sign Up for Sandbox Access to get your client ID and secret to work through this Build Guide!
What is Customer Onboarding?
Customer onboarding is the process of creating and verifying customer identities on the Rail platform through our Applications API. This includes collecting required information, uploading KYC/KYB documents, and submitting applications for approval. Once approved, customers can access accounts and start transacting.
Rail supports onboarding for two customer types:
- Individual Customers - Personal accounts requiring individual KYC verification
- Corporate Customers - Business accounts requiring corporate KYB verification, beneficial owner information, and authorized user details
Core API Flow Sequence
The standard API onboarding process follows these key steps:
-
POST
/v1/applications- Create the application -
GET
/v1/applications/{application_id}- Retrieve application status to identify required documents -
POST
/v1/applications/{application_id}/documents- Upload KYC documents -
GET
/v1/applications/{application_id}- Retrieve application details again to verify completion -
POST
/v1/applications/{application_id}/submit- Submit the application for processing
Build Guide
This guide provides two scenarios:
By the end of this guide you will have:
- Authenticated your request
- Created an application
- Retrieved document IDs
- Uploaded required documents
- Submitted the application
- Monitored application status
Let's go!
Authenticating your request
Every request you make to a Rail API endpoint requires an AUTH_TOKEN. We secure our endpoints using standards based OAuth2 Client Credentials Grant and scopes.
To obtain the AUTH_TOKEN, you will need to authorize your account using your BASE_64_ENCODED_CLIENTID_AND_SECRET with the scopes you require:
curl --location --request POST 'https://auth.layer2financial.com/oauth2/ausbdqlx69rH6OjWd696/v1/token?grant_type=client_credentials&scope=applications:read+applications:write+customers:read' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cache-Control: no-cache' \
--header 'Authorization: Basic {BASE_64_ENCODED_CLIENTID_AND_SECRET}'This gives you a response object containing your AUTH_TOKEN:
{
"token_type": "Bearer",
"expires_in": 43200,
"access_token": {AUTH_TOKEN},
"scope": "applications:read applications:write customers:read"
}The scopes we'll need for this tutorial are:
-
applications:readandapplications:writeto create and manage applications -
customers:readto retrieve customer information after approval
The full list of scopes are available here.
Scenario 1: Individual Customer Onboarding
Individual customers require basic KYC information including name, address, and identity verification documents.
Step 1: Create Application
Create an application by calling the /v1/applications endpoint.
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/applications' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{
"customer_id": "INDIVIDUAL_CUSTOMER_001",
"customer_type": "INDIVIDUAL",
"profile": {
"name": {
"first_name": "Jane",
"last_name": "Doe"
},
"date_of_birth": "1990-01-15",
"tax_reference_number": "123-45-6789",
"address": {
"address_line1": "123 Main Street",
"city": "Boston",
"state": "MA",
"postal_code": "02101",
"country_code": "US"
},
"email": "jane.doe@example.com",
"phone_number": "+1234567890"
},
"default_account": {
"product_id": "DEPOSIT_BASIC",
"asset_type_id": "FIAT_TESTNET_USD"
}
}'The response contains the application_id you'll need for subsequent steps:
{
"data": {
"id": "app_123456789",
"status": "INCOMPLETE"
}
}Save this application_id - you'll need it throughout the onboarding process.
Step 2: Get Document IDs
Before uploading documents, you need to retrieve the document_ids by calling the /v1/applications/{application_id} endpoint.
Note: This is the same endpoint used to check the application status throughout the onboarding process. It provides both status information and the document IDs you need for uploads.
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_123456789' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json'The response contains the document IDs you need to upload:
{
"data": {
"id": "app_123456789",
"status": "INCOMPLETE",
"customer_id": "INDIVIDUAL_CUSTOMER_001",
"application_document_errors": [
{
"document_id": "doc_id_12345",
"document_type": "PASSPORT",
"status": "MISSING"
},
{
"document_id": "doc_id_67890",
"document_type": "PROOF_OF_ADDRESS",
"status": "MISSING"
}
],
"application_validation_errors": []
}
}The application_document_errors array contains the document_ids you'll use in the next step. These IDs are generated by the system when you receive the status response.
Step 3: Upload Documents
Upload the required documents using the /v1/documents/{document_id} endpoint.
For each document, you'll use the document_id from the previous step:
# Upload passport
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/documents/doc_id_12345' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--form 'file=@"/path/to/passport.pdf"'
# Upload proof of address
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/documents/doc_id_67890' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--form 'file=@"/path/to/utility_bill.pdf"'Each successful upload returns:
{
"data": {
"id": "doc_id_12345",
"status": "UPLOADED"
}
}Step 4: Verify Application Readiness
Check the application status again to ensure all requirements are met:
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_123456789' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json'If ready for submission, the response will show:
{
"data": {
"id": "app_123456789",
"status": "READY_FOR_SUBMISSION",
"customer_id": "INDIVIDUAL_CUSTOMER_001",
"application_document_errors": [],
"application_validation_errors": []
}
}If the status shows
INCOMPLETE, review theapplication_validation_errorsarray to see what needs to be corrected. Update the application using the/v1/applications/{application_id}endpoint.
Step 5: Submit Application
Once the status is READY_FOR_SUBMISSION, submit the application:
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/applications/app_123456789/submit' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json'The response confirms submission:
{
"data": {
"id": "app_123456789",
"status": "SUBMITTED"
}
}Step 6: Check Application Status
Poll the status endpoint to monitor the application progress:
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_123456789' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json'The application will progress through these statuses:
- SUBMITTED → Application received and under initial review
- PROCESSING → Application is being processed by banking partners
- CHANGES_REQUESTED → Additional information or corrections needed (go back to Step 4)
- APPROVED → Customer is onboarded and account is created
- REJECTED → Application was declined (contact support for details)
When approved, the response will include the created customer:
{
"data": {
"id": "app_123456789",
"status": "APPROVED",
"customer_id": "INDIVIDUAL_CUSTOMER_001",
"created_timestamp": "2023-11-20T14:32:18.123456"
}
}Scenario 2: Corporate Customer Onboarding
Corporate customers require more extensive information including company details, beneficial owners (UBOs), officers, and authorized users.
Step 1: Create Corporate Application
Create a corporate application by calling the /v1/applications endpoint:
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/applications' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{
"customer_id": "CORPORATE_CUSTOMER_001",
"customer_type": "CORPORATION",
"profile": {
"legal_name": "Example Tech Corp",
"incorporation_date": "2020-01-01",
"tax_reference_number": "12-3456789",
"address": {
"address_line1": "456 Business Blvd",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country_code": "US"
},
"business_type": "TECHNOLOGY",
"website": "https://exampletech.com"
},
"default_account": {
"product_id": "DEPOSIT_BASIC",
"asset_type_id": "FIAT_TESTNET_USD"
}
}'The response contains the application_id:
{
"data": {
"id": "app_corp_987654",
"status": "INCOMPLETE"
}
}Step 2: Add Individuals (UBOs, Officers, Authorized Users)
Add beneficial owners and authorized users using the /v1/applications/{application_id}/individual endpoint:
# Add Beneficial Owner
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654/individual' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{
"individual_type": "BENEFICIAL_OWNER",
"ownership_percentage": 60,
"profile": {
"name": {
"first_name": "John",
"last_name": "Smith"
},
"date_of_birth": "1975-05-20",
"tax_reference_number": "987-65-4321",
"address": {
"address_line1": "789 Owner Lane",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country_code": "US"
},
"email": "john.smith@exampletech.com",
"phone_number": "+1987654321"
}
}'The response includes the individual_id:
{
"data": {
"id": "individual_001",
"individual_type": "BENEFICIAL_OWNER"
}
}Repeat this step for all beneficial owners (those owning >25%), corporate officers, and authorized users.
Step 3: Get Document IDs
Retrieve document IDs for both corporate and individual documents:
Note: This is the same endpoint used to check the application status throughout the onboarding process. It provides both status information and the document IDs you need for uploads.
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json'The response contains document IDs for the corporation and each individual:
{
"data": {
"id": "app_corp_987654",
"status": "INCOMPLETE",
"customer_id": "CORPORATE_CUSTOMER_001",
"application_document_errors": [
{
"document_id": "doc_corp_001",
"document_type": "ARTICLES_OF_INCORPORATION",
"status": "MISSING"
},
{
"document_id": "doc_corp_002",
"document_type": "OWNERSHIP_STRUCTURE",
"status": "MISSING"
}
],
"individual_errors": [
{
"individual_id": "individual_001",
"individual_type": "BENEFICIAL_OWNER",
"individual_document_errors": [
{
"document_id": "doc_ind_001",
"document_type": "PASSPORT",
"status": "MISSING"
},
{
"document_id": "doc_ind_002",
"document_type": "PROOF_OF_ADDRESS",
"status": "MISSING"
}
]
}
]
}
}You receive the document_ids from the status endpoint. The corporate documents are in application_document_errors, and individual documents are nested within individual_errors.
Step 4: Upload Documents
Upload documents for both the corporation and individuals:
# Upload corporate documents
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/documents/doc_corp_001' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--form 'file=@"/path/to/articles_of_incorporation.pdf"'
# Upload beneficial owner documents
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/documents/doc_ind_001' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--form 'file=@"/path/to/owner_passport.pdf"'Step 5: Verify and Submit
Check the application status to ensure it's READY_FOR_SUBMISSION:
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654' \
--header 'Authorization: Bearer {AUTH_TOKEN}'If ready, submit the application:
curl --location --request POST 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654/submit' \
--header 'Authorization: Bearer {AUTH_TOKEN}' \
--header 'Content-Type: application/json'Step 6: Monitor Application Status
Poll the status endpoint to track progress through approval:
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654' \
--header 'Authorization: Bearer {AUTH_TOKEN}'Application Status Flow
Applications progress through several stages:
INCOMPLETE → READYFORSUBMISSION → SUBMITTED → PROCESSING → APPROVED / REJECTED
Note: When an application shows
CHANGES_REQUESTED, you must update the application by fixing fields and/or uploading documents, then resubmit. Use the Application Status endpoint to see exactly what needs to be changed.
For more details on application statuses, see the Applications Guide.
Multi-Provider Processing
Rail works with multiple banking partners simultaneously to provide the best service and redundancy. Here's how it works:
- Initial Approval : When you submit an application, Rail first approves it based on our compliance requirements
- Provider Translation : Once approved by Rail, the application data is sent to our banking providers
- Customer Activation : As providers approve the application, the customer becomes "active" and can start transacting
-
Ongoing Processing
: The main application may still show as
PROCESSINGbecause not all partners have completed their approval process
This multi-provider approach ensures:
- Faster time to activation (customer can transact as soon as one provider approves)
- Higher approval rates (multiple providers increase chances of approval)
- Better redundancy and service reliability
Summary
Let's review the customer onboarding process:
Individual Customer Onboarding
-
Authenticate
- Get your
AUTH_TOKENusing OAuth2 -
Create Application
- POST to
/v1/applicationswith individual details -
Get Document IDs
- GET
/v1/applications/{application_id}to retrieve document IDs -
Upload Documents
- POST to
/v1/documents/{document_id}for passport and proof of address -
Submit Application
- POST to
/v1/applications/{application_id}/submit -
Monitor Status
- Poll the status endpoint until
APPROVED
Corporate Customer Onboarding
-
Authenticate
- Get your
AUTH_TOKENusing OAuth2 -
Create Application
- POST to
/v1/applicationswith corporate details -
Add Individuals
- POST to
/v1/applications/{application_id}/individualfor each UBO, officer, and authorized user -
Get Document IDs
- GET
/v1/applications/{application_id}to retrieve all document IDs -
Upload Documents
- POST to
/v1/documents/{document_id}for corporate and individual documents -
Submit Application
- POST to
/v1/applications/{application_id}/submit -
Monitor Status
- Poll the status endpoint until
APPROVED
To dive deeper into what you can do on the Rail platform, head to our API documentation.
Contact Us - We'd love to hear your thoughts, and you can contact the team via slack, website or email support@layer2financial.com.