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

# Business Verification (KYB)

> Complete identity verification for business customers

After creating a business customer, you must complete identity verification (KYB) before they can transact. Business verification requires company information, documents, and details about associated parties (UBOs, shareholders, and representatives).

<Info>
  If you don't want to build the verification flow via API, you can share the
  `verification.link` returned in the customer response directly with your
  customer. The link opens a guided flow where they can submit all required
  information and documents without any additional API integration.
</Info>

<Warning>
  If you start the verification process through the API, do not share the
  `verification.link` with your customer. Mixing both approaches can cause
  conflicts and lead to unexpected issues during the verification flow.
</Warning>

## Prerequisites

* A business customer already created (see [Create a Customer](/guides/create-a-customer))
* An API key from the [Dashboard](https://dashboard.lumx.io)
* Your environment base URL (see [Environments](/get-started/environments))

## Verification flow

<Steps>
  <Step title="Accept terms of service">
    Before starting verification, the customer must accept the terms of service. Send a `POST` request to `/customers/{id}/tos` to get the acceptance URL. You can optionally include a `redirectUrl` to redirect the customer after they accept.

    ```bash Request theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/tos \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "redirectUrl": "https://yourapp.com/onboarding/next-step"
      }'
    ```

    ```json Response theme={null}
    {
      "url": "https://dashboard.lumx.io/tos/sandbox/eyJhbGciOiJSUzI1...",
      "expiresAt": "2026-04-09T16:00:00Z"
    }
    ```

    Share the returned URL with your customer. The link expires after 24 hours. Generate a new one if needed. The `requirements` array will show `TERMS_OF_SERVICE` as `NOT_SENT` until they accept. You can check the status by [reading the customer](/api-reference/customers/read-a-customer).

    <Note>
      The request body is optional. If you don't need to redirect the customer after acceptance, you can send the request without a body.
    </Note>
  </Step>

  <Step title="Send additional information">
    Send a `PATCH` request to `/customers/{id}/additional-information` with the company's details and transactional information.

    ```bash Request theme={null}
    curl -X PATCH https://api-sandbox.lumx.io/customers/{id}/additional-information \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "type": "BUSINESS",
        "phone": "+5511999999999",
        "address": {
          "country": "BRA",
          "line1": "Av. Paulista, 1000, Sala 101",
          "city": "São Paulo",
          "state": "SP",
          "postalCode": "01310-100"
        },
        "monthlyVolumeInUSD": "50000.00",
        "transactionVolumeInUSD": "10000.00",
        "jurisdictions": ["BRA", "USA", "EU"],
        "involvedActivities": ["NONE"],
        "transactionCounterparties": ["SELF"],
        "companyType": "BLOCKCHAIN_SOFTWARE_COMPANY",
        "annualRevenue": "1000000.00",
        "monthlyTransactionVolume": "100000.00",
        "complianceAndAML": "We have a dedicated compliance team and use third-party AML screening tools.",
        "isRegulatedActivity": false,
        "regulatedActivityDetails": "",
        "website": "https://example.com",
        "sourceOfFunds": "COMPANY",
        "servicesProvided": "We provide blockchain-based payment infrastructure for B2B cross-border transactions."
      }'
    ```

    All fields are required. Here's a summary of the business-specific fields:

    | Field                      | Description                                                              |
    | :------------------------- | :----------------------------------------------------------------------- |
    | `companyType`              | Type of company (e.g., `BLOCKCHAIN_SOFTWARE_COMPANY`, `PAYMENT_GATEWAY`) |
    | `annualRevenue`            | Company's annual revenue in USD                                          |
    | `monthlyTransactionVolume` | Expected monthly transaction volume                                      |
    | `complianceAndAML`         | Description of the company's compliance and AML policies                 |
    | `isRegulatedActivity`      | Whether the company is involved in regulated activities                  |
    | `regulatedActivityDetails` | Details if `isRegulatedActivity` is `true`                               |
    | `website`                  | Company website URL                                                      |
    | `sourceOfFunds`            | Origin of funds (e.g., `COMPANY`, `COMPANY_CAPITAL`, `INVESTMENT`)       |
    | `servicesProvided`         | Description of the services or products the company offers               |

    For all accepted values, see the [API Reference](/api-reference/customers/send-additional-information).
  </Step>

  <Step title="Upload company documents">
    Upload company documents using `POST /customers/{id}/documents`. Each document is sent as a `multipart/form-data` request.

    Required documents:

    * `INCORPORATION_ARTICLES`
    * `SHAREHOLDER_REGISTRY`
    * `DIRECTORS_REGISTRY`
    * `PROOF_OF_ADDRESS` (must be from the last 90 days)

    Optional documents:

    * `POWER_OF_ATTORNEY`
    * `REGULATED_ACTIVITY_DOCUMENT`
    * `SIGNED_BALANCE_SHEET`
    * `SIGNED_CORPORATE_STRUCTURE_CHART`
    * `SIGNED_INCOME_STATEMENT`
    * `OTHER` (any additional document)

    ```bash Upload incorporation articles theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/incorporation-articles.pdf" \
      -F "type=INCORPORATION_ARTICLES" \
      -F "country=BRA"
    ```

    ```bash Upload shareholder registry theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/shareholder-registry.pdf" \
      -F "type=SHAREHOLDER_REGISTRY" \
      -F "country=BRA"
    ```

    ```bash Upload directors registry theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/directors-registry.pdf" \
      -F "type=DIRECTORS_REGISTRY" \
      -F "country=BRA"
    ```

    Files must be JPG, PNG, or PDF with a maximum size of 50MB.
  </Step>

  <Step title="Add associated parties">
    Add the company's UBOs, shareholders, and representatives using `POST /customers/{id}/associated-parties`. Each associated party can have one or more roles.

    <Warning>
      Before starting verification, the company must have at least one associated party assigned to each required role: <b>UBO</b>, <b>Shareholder</b>, and <b>Representative</b>.

       A single individual may fulfill multiple roles, and multiple individuals may be assigned to the same role.
    </Warning>

    There are three role types:

    * `UBO` (Ultimate Beneficial Owner): always `INDIVIDUAL` type. Requires `ownershipPercentage` (25–100%).
    * `SHAREHOLDER`: can be `INDIVIDUAL` or `BUSINESS` type. Requires `ownershipPercentage` (25–100%).
    * `REPRESENTATIVE`: always `INDIVIDUAL` type. No `ownershipPercentage` needed.

    <Tabs>
      <Tab title="UBO (Individual)">
        ```bash Request theme={null}
        curl -X POST https://api-sandbox.lumx.io/customers/{id}/associated-parties \
          -H "Authorization: Bearer YOUR_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "type": "INDIVIDUAL",
            "roles": ["UBO"],
            "name": "Maria Santos",
            "birthDate": "1985-07-10",
            "email": "maria.santos@example.com",
            "taxId": "987.654.321-00",
            "address": {
              "country": "BRA",
              "line1": "Rua das Acácias, 456",
              "city": "Rio de Janeiro",
              "state": "RJ",
              "postalCode": "20000-000"
            },
            "ownershipPercentage": 40
          }'
        ```

        ```json Response theme={null}
        {
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "type": "INDIVIDUAL",
          "roles": ["UBO"],
          "name": "Maria Santos",
          "taxId": "987.654.321-00",
          "birthDate": "1985-07-10",
          "email": "maria.santos@example.com",
          "address": {
            "country": "BRA",
            "line1": "Rua das Acácias, 456",
            "city": "Rio de Janeiro",
            "state": "RJ",
            "postalCode": "20000-000"
          },
          "ownershipPercentage": 40,
          "verification": {
            "status": "NOT_STARTED",
            "level": "STANDARD",
            "link": "https://in.sumsub.com/websdk/p/sbx_aA00bB11cC33dD44"
          },
          "createdAt": "2024-01-15T11:00:00Z",
          "updatedAt": "2024-01-15T11:00:00Z"
        }
        ```
      </Tab>

      <Tab title="Shareholder (Individual)">
        ```bash Request theme={null}
        curl -X POST https://api-sandbox.lumx.io/customers/{id}/associated-parties \
          -H "Authorization: Bearer YOUR_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "type": "INDIVIDUAL",
            "roles": ["SHAREHOLDER"],
            "name": "Pedro Oliveira",
            "birthDate": "1978-12-05",
            "email": "pedro.oliveira@example.com",
            "taxId": "111.222.333-44",
            "address": {
              "country": "BRA",
              "line1": "Av. Brasil, 789",
              "city": "São Paulo",
              "state": "SP",
              "postalCode": "01000-000"
            },
            "ownershipPercentage": 35
          }'
        ```
      </Tab>

      <Tab title="Shareholder (Business)">
        ```bash Request theme={null}
        curl -X POST https://api-sandbox.lumx.io/customers/{id}/associated-parties \
          -H "Authorization: Bearer YOUR_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "type": "BUSINESS",
            "roles": ["SHAREHOLDER"],
            "legalName": "Investment Fund ABC",
            "incorporationDate": "2010-05-20",
            "email": "contact@fundabc.com",
            "taxId": "99.988.877/0001-66",
            "address": {
              "country": "USA",
              "line1": "123 Wall Street",
              "city": "New York",
              "state": "NY",
              "postalCode": "10005"
            },
            "ownershipPercentage": 25
          }'
        ```
      </Tab>

      <Tab title="Representative">
        ```bash Request theme={null}
        curl -X POST https://api-sandbox.lumx.io/customers/{id}/associated-parties \
          -H "Authorization: Bearer YOUR_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "type": "INDIVIDUAL",
            "roles": ["REPRESENTATIVE"],
            "name": "Carlos Mendes",
            "birthDate": "1990-03-15",
            "email": "carlos.mendes@example.com",
            "taxId": "555.666.777-88",
            "address": {
              "country": "BRA",
              "line1": "Rua Principal, 100",
              "city": "Belo Horizonte",
              "state": "MG",
              "postalCode": "30000-000"
            }
          }'
        ```

        <Note>Representatives do not require `ownershipPercentage`.</Note>
      </Tab>

      <Tab title="Multiple roles">
        ```bash Request theme={null}
        curl -X POST https://api-sandbox.lumx.io/customers/{id}/associated-parties \
          -H "Authorization: Bearer YOUR_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "type": "INDIVIDUAL",
            "roles": ["UBO", "REPRESENTATIVE"],
            "name": "Ana Silva",
            "birthDate": "1982-09-25",
            "email": "ana.silva@example.com",
            "taxId": "444.555.666-77",
            "address": {
              "country": "BRA",
              "line1": "Av. das Nações, 200",
              "city": "Brasília",
              "state": "DF",
              "postalCode": "70000-000"
            },
            "ownershipPercentage": 30
          }'
        ```

        <Note>When an associated party has multiple roles, include all applicable roles in the `roles` array. If UBO or SHAREHOLDER is included, `ownershipPercentage` is required.</Note>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Upload associated party documents">
    Upload documents for each associated party using the same `POST /customers/{id}/documents` endpoint, but include the `associatedPartyId` field.

    Individual associated parties (UBOs, shareholders, and representatives) need an identity document (`ID_CARD`, `PASSPORT`, or `DRIVERS_LICENSE`) and a `PROOF_OF_ADDRESS` from the last 90 days:

    <Note>
      Identity documents (`ID_CARD` and `DRIVERS_LICENSE`) require the `side` field. Upload the front and back as separate requests. For the digital Brazilian driver's license (CNH digital), the `side` field is not needed.
    </Note>

    ```bash Upload identity document for associated party (front) theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/document-front.jpg" \
      -F "type=ID_CARD" \
      -F "side=FRONT_SIDE" \
      -F "country=BRA" \
      -F "associatedPartyId=a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    ```

    ```bash Upload identity document for associated party (back) theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/document-back.jpg" \
      -F "type=ID_CARD" \
      -F "side=BACK_SIDE" \
      -F "country=BRA" \
      -F "associatedPartyId=a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    ```

    ```bash Upload proof of address for associated party theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/proof-of-address.pdf" \
      -F "type=PROOF_OF_ADDRESS" \
      -F "country=BRA" \
      -F "associatedPartyId=a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    ```

    Business associated parties need company formation documents:

    ```bash Upload incorporation articles for business shareholder theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/incorporation-articles.pdf" \
      -F "type=INCORPORATION_ARTICLES" \
      -F "country=USA" \
      -F "associatedPartyId=b2c3d4e5-f6a7-8901-bcde-f12345678901"
    ```

    ```bash Upload directors registry for business shareholder theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/documents \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "file=@/path/to/directors-registry.pdf" \
      -F "type=DIRECTORS_REGISTRY" \
      -F "country=USA" \
      -F "associatedPartyId=b2c3d4e5-f6a7-8901-bcde-f12345678901"
    ```
  </Step>

  <Step title="Start verification">
    Unlike individual customers, business verification must be started explicitly. Ensure all documents and associated parties are uploaded before calling this endpoint.

    ```bash Request theme={null}
    curl -X POST https://api-sandbox.lumx.io/customers/{id}/verifications \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    ```json Response theme={null}
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
    }
    ```

    <Warning>
      Before starting verification, ensure you have:

      * At least one associated party with each role type: UBO, SHAREHOLDER, and REPRESENTATIVE
      * All required company documents uploaded
      * All associated party documents uploaded

      Missing documents or role types will delay or prevent the verification review.
    </Warning>
  </Step>

  <Step title="Monitor verification status">
    Check the verification status using the verification ID returned in the previous step:

    ```bash Request theme={null}
    curl https://api-sandbox.lumx.io/customers/{id}/verifications/{verificationId} \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    ```json Response theme={null}
    {
      "customerId": "c85cb5ef-0574-4450-806d-195944f1e309",
      "status": "UNDER_VERIFICATION",
      "level": "STANDARD"
    }
    ```

    | Status               | Description                                     |
    | :------------------- | :---------------------------------------------- |
    | `NOT_STARTED`        | Verification created but review not yet started |
    | `UNDER_VERIFICATION` | Documents submitted and being reviewed          |
    | `APPROVED`           | Verification complete. Customer can transact    |
    | `RFI`                | Additional documentation required               |
    | `FINAL_REJECTION`    | Customer permanently rejected                   |

    You can also receive status updates via [webhooks](/developer/webhooks) instead of polling.

    <Tip>
      In sandbox, you can simulate different verification statuses using magic numbers in the customer's `taxId`. See [Sandbox magic numbers](/compliance/identity-verification#sandbox-magic-numbers) for the full list.
    </Tip>
  </Step>
</Steps>

## Multi-level corporate structures

If your customer has a multi-level ownership structure (e.g., a holding company that owns another company that owns the customer), you can use the `parentId` field to nest shareholders across multiple levels.

For example, if "Investment Fund ABC" (a business shareholder) has its own individual shareholders, you can link them by passing the fund's associated party ID as `parentId`:

```bash Request theme={null}
curl -X POST https://api-sandbox.lumx.io/customers/{id}/associated-parties \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "INDIVIDUAL",
    "roles": ["SHAREHOLDER"],
    "parentId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "name": "John Smith",
    "birthDate": "1975-04-20",
    "email": "john.smith@fundabc.com",
    "taxId": "123-45-6789",
    "address": {
      "country": "USA",
      "line1": "456 Broadway",
      "city": "New York",
      "state": "NY",
      "postalCode": "10013"
    },
    "ownershipPercentage": 50
  }'
```

This creates the following structure:

```
Your Customer (Business)
└── Investment Fund ABC (Business Shareholder): 25%
    └── John Smith (Individual Shareholder): 50%
```

<Note>
  Associated parties nested under a shareholder (via `parentId`) can only have
  the `SHAREHOLDER` role. Other roles such as `UBO` and `REPRESENTATIVE` are
  only valid for top-level associated parties.
</Note>

You can repeat this pattern for as many levels as needed. Each associated party at every level requires its own documents and verification.

## Handling rejections

When a business receives `RFI`, the verification response includes details about what needs to be corrected:

```json theme={null}
{
  "customerId": "c85cb5ef-0574-4450-806d-195944f1e309",
  "status": "RFI",
  "level": "STANDARD",
  "statusReason": {
    "rejectLabels": ["screenshot", "unsatisfactory_photos"],
    "rejectSubLabels": ["proofOfAddress_listOfDocs", "badPhoto"],
    "documents": [
      {
        "type": "PASSPORT",
        "status": "RFI",
        "comment": "Screenshots aren't accepted. Please upload a live photo of the document.",
        "rejectLabels": ["screenshot", "unsatisfactory_photos"]
      }
    ]
  }
}
```

Re-upload the corrected documents and start a new verification.

<Warning>
  A `FINAL_REJECTION` is permanent. The customer cannot resubmit documents or be
  re-verified.
</Warning>

## Review timeline

Standard KYB verification is typically reviewed within 2 business days. See [Identity Verification](/compliance/identity-verification#verification-slas) for full details.

## Retrying verification for specific associated parties

When only some associated parties are rejected, you can retry verification for those parties in isolation. Pass `associatedPartyIds` in the request body when starting a verification:

```bash Request theme={null}
curl -X POST https://api-sandbox.lumx.io/customers/{id}/verifications \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "associatedPartyIds": [
      "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    ]
  }'
```

Only the listed associated parties are sent for verification again. The customer-level verification is not restarted, and any associated party not included in the list keeps its current verification status.

<Note>
  Resubmit any corrected documents/information for the affected associated parties before starting the retry. This option applies only to BUSINESS customers.
</Note>

## Related resources

<CardGroup cols="2">
  <Card title="Webhooks" href="/developer/webhooks">
    Receive real-time status updates.
  </Card>

  <Card title="Transaction Limits" href="/compliance/transaction-limits">
    Understand post-verification limits.
  </Card>

  <Card title="Identity Verification" href="/compliance/identity-verification">
    Full compliance requirements.
  </Card>
</CardGroup>
