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:

  1. POST /v1/applications - Create the application
  2. GET /v1/applications/{application_id} - Retrieve application status to identify required documents
  3. POST /v1/applications/{application_id}/documents - Upload KYC documents
  4. GET /v1/applications/{application_id} - Retrieve application details again to verify completion
  5. POST /v1/applications/{application_id}/submit - Submit the application for processing

Build Guide

This guide provides two scenarios:

  1. Individual Customer Onboarding
  2. Corporate Customer Onboarding

By the end of this guide you will have:

  1. Authenticated your request
  2. Created an application
  3. Retrieved document IDs
  4. Uploaded required documents
  5. Submitted the application
  6. 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:

Copy
Copied
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:

Copy
Copied
{
    "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:read and applications:write to create and manage applications
  • customers:read to 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.

Copy
Copied
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:

Copy
Copied
{
    "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.

Copy
Copied
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:

Copy
Copied
{
    "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:

Copy
Copied
# 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:

Copy
Copied
{
    "data": {
        "id": "doc_id_12345",
        "status": "UPLOADED"
    }
}

Step 4: Verify Application Readiness

Check the application status again to ensure all requirements are met:

Copy
Copied
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:

Copy
Copied
{
    "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 the application_validation_errors array 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:

Copy
Copied
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:

Copy
Copied
{
    "data": {
        "id": "app_123456789",
        "status": "SUBMITTED"
    }
}

Step 6: Check Application Status

Poll the status endpoint to monitor the application progress:

Copy
Copied
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:

Copy
Copied
{
    "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:

Copy
Copied
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:

Copy
Copied
{
    "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:

Copy
Copied
# 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:

Copy
Copied
{
    "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.

Copy
Copied
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:

Copy
Copied
{
    "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:

Copy
Copied
# 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:

Copy
Copied
curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654' \
--header 'Authorization: Bearer {AUTH_TOKEN}'

If ready, submit the application:

Copy
Copied
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:

Copy
Copied
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:

INCOMPLETEREADYFORSUBMISSIONSUBMITTEDPROCESSINGAPPROVED / 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:

  1. Initial Approval : When you submit an application, Rail first approves it based on our compliance requirements
  2. Provider Translation : Once approved by Rail, the application data is sent to our banking providers
  3. Customer Activation : As providers approve the application, the customer becomes "active" and can start transacting
  4. Ongoing Processing : The main application may still show as PROCESSING because 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

  1. Authenticate - Get your AUTH_TOKEN using OAuth2
  2. Create Application - POST to /v1/applications with individual details
  3. Get Document IDs - GET /v1/applications/{application_id} to retrieve document IDs
  4. Upload Documents - POST to /v1/documents/{document_id} for passport and proof of address
  5. Submit Application - POST to /v1/applications/{application_id}/submit
  6. Monitor Status - Poll the status endpoint until APPROVED

Corporate Customer Onboarding

  1. Authenticate - Get your AUTH_TOKEN using OAuth2
  2. Create Application - POST to /v1/applications with corporate details
  3. Add Individuals - POST to /v1/applications/{application_id}/individual for each UBO, officer, and authorized user
  4. Get Document IDs - GET /v1/applications/{application_id} to retrieve all document IDs
  5. Upload Documents - POST to /v1/documents/{document_id} for corporate and individual documents
  6. Submit Application - POST to /v1/applications/{application_id}/submit
  7. 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.

© 2024 Rail. All Rights Reserved.