> ## Documentation Index
> Fetch the complete documentation index at: https://docs.conduit.financial/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer Onboarding

> This guide shows how to create and onboard your first customer on Conduit using the Customer API.

## Pre-requisites

* Active Conduit account with API access
* API credentials (API Key and Secret) - see [Setting up your API credentials](/guides/authentication)
* You have reviewed our [Customers](/core-concepts/customers) Core Concepts

## Hosted Onboarding

<Steps>
  <Step title="Hosted Onboarding (Generate a KYB Link)">
    Create the customer and request a hosted KYB link in a single call by setting `onboardingFlow: kyb_link`.

    **Endpoint:** `POST /customers`

    ### Request Example

    ```bash theme={null}
    curl --request POST \
      --url https://api.conduit.financial/customers \
      --header "X-API-Key: your_api_key" \
      --header "X-API-Secret: your_api_secret" \
      --header "Content-Type: application/json" \
      --header "Api-Version: 2024-12-01"
      --data '{
      "businessLegalName": "Acme Corporation Inc.",
      "country": "USA",
      "onboardingFlow": "kyb_link"
      }'
    ```

    ### Response Example

    ```json theme={null}
    {
      "id": "cus_2ofTA13AD0xBtbEvBl20aEb1hEu",
      "onboardingFlow": "kyb_link",
      "kybLink": "https://example.com/kyb/verify/abc123",
      "kybLinkExpiration": "2024-12-31T23:59:59.000Z",
      "businessLegalName": "Example Business"
    }
    ```
  </Step>

  <Step title="Hosted Onboarding: Share the KYB Link">
    Share this link with your customer. In this hosted flow your customer will provide their business details, information on control persons, and documents directly to us by filling up the KYB link.
  </Step>

  <Step title="Hosted Onboarding: Monitor the Status">
    Monitor the status of the customer onboarding process via webhooks or the dashboard.  Learn more about creating a webhook [here](/guides/webhooks/first-webhook).

    After submission, liveness links are provided per control person; ensure your customer's control persons' complete liveness selfie check to proceed with review. and account opening
  </Step>

  <Step title="Hosted Onboarding: Renew the KYB Link">
    If the KYB link expires, you can generate a new one by creating a new customer with the same `customerId`.

    ### Request Example

    ```bash theme={null}
    curl --request POST \
    --url https://sandbox-api.conduit.financial/customers/{id}/kyb-link \
    --header 'X-API-Key: <api-key>' \
    --header 'X-API-Secret: <api-key>'
    ```

    ### Response Example

    ```json theme={null}
    {
    "message": "KYB verification link created successfully",
    "verification_url": "https://example.com/kyb/verify/abc123"
    }
    ```
  </Step>
</Steps>

## Direct Onboarding (API-first)

<Steps>
  <Step title="Direct Onboarding (API-first): Create a Customer">
    Create the customer with `onboardingFlow: direct` and include business information to start the API-first onboarding flow.

    ### Request Example

    ```bash theme={null}
    curl --request POST \
      --url https://api.conduit.financial/customers \
      --header "X-API-Key: your_api_key" \
      --header "X-API-Secret: your_api_secret" \
      --header "Content-Type: application/json" \
      --header "Api-Version: 2024-12-01" \
      --data '{
        "businessLegalName": "Acme Corporation Inc.",
        "country": "USA",
        "onboardingFlow": "direct",
        "businessInformation": {
          "hasDBA": false,
          "registeredDate": "2024-01-01",
          "website": "https://acme.com",
          "industry": "General Commercial/Operating Entity",
          "email": "[email protected]",
          "phone": "+1234567890",
          "taxIdentificationNumber": "12-3456789",
          "businessEntityId": "BE001",
          "naicsCode": "541511",
          "isFinancialInstitution": false,
          "registeredAddress": {
            "streetLine1": "456 Office Ave",
            "streetLine2": "Suite 200",
            "city": "New York",
            "state": "NY",
            "postalCode": "10002",
            "country": "USA"
          },
          "operatingAddress": {
            "streetLine1": "456 Office Ave",
            "streetLine2": "Suite 200",
            "city": "New York",
            "state": "NY",
            "postalCode": "10002",
            "country": "USA"
          },
          "isSubsidiary": false,
          "isOperating": true,
          "businessDescription": "Provider of industrial widgets and services",
          "businessEntityType": "Corporation",
          "accountPurpose": "Payroll/ Employee Payouts",
          "highRiskIndustry": "None of the above",
          "hasNestedFlows": false,
          "certifiesOwnTreasuryUse": true,
          "keyGeographicBusinessCountries": ["USA"],
          "anticipatedTransactionsVolume": 1000,
          "usesBlockChainWallets": false,
          "anticipatedMonthlyVolume": 100000,
          "expectedAverageDailyBalance": 250000,
          "sourceOfFunds": "Revenue From Products/Services",
          "productsOrServices": ["Technology / SaaS Provider"],
          "isGeneratingRevenues": true,
          "revenueCoverage": "More than 50% of expenses and growing",
          "hasInstitutionalInvestors": false,
          "runwayDurationMonths": "More than 12 months",
          "cashOnHandUsd": 500000,
          "flowOfFundsDescription": "Funds are collected from customers via payment processing and disbursed to vendors and suppliers.",
          "termsOfServiceAcceptance": {
            "date": "2024-01-01",
            "ipAddress": "192.168.1.1",
            "isAuthenticated": true
          }
        }
      }'

    ```

    ### Response Example

    ```json theme={null}
    {
      "onboardingFlow": "direct",
      "id": "cus_2ofTA13AD0xBtbEvBl20aEb1hEu",
      "status": "created",
      "businessLegalName": "Acme Corporation Inc."
    }

    ```

    <Note>
      Success! Save this `customerId` - you'll need it for subsequent steps
    </Note>
  </Step>

  <Step title="Direct Onboarding: Add Control Persons">
    Register individuals with 25%+ ownership or significant control over the business.

    ### Request Example

    **Endpoint:** `POST /customers/{customer_id}/control-persons`

    ### Request Example

    ```bash theme={null}
    curl --request POST \
      --url https://api.conduit.financial/customers/cus_30V7EQpemfcgMctQUjDKf1sQLtA/control-persons \
      --header "X-API-Key: your_api_key" \
      --header "X-API-Secret: your_api_secret" \
      --header "Content-Type: application/json" \
      --header "Api-Version: 2024-12-01" \
      --data '{
        "controlPersons": [
          {
            "firstName": "John",
            "lastName": "Doe",
            "email": "[email protected]",
            "birthDate": "1980-01-15",
            "nationality": "USA",
            "phone": "+1234567890",
            "ownershipPercentage": 100,
            "ssn": "123-45-6789",
            "address": {
              "streetLine1": "123 Main St",
              "city": "New York",
              "state": "NY",
              "postalCode": "10001",
              "country": "USA"
            },
            "roles": [
              {
                "name": "beneficial_owner",
                "startDate": "2024-01-01",
                "current": true
              }
            ],
            "identityInfo": {
              "documentCountry": "USA",
              "documentType": "passport",
              "documentNumber": "123456789",
              "documentIssueDate": "2020-01-01",
              "documentExpiryDate": "2030-01-01"
            }
          }
        ]
      }'

    ```

    ### Response Example

    ```json theme={null}
    {
      "success": true,
      "customerId": "cus_30V7EQpemfcgMctQUjDKf1sQLtA",
      "controlPersons": [
        {
          "id": "ctl_2nqjHpNLK6wSNlFyMvZgX8SYeAO",
          "firstName": "John",
          "lastName": "Doe",
          "email": "[email protected]"
        }
      ]
    }

    ```

    <Note>
      Save each `controlPersonId` - you’ll use them when uploading KYC documents
    </Note>
  </Step>

  <Step title="Direct Onboarding: Upload KYB Documents ">
    Upload business verification documents (KYB) for the business entity.

    **Endpoint:** `POST /customers/onboarding/{customer_id}/documents` Use the `purpose="kyb"` to upload business verification documents (KYB).

    ### Request Example

    ```bash theme={null}
    curl --request POST \
      --url https://api.conduit.financial/customers/onboarding/cus_30V7EQpemfcgMctQUjDKf1sQLtA/documents \
      --header "X-API-Key: your_api_key" \
      --header "X-API-Secret: your_api_secret" \
      --header "Api-Version: 2024-12-01" \
      --form 'name="Articles of Incorporation"' \
      --form 'purpose="kyb"' \
      --form 'type="articles_of_incorporation"' \
      --form 'front=@"/path/to/articles.pdf"'

    ```

    ### Response Example

    ```json theme={null}

    {
     "id": "doc_2nqjHpNLK6wSNlFyMvZgX8SYeAO",
     "createdAt": "2024-10-26T02:21:03.742Z"
    }

    ```
  </Step>

  <Step title="Direct Onboarding: Upload KYC Documents">
    Upload identity documents (KYC) for each registered control person.

    **Endpoint:** `POST /customers/onboarding/{customer_id}/documents`

    Use the `purpose="kyc"` to upload identity documents (KYC).

    Use the `controlPersonId` to upload identity documents for a specific control person.

    ### Request Example ( Single File Upload)

    ```bash theme={null}
    curl --location 'https://sandbox-api.conduit.financial/customers/onboarding/cus_36Ni3GyVjJMX1mBVdl9cr2fUXCw/documents' \
    --header 'x-api-key: API_KEY' \
    --header 'x-api-secret: API_SECRET' \
    --header 'Api-Version: 2024-12-01' \
    --form 'file=@"/path/to/passport.jpg"' \
    --form 'name="Passport"' \
    --form 'purpose="kyc"' \
    --form 'type="passport"' \
    --form 'controlPersonId="ctl_35mz1MuXalPtkKjrl5WnqiA8ZHf"'
    ```

    ### Request Example ( Front and Back File Upload)

    ```bash theme={null}
    curl --location 'https://sandbox-api.conduit.financial/customers/onboarding/cus_36Ni3GyVjJMX1mBVdl9cr2fUXCw/documents' \
    --header 'x-api-key: API_KEY' \
    --header 'x-api-secret: API_SECRET' \
    --header 'Api-Version: 2024-12-01' \
    --form 'front=@"/path/to/front.jpg"' \
    --form 'back=@"/path/to/back.jpg"' \
    --form 'name="Driver License"' \
    --form 'purpose="kyc"' \
    --form 'type="driver_license"' \
    --form 'controlPersonId="ctl_35mz1MuXalPtkKjrl5WnqiA8ZHf"'
    ```
  </Step>

  <Step title="Direct Onboarding: Submit for Review">
    Submit onboarding data for compliance review.

    **Endpoint:** `POST /customers/{customer_id}/submit`

    ### Request Example

    ```bash theme={null}
    curl --request POST \
      --url https://api.conduit.financial/customers/cus_30V7EQpemfcgMctQUjDKf1sQLtA/submit \
      --header "X-API-Key: your_api_key" \
      --header "X-API-Secret: your_api_secret" \
      --header "Content-Type: application/json" \
      --header "Api-Version: 2024-12-01"

    ```

    ### Response Example

    ```json theme={null}
    {
      "success": true,
      "status": "manual_review",
      "livenessLinks": [
        {
          "controlPersonId": "ctl_34yPkFSqTUpwOwe0zoovDKU9Yad",
          "verificationUrl": "https://verify.example.com/?verification_session_id=abc"
        }
      ]
    }
    ```

    <Note>
      Response includes <code>
      livenessLinks</code>

      with a <code>
      verificationUrl</code>

      per control person. Save these links. Use them to complete liveness as this is a mandatory step in the onboarding process.
    </Note>
  </Step>

  <Step title="Direct Onboarding: Complete Liveness Checks">
    The <code>livenessLinks</code> are available only if the control person's roles include <code>authorized\_representative</code>. Use each <code>verificationUrl</code> from <code>livenessLinks</code> to prompt the corresponding control person to complete liveness. Once completed, the onboarding review proceeds automatically.
  </Step>

  <Step title="Direct Onboarding: Fetch Latest Liveness Link (if needed)">
    If you didn't save the link, you can fetch the latest liveness information for a control person.

    **Endpoint:** <code>
    GET /customers/:customer\_id/control-persons/:control\_person\_id/liveness</code>

    ### Request Example

    ```bash theme={null}
    curl --request GET \
      --url "https://api.conduit.financial/customers/cus_30V7EQpemfcgMctQUjDKf1sQLtA/control-persons/ctl_2nqjHpNLK6wSNlFyMvZgX8SYeAO/liveness" \
      --header "X-API-Key: your_api_key" \
      --header "X-API-Secret: your_api_secret" \
      --header "Api-Version: 2024-12-01"
    ```

    ### Response Example

    ```json theme={null}
    {
      "controlPersonId": "ctl_2nqjHpNLK6wSNlFyMvZgX8SYeAO",
      "verificationUrl": "https://verify.example.com/?verification_session_id=abc",
      "status": "PENDING",
      "expirationDate": "2025-12-31T23:59:59.000Z"
    }
    ```
  </Step>
</Steps>

## Summary

Once the customer status is `active`, they’re verified and ready to:

* Add [payment methods](/core-concepts/payment-methods) (bank accounts, funding sources)
* Create [counterparties](/core-concepts/counterparties)

<Note>
  A Virtual USD Account is provisioned for the customer after onboarding is completed. Learn more: [Virtual USD Accounts](/core-concepts/virtual-accounts).
</Note>

## What's next?

* [Create Your Customer's First Payment Method](/guides/customer/first-payment-method)
* [Create Your Customer's First Counterparty](/guides/counterparty/adding-a-counterparty)
* [Configure Your First Webhook](/guides/webhooks/first-webhook)
* [Read more about Virtual USD Accounts](/core-concepts/virtual-accounts)

## API Reference

Check our [API Reference](/api-reference/customers/create-a-customer) to learn how to create and manage customers using our API.

## Support

Reach out to our [support team](https://support.conduitpay.com/) to get help and share your feedback.
