# Customer Onboarding via API *If you haven't already, [Sign Up for Sandbox Access](https://rail.io/contact-us) 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`](/api-docs/openapi/rail-spec#operation/createApplication) - Create the application 2. **GET** [`/v1/applications/{application_id}`](/api-docs/openapi/rail-spec#operation/getApplicationStatus) - Retrieve application status to identify required documents 3. **POST** [`/v1/applications/{application_id}/documents`](/api-docs/openapi/rail-spec#operation/uploadDocument) - Upload KYC documents 4. **GET** [`/v1/applications/{application_id}`](/api-docs/openapi/rail-spec#operation/getApplicationStatus) - Retrieve application details again to verify completion 5. **POST** [`/v1/applications/{application_id}/submit`](/api-docs/openapi/rail-spec#operation/submitApplication) - Submit the application for processing ## Build Guide This guide provides two scenarios: 1. [Individual Customer Onboarding](#scenario-1-individual-customer-onboarding) 2. [Corporate Customer Onboarding](#scenario-2-corporate-customer-onboarding) By the end of this guide you will have: 1. [Authenticated your request](#authenticating-your-request) 2. [Created an application](#scenario-1-individual-customer-onboarding) 3. [Retrieved document IDs](#step-2-get-document-ids) 4. [Uploaded required documents](#step-3-upload-documents) 5. [Submitted the application](#step-5-submit-application) 6. [Monitored application status](#step-6-check-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: ```bash 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`: ```javascript { "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](/guides/authentication). ## 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`](/api-docs/openapi/rail-spec#operation/createApplication) endpoint. ```bash 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: ```javascript { "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_id`s by calling the [`/v1/applications/{application_id}`](/api-docs/openapi/rail-spec#operation/getApplicationStatus) 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. ```bash 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: ```javascript { "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_id`s 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}`](/api-docs/openapi/rail-spec#operation/uploadDocument) endpoint. For each document, you'll use the `document_id` from the previous step: ```bash # 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: ```javascript { "data": { "id": "doc_id_12345", "status": "UPLOADED" } } ``` ### Step 4: Verify Application Readiness Check the application status again to ensure all requirements are met: ```bash 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: ```javascript { "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}`](/api-docs/openapi/rail-spec#operation/updateApplication) endpoint. ### Step 5: Submit Application Once the status is `READY_FOR_SUBMISSION`, submit the application: ```bash 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: ```javascript { "data": { "id": "app_123456789", "status": "SUBMITTED" } } ``` ### Step 6: Check Application Status Poll the status endpoint to monitor the application progress: ```bash 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: ```javascript { "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`](/api-docs/openapi/rail-spec#operation/createApplication) endpoint: ```bash 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`: ```javascript { "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`](/api-docs/openapi/rail-spec#operation/addIndividualToApplication) endpoint: ```bash # 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`: ```javascript { "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. ```bash 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: ```javascript { "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_id`s 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: ```bash # 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`: ```bash curl --location --request GET 'https://sandbox.layer2financial.com/api/v1/applications/app_corp_987654' \ --header 'Authorization: Bearer {AUTH_TOKEN}' ``` If ready, submit the application: ```bash 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: ```bash 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** → **READY_FOR_SUBMISSION** → **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](/api-docs/openapi/rail-spec#operation/getApplicationStatus) to see exactly what needs to be changed. For more details on application statuses, see the [Applications Guide](/guides/applications). ## 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`](/api-docs/openapi/rail-spec#operation/createApplication) with individual details 3. **Get Document IDs** - GET [`/v1/applications/{application_id}`](/api-docs/openapi/rail-spec#operation/getApplicationStatus) to retrieve document IDs 4. **Upload Documents** - POST to [`/v1/documents/{document_id}`](/api-docs/openapi/rail-spec#operation/uploadDocument) for passport and proof of address 5. **Submit Application** - POST to [`/v1/applications/{application_id}/submit`](/api-docs/openapi/rail-spec#operation/submitApplication) 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`](/api-docs/openapi/rail-spec#operation/createApplication) with corporate details 3. **Add Individuals** - POST to [`/v1/applications/{application_id}/individual`](/api-docs/openapi/rail-spec#operation/addIndividualToApplication) for each UBO, officer, and authorized user 4. **Get Document IDs** - GET [`/v1/applications/{application_id}`](/api-docs/openapi/rail-spec#operation/getApplicationStatus) to retrieve all document IDs 5. **Upload Documents** - POST to [`/v1/documents/{document_id}`](/api-docs/openapi/rail-spec#operation/uploadDocument) for corporate and individual documents 6. **Submit Application** - POST to [`/v1/applications/{application_id}/submit`](/api-docs/openapi/rail-spec#operation/submitApplication) 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](/api-docs/openapi/rail-spec).