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

# Onboard an entity by API

> Create an Entity for your client and complete its Know Your Customer review through the Fintoc API without using the dashboard, for platforms and marketplaces.

Use the API to create and onboard an `Entity` that can own `Account` objects after approval, without using the dashboard.

This flow is for platforms that create an `Entity` for each client, such as marketplaces or wallets that hold balances under each client's legal name. To create `Account` objects under your own root `Entity`, see [Create more accounts](/guides/transfers/manage-accounts/creating-more-accounts) instead.

<Info>
  **Availability**

  Onboarding by API supports Mexican `Entity` objects. For entities outside Mexico, create the `Entity` from the dashboard.
</Info>

```mermaid theme={null}
flowchart LR
    A[Create entity] --> B[Create onboarding]
    B --> C[Upload company documents]
    C --> D[Upload shareholder documents]
    D --> E[Submit for review]
    E -->|entity.onboarding.approved| F[Create accounts]
    E -->|entity.onboarding.rejected| B
```

## Before you start

You need a test secret key (`sk_test_...`). Find the key in the [dashboard](https://dashboard.fintoc.com/) under **Developers → API Keys**. Run the whole flow in `test` mode first, then switch to your `live` key.

## Step 1: Create the entity

An `Entity` is the legal account holder. Create one for your client with their legal name and Mexican tax ID (RFC). Set `country_code` to `mx`, and set `holder_id` to the client's RFC.

```bash theme={null}
curl --request POST \
     --url https://api.fintoc.com/v2/entities \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "country_code": "mx",
  "holder_name": "Test Entity 1",
  "holder_id": "AAA010101AAA"
}
'
```

```json Response theme={null}
{
  "id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
  "object": "entity",
  "country_code": "mx",
  "holder_id": "AAA010101AAA",
  "holder_name": "Test Entity 1",
  "is_root": false,
  "mode": "test",
  "status": "waiting_initialization"
}
```

Save the `Entity` ID (`ent_...`); every onboarding call uses this value. See [The Entity object](/api/transfers-api/entities/entity-object) for the full attribute list.

## Step 2: Create the onboarding

The `Onboarding` holds the Know Your Customer review for one `Entity`. The review includes company information, the legal representative, the transactional profile, and the shareholders. Create one onboarding per `Entity` and pass the structured data in the request.

```bash theme={null}
curl --request POST \
     --url https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "company_information": {
    "business_activity": "Servicios financieros",
    "business_address": "Av. Insurgentes 456, CDMX",
    "fiscal_address": "Av. Reforma 123, CDMX",
    "incorporation_date": "2020-01-15",
    "phone": "+521111111111",
    "settlement_account": "000000000000000000"
  },
  "legal_representative": {
    "first_name": "Test Customer 1",
    "last_name": "Customer",
    "email": "rep@example.com",
    "nationality": "mx",
    "identification_number": "AAAA010101HDFAAA01",
    "position": "Director General"
  },
  "transactional_profile": {
    "resource_origins": ["trusts", "investments"],
    "monthly_amount_range": "1_500000",
    "monthly_operations_range": "1_15000"
  },
  "shareholders": [
    {
      "type": "natural_person",
      "name": "Test Customer 2",
      "last_name": "Customer",
      "holder_id": "AAAA010101AAA",
      "nationality": "mx",
      "percentage": 60
    },
    {
      "type": "legal_entity",
      "name": "Test Entity 2",
      "holder_id": "AAA010101AAA",
      "nationality": "mx",
      "percentage": 40,
      "children": [
        {
          "type": "natural_person",
          "name": "Test Customer 3",
          "last_name": "Customer",
          "holder_id": "AAAA010101AAA",
          "nationality": "mx",
          "percentage": 80
        }
      ]
    }
  ]
}
'
```

```json Response theme={null}
{
  "id": "onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "object": "onboarding",
  "entity_id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
  "status": "in_progress",
  "source": "api",
  "submittable": false,
  "submitted_at": null,
  "reviewed_at": null,
  "data": {
    "company_information": {
      "business_activity": "Servicios financieros"
    }
  },
  "shareholders": [
    {
      "id": "onbsh_0ujsswThIGTUYm2K8FjOOfXtY1K",
      "object": "onboarding_shareholder",
      "type": "natural_person",
      "name": "Test Customer 2",
      "last_name": "Customer",
      "percentage": 60,
      "holder_id": "AAAA010101AAA",
      "parent_id": null,
      "document": { "slot_key": "identification", "status": "missing" }
    },
    {
      "id": "onbsh_8anBwgZktbZH6ydyHa6Tm0eM",
      "object": "onboarding_shareholder",
      "type": "legal_entity",
      "name": "Test Entity 2",
      "percentage": 40,
      "holder_id": "AAA010101AAA",
      "parent_id": null,
      "document": { "slot_key": "articles_of_incorporation", "status": "missing" }
    },
    {
      "id": "onbsh_9bnCxhAlucAI7zezIb7Un1fN",
      "object": "onboarding_shareholder",
      "type": "natural_person",
      "name": "Test Customer 3",
      "last_name": "Customer",
      "percentage": 80,
      "holder_id": "AAAA010101AAA",
      "parent_id": "onbsh_8anBwgZktbZH6ydyHa6Tm0eM",
      "document": { "slot_key": "identification", "status": "missing" }
    }
  ],
  "documents": [
    { "slot_key": "tax_registration_certificate", "status": "missing" },
    { "slot_key": "settlement_bank_statement", "status": "missing" },
    { "slot_key": "proof_of_address", "status": "missing" },
    { "slot_key": "representative_identification", "status": "missing" },
    { "slot_key": "representative_power_of_attorney", "status": "missing" },
    { "slot_key": "shareholder_structure", "status": "missing" }
  ]
}
```

Three details to note in the response:

* `submittable` is `false` until every required field and document is in place.
* `documents` lists each company document slot and its `status`, either `missing` or `uploaded`. Read this array to identify outstanding documents.
* Each shareholder has a `document` slot. A `legal_entity` shareholder can include nested `children`.

Some fields use Mexico-specific identifiers. The legal representative's `identification_number` is a Mexican Unique Population Registry Code (CURP). The `settlement_account` is an 18-digit standardized Mexican bank account number (CLABE). See [The Onboarding object](/api/transfers-api/onboardings/onboarding-object) for every field.

## Step 3: Upload the company documents

Upload one file to each company document slot in the `documents` array. Send the file as `multipart/form-data` in the `file` field. Each file must be a PDF, JPEG, or PNG. The maximum file size is 20 MB. Uploading to a slot that already has a file replaces the existing file.

```bash theme={null}
curl --request PUT \
     --url https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings/onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K/documents/tax_registration_certificate \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --form 'file=@tax_registration_certificate.pdf'
```

```json Response theme={null}
{
  "id": "onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "object": "onboarding",
  "documents": [
    {
      "slot_key": "tax_registration_certificate",
      "status": "uploaded",
      "filename": "tax_registration_certificate.pdf",
      "uploaded_at": "2026-01-15T14:30:00Z"
    }
  ]
}
```

Repeat for each remaining slot: `settlement_bank_statement`, `proof_of_address`, `representative_identification`, `representative_power_of_attorney`, and `shareholder_structure`.

## Step 4: Upload each shareholder's document

Each declared shareholder needs a document. Use the shareholder `id` (`onbsh_...`) from the Step 2 response. Upload `identification` for a `natural_person` shareholder. Upload `articles_of_incorporation` for a `legal_entity` shareholder. The file rules match Step 3.

```bash theme={null}
curl --request PUT \
     --url https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings/onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K/shareholders/onbsh_0ujsswThIGTUYm2K8FjOOfXtY1K/document \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --form 'file=@identification.pdf'
```

```json Response theme={null}
{
  "id": "onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "object": "onboarding",
  "shareholders": [
    {
      "id": "onbsh_0ujsswThIGTUYm2K8FjOOfXtY1K",
      "object": "onboarding_shareholder",
      "document": {
        "slot_key": "identification",
        "status": "uploaded",
        "filename": "identification.pdf",
        "uploaded_at": "2026-01-15T14:30:00Z"
      }
    }
  ]
}
```

## Step 5: Submit for review

Once `submittable` is `true`, submit the onboarding for Fintoc to review. The onboarding must be `in_progress` and include every required field and document. After submission, the onboarding moves to `submitted` and can no longer be modified.

```bash theme={null}
curl --request POST \
     --url https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings/onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K/submit \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json'
```

```json Response theme={null}
{
  "id": "onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "object": "onboarding",
  "entity_id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
  "status": "submitted",
  "source": "api",
  "submittable": true,
  "submitted_at": "2026-01-15T15:00:00Z",
  "reviewed_at": null
}
```

If a required field or document is missing, or the onboarding is no longer `in_progress`, the call returns a `422 Unprocessable Entity` error.

## Step 6: Track the review

An onboarding moves through `pending`, `in_progress`, `submitted`, and then `approved`, `rejected`, or `cancelled`. Fintoc sends one of these webhook events when it approves or rejects the onboarding:

| Event                        | Onboarding result                                    |
| :--------------------------- | :--------------------------------------------------- |
| `entity.onboarding.approved` | The `Entity` passed review and is ready to transact. |
| `entity.onboarding.rejected` | The review failed. Create a new onboarding to retry. |

Subscribe to these events in the dashboard under **Developers → Webhooks**, or poll the onboarding directly:

```bash theme={null}
curl --request GET \
     --url https://api.fintoc.com/v2/entities/ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN/onboardings/onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json'
```

```json Response theme={null}
{
  "id": "onbprc_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "object": "onboarding",
  "entity_id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
  "status": "approved",
  "source": "api",
  "submittable": true,
  "submitted_at": "2026-01-15T15:00:00Z",
  "reviewed_at": "2026-01-16T09:00:00Z"
}
```

Check `status` to track the onboarding. Once `status` is `approved`, the `Entity` is ready to transact.

## Step 7: Create accounts once approved

After the `Entity` is approved, create one or more `Account` objects under the `Entity`. Pass the `Entity` ID as `entity_id`. Each `Account` has its own balance and root account number. Outbound transfer receipts show the client's legal name. See [Create more accounts](/guides/transfers/manage-accounts/creating-more-accounts) for account creation details.

```bash theme={null}
curl --request POST \
     --url https://api.fintoc.com/v2/accounts \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "entity_id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
  "description": "Client settlement account"
}
'
```

```json Response theme={null}
{
  "id": "acc_8anBwgZktbZH6ydyHa6Tm0eM",
  "object": "account",
  "mode": "test",
  "description": "Client settlement account",
  "root_account_number": "000000000000000000",
  "root_account_number_id": "acno_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "available_balance": 0,
  "currency": "MXN",
  "entity": {
    "id": "ent_2daFu0zqqDtZGJaSi2TGI2Mm1nN",
    "holder_name": "Test Entity 1",
    "holder_id": "AAA010101AAA"
  }
}
```

## Test the integration

In `test` mode, run the full sequence above with your `sk_test_...` key. Create the `Entity` and onboarding, upload a sample file to every slot, and submit the onboarding. Confirm that `submittable` turns `true` only after every slot reports `uploaded`. Confirm that the onboarding reaches `submitted`, then track the review result as described in Step 6.

## What's next

* [Create more accounts](/guides/transfers/manage-accounts/creating-more-accounts) for an approved `Entity`.
* Review [The Onboarding object](/api/transfers-api/onboardings/onboarding-object) and [the onboarding endpoints](/api/transfers-api/onboardings/entities-onboardings-create) in the API reference.
