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

# Ingest KYC/KYB Client Data

> Step-by-step guide for ingesting Individual and Corporate clients into the Corsa compliance platform.

This guide walks you through ingesting client data into Corsa. Clients are the foundation of your compliance data - all transactions, alerts, and cases are linked back to them.

Full API endpoint details are available in the [API Reference](https://api.corsa.finance/api-spec.json) (requires API credentials).

<Note>
  All SDK examples on this page assume you have initialized the Corsa client as shown in the [Node.js SDK Configuration](/sdk/configuration) or [Python SDK Configuration](/sdk/python-configuration) guide.
</Note>

***

## Overview

Corsa supports two types of clients:

* **Individuals** - Natural persons (retail customers).
* **Corporates** - Legal entities (businesses, organizations).

Both types support **upsert** behavior: if a client with the same `referenceId` already exists, it will be updated instead of duplicated.

***

## Step 1: Prepare Your Client Data

Before calling the API, gather the required data for each client type.

### Individual Clients

| Category                 | Fields                                                                            |
| ------------------------ | --------------------------------------------------------------------------------- |
| **Personal Information** | Name, Date of Birth, Gender, Citizenship                                          |
| **Documents**            | Passport, Driver's License, etc. (managed via identity verification integrations) |
| **Address**              | Residential address                                                               |
| **Contact Details**      | Email, Phone Number                                                               |

### Corporate Clients

| Category           | Fields                                                                                  |
| ------------------ | --------------------------------------------------------------------------------------- |
| **Entity Details** | Legal Name, Registration Number, Date of Incorporation                                  |
| **Business Info**  | Industry, Business Type, Description                                                    |
| **Structure**      | Ownership type, Complexity                                                              |
| **Members**        | Associated Members (Individual or Corporate) who act as UBOs, Directors, or Signatories |

***

## Step 2: Ingest Individual Clients

**Endpoint:** `POST /v1/clients/individuals`

Use the `upsert=true` query parameter to update an existing client if they already exist (matched by `referenceId`).

<CodeGroup>
  ```json REST API theme={null}
  POST /v1/clients/individuals?upsert=true
  Content-Type: application/json

  {
    "referenceId": "USER-12345",
    "accountStatus": "APPROVED",
    "activityStatus": "ACTIVE",
    "general": {
      "firstName": "John",
      "lastName": "Doe",
      "dateOfBirth": "1985-06-15",
      "citizenship": "USA",
      "personalId": "123-45-6789",
      "gender": "MALE"
    },
    "address": {
      "addressLine1": "123 Main St",
      "city": "New York",
      "country": "USA",
      "postalCode": "10001"
    },
    "contact": {
      "emailAddress": "john.doe@example.com",
      "phoneNumber": "+1-555-0199"
    },
    "tags": ["retail", "high-volume"]
  }
  ```

  ```typescript Javascript theme={null}
  const individual = await corsa.clients.createIndividualClient(
    {
      referenceId: "USER-12345",
      accountStatus: "APPROVED",
      activityStatus: "ACTIVE",
      general: {
        firstName: "John",
        lastName: "Doe",
        dateOfBirth: "1985-06-15",
        citizenship: "USA",
        personalId: "123-45-6789",
        gender: "MALE",
      },
      address: {
        addressLine1: "123 Main St",
        city: "New York",
        country: "USA",
        postalCode: "10001",
      },
      contact: {
        emailAddress: "john.doe@example.com",
        phoneNumber: "+1-555-0199",
      },
      tags: ["retail", "high-volume"],
    },
    true // upsert
  );
  ```

  ```python Python theme={null}
  from corsa_sdk.api.clients.create_individual_client import _get_kwargs
  from corsa_sdk.models.create_individual_client_dto import CreateIndividualClientDto
  from corsa_sdk.models.individual_client_general_information_dto import IndividualClientGeneralInformationDto
  from corsa_sdk.models.individual_client_address_dto import IndividualClientAddressDto
  from corsa_sdk.models.individual_client_contact_information_dto import IndividualClientContactInformationDto

  resp = http.request(**_get_kwargs(
      body=CreateIndividualClientDto(
          reference_id="USER-12345",
          account_status="APPROVED",
          activity_status="ACTIVE",
          general=IndividualClientGeneralInformationDto(
              first_name="John",
              last_name="Doe",
              date_of_birth="1985-06-15",
              citizenship="USA",
              personal_id="123-45-6789",
              gender="MALE",
          ),
          address=IndividualClientAddressDto(
              address_line1="123 Main St",
              city="New York",
              country="USA",
              postal_code="10001",
          ),
          contact=IndividualClientContactInformationDto(
              email_address="john.doe@example.com",
              phone_number="+1-555-0199",
          ),
          tags=["retail", "high-volume"],
      ),
      upsert=True,
  ))
  individual = resp.json()
  ```
</CodeGroup>

The response will include the Corsa-generated client `id` - save this for linking transactions and alerts later.

***

## Step 3: Ingest Corporate Clients

**Endpoint:** `POST /v1/clients/corporates`

Use this endpoint to onboard business entities.

<CodeGroup>
  ```json REST API theme={null}
  POST /v1/clients/corporates?upsert=true
  Content-Type: application/json

  {
    "referenceId": "CORP-98765",
    "accountStatus": "APPROVED",
    "activityStatus": "ACTIVE",
    "general": {
      "legalEntityName": "Acme Innovations LLC",
      "dateOfIncorporation": "2018-04-12",
      "countryOfIncorporation": "USA"
    },
    "business": {
      "industry": "Technology",
      "description": "SaaS provider for financial services",
      "businessType": "FINANCIAL_INSTITUTIONS",
      "incorporationType": "LIMITED_LIABILITY_COMPANY"
    },
    "address": {
      "registrationAddress": {
        "addressLine1": "456 Tech Park Blvd",
        "city": "Austin",
        "country": "USA",
        "postalCode": "73301"
      }
    },
    "tags": ["enterprise", "saas"]
  }
  ```

  ```typescript Javascript theme={null}
  const corporate = await corsa.clients.createCorporateClient(
    {
      referenceId: "CORP-98765",
      accountStatus: "APPROVED",
      activityStatus: "ACTIVE",
      general: {
        legalEntityName: "Acme Innovations LLC",
        dateOfIncorporation: "2018-04-12",
        countryOfIncorporation: "USA",
      },
      business: {
        industry: "Technology",
        description: "SaaS provider for financial services",
        businessType: "FINANCIAL_INSTITUTIONS",
        incorporationType: "LIMITED_LIABILITY_COMPANY",
      },
      address: {
        registrationAddress: {
          addressLine1: "456 Tech Park Blvd",
          city: "Austin",
          country: "USA",
          postalCode: "73301",
        },
      },
      tags: ["enterprise", "saas"],
    },
    true // upsert
  );
  ```

  ```python Python theme={null}
  from corsa_sdk.api.clients.create_corporate_client import _get_kwargs
  from corsa_sdk.models.create_corporate_client_dto import CreateCorporateClientDto

  resp = http.request(**_get_kwargs(
      body=CreateCorporateClientDto(
          reference_id="CORP-98765",
          account_status="APPROVED",
          activity_status="ACTIVE",
          general={"legalEntityName": "Acme Innovations LLC", "dateOfIncorporation": "2018-04-12", "countryOfIncorporation": "USA"},
          business={"industry": "Technology", "description": "SaaS provider for financial services", "businessType": "FINANCIAL_INSTITUTIONS", "incorporationType": "LIMITED_LIABILITY_COMPANY"},
          address={"registrationAddress": {"addressLine1": "456 Tech Park Blvd", "city": "Austin", "country": "USA", "postalCode": "73301"}},
          tags=["enterprise", "saas"],
      ),
      upsert=True,
  ))
  corporate = resp.json()
  ```
</CodeGroup>

***

## Step 4: Retrieve a Client

Use the GET endpoints to fetch client data by their Corsa-generated ID.

### Get an Individual Client

**Endpoint:** `GET /v1/clients/individuals/{clientId}`

<CodeGroup>
  ```bash REST API theme={null}
  GET /v1/clients/individuals/client-uuid-123
  ```

  ```typescript Javascript theme={null}
  const individual = await corsa.clients.getIndividualClient("client-uuid-123");
  ```

  ```python Python theme={null}
  from corsa_sdk.api.clients.get_individual_client import _get_kwargs

  resp = http.request(**_get_kwargs(client_id="client-uuid-123"))
  individual = resp.json()
  ```
</CodeGroup>

### Get a Corporate Client

**Endpoint:** `GET /v1/clients/corporates/{clientId}`

<CodeGroup>
  ```bash REST API theme={null}
  GET /v1/clients/corporates/client-uuid-456
  ```

  ```typescript Javascript theme={null}
  const corporate = await corsa.clients.getCorporateClient("client-uuid-456");
  ```

  ```python Python theme={null}
  from corsa_sdk.api.clients.get_corporate_client import _get_kwargs

  resp = http.request(**_get_kwargs(client_id="client-uuid-456"))
  corporate = resp.json()
  ```
</CodeGroup>

***

## Step 5: Update a Client

Use the PUT endpoints to update existing client data. All fields are optional on update - only include the fields you want to change.

### Update an Individual Client

**Endpoint:** `PUT /v1/clients/individuals/{clientId}`

<CodeGroup>
  ```json REST API theme={null}
  PUT /v1/clients/individuals/client-uuid-123
  Content-Type: application/json

  {
    "general": {
      "firstName": "John",
      "lastName": "Doe-Smith"
    },
    "contact": {
      "emailAddress": "john.doesmith@example.com"
    },
    "accountStatus": "APPROVED",
    "activityStatus": "ACTIVE"
  }
  ```

  ```typescript Javascript theme={null}
  const updated = await corsa.clients.updateIndividualClient(
    "client-uuid-123",
    {
      general: {
        firstName: "John",
        lastName: "Doe-Smith",
      },
      contact: {
        emailAddress: "john.doesmith@example.com",
      },
      accountStatus: "APPROVED",
      activityStatus: "ACTIVE",
    }
  );
  ```

  ```python Python theme={null}
  from corsa_sdk.api.clients.update_individual_client import _get_kwargs
  from corsa_sdk.models.update_individual_client_dto import UpdateIndividualClientDto
  from corsa_sdk.models.individual_client_general_information_dto import IndividualClientGeneralInformationDto
  from corsa_sdk.models.individual_client_contact_information_dto import IndividualClientContactInformationDto

  resp = http.request(**_get_kwargs(
      client_id="client-uuid-123",
      body=UpdateIndividualClientDto(
          general=IndividualClientGeneralInformationDto(
              first_name="John",
              last_name="Doe-Smith",
          ),
          contact=IndividualClientContactInformationDto(
              email_address="john.doesmith@example.com",
          ),
      ),
  ))
  updated = resp.json()
  ```
</CodeGroup>

### Update a Corporate Client

**Endpoint:** `PUT /v1/clients/corporates/{clientId}`

<CodeGroup>
  ```json REST API theme={null}
  PUT /v1/clients/corporates/client-uuid-456
  Content-Type: application/json

  {
    "activityStatus": "ACTIVE",
    "accountStatus": "APPROVED",
    "business": {
      "industry": "Financial Services",
      "description": "Updated business description"
    }
  }
  ```

  ```typescript Javascript theme={null}
  const updated = await corsa.clients.updateCorporateClient(
    "client-uuid-456",
    {
      activityStatus: "ACTIVE",
      accountStatus: "APPROVED",
      business: {
        industry: "Financial Services",
        description: "Updated business description",
      },
    }
  );
  ```

  ```python Python theme={null}
  from corsa_sdk.api.clients.update_corporate_client import _get_kwargs
  from corsa_sdk.models.update_corporate_client_dto import UpdateCorporateClientDto

  resp = http.request(**_get_kwargs(
      client_id="client-uuid-456",
      body=UpdateCorporateClientDto(
          activity_status="ACTIVE",
          account_status="APPROVED",
      ),
  ))
  updated = resp.json()
  ```
</CodeGroup>

***

## Step 6: Bulk Update Clients

Apply the same field changes to up to 100 clients in a single request. Use this when you need to update risk assessments, statuses, or screening results across a group of clients at once.

### Bulk Update Individual Clients

**Endpoint:** `PATCH /v1/clients/individuals/bulk/update`

<CodeGroup>
  ```json REST API theme={null}
  PATCH /v1/clients/individuals/bulk/update
  Content-Type: application/json

  {
    "clientIds": ["client-uuid-001", "client-uuid-002", "client-uuid-003"],
    "update": {
      "accountStatus": "FROZEN",
      "currentRisk": {
        "score": 90,
        "level": "HIGH",
        "reason": "Periodic review triggered elevated risk score"
      }
    }
  }
  ```

  ```typescript Javascript theme={null}
  const result = await corsa.clients.bulkUpdateIndividualClients({
    clientIds: ["client-uuid-001", "client-uuid-002", "client-uuid-003"],
    update: {
      accountStatus: "FROZEN",
      currentRisk: {
        score: 90,
        level: "HIGH",
        reason: "Periodic review triggered elevated risk score",
      },
    },
  });
  ```
</CodeGroup>

### Bulk Update Corporate Clients

**Endpoint:** `PATCH /v1/clients/corporates/bulk/update`

<CodeGroup>
  ```json REST API theme={null}
  PATCH /v1/clients/corporates/bulk/update
  Content-Type: application/json

  {
    "clientIds": ["corp-uuid-001", "corp-uuid-002"],
    "update": {
      "sanctionsStatus": "FLAGGED",
      "tagsToAdd": ["under-review"],
      "tagsToRemove": ["clear"]
    }
  }
  ```

  ```typescript Javascript theme={null}
  const result = await corsa.clients.bulkUpdateCorporateClients({
    clientIds: ["corp-uuid-001", "corp-uuid-002"],
    update: {
      sanctionsStatus: "FLAGGED",
      tagsToAdd: ["under-review"],
      tagsToRemove: ["clear"],
    },
  });
  ```
</CodeGroup>

### Bulk Update Request Fields

| Field                       | Required | Description                                                                                                                                             |
| --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clientIds`                 | Yes      | Array of client IDs or `referenceId`s to update (maximum 100).                                                                                          |
| `update`                    | Yes      | Fields to apply to every client in the list.                                                                                                            |
| `update.accountStatus`      | No       | `APPROVED`, `WAITING_FOR_REVIEW`, `IN_REVIEW`, `REJECTED`, `OFF_BOARDED`, `FROZEN`, `PENDING_DOCUMENTS`, `CLOSED_BY_CLIENT`, `APPLICATION_IN_PROGRESS`. |
| `update.activityStatus`     | No       | `ACTIVE` or `NOT_ACTIVE`.                                                                                                                               |
| `update.sanctionsStatus`    | No       | `CLEAR`, `FLAGGED`, `UNDER_REVIEW`, `NOT_CHECKED`.                                                                                                      |
| `update.pepStatus`          | No       | `CLEAR`, `FLAGGED`, `UNDER_REVIEW`, `NOT_CHECKED`.                                                                                                      |
| `update.adverseMediaStatus` | No       | `CLEAR`, `FLAGGED`, `UNDER_REVIEW`, `NOT_CHECKED`.                                                                                                      |
| `update.currentRisk`        | No       | Risk assessment object (`score`, `level`, `reason`, `calculatedAt`).                                                                                    |
| `update.tagsToAdd`          | No       | Tags to add (additive — existing tags are preserved).                                                                                                   |
| `update.tagsToRemove`       | No       | Tags to remove.                                                                                                                                         |
| `update.customFields`       | No       | Key-value custom fields.                                                                                                                                |

### Bulk Update Response

```json theme={null}
{
  "updatedClients": [
    { "id": "client-uuid-001", "referenceId": "USER-001", "appliedChanges": { "accountStatus": "FROZEN" } },
    { "id": "client-uuid-002", "referenceId": "USER-002", "appliedChanges": { "accountStatus": "FROZEN" } }
  ],
  "failedClients": [],
  "totalProcessed": 3,
  "successCount": 2,
  "failureCount": 0
}
```

The response includes a per-client breakdown so you can identify any partial failures without re-querying each record individually.

***

## Step 7: Enable Automatic Risk Model

**Endpoints:**

* `PUT /v1/clients/individuals/{clientId}/current-risk/enable-auto-model`
* `PUT /v1/clients/corporates/{clientId}/current-risk/enable-auto-model`

Switch a client to automatic, model-driven risk scoring. Once enabled, Corsa's risk model continuously recalculates the client's risk score based on their activity and data signals — removing the need to push manual `currentRisk` updates.

<CodeGroup>
  ```json REST API theme={null}
  PUT /v1/clients/individuals/client-uuid-123/current-risk/enable-auto-model
  Content-Type: application/json

  {
    "reason": "Client graduated from manual risk review process"
  }
  ```

  ```typescript Javascript theme={null}
  // Enable for an individual client
  await fetch(
    `${BASE_URL}/v1/clients/individuals/client-uuid-123/current-risk/enable-auto-model`,
    {
      method: "PUT",
      headers: {
        Authorization: `Bearer ${API_TOKEN}:${API_SECRET}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ reason: "Client graduated from manual risk review process" }),
    }
  );

  // Enable for a corporate client
  await fetch(
    `${BASE_URL}/v1/clients/corporates/corp-uuid-456/current-risk/enable-auto-model`,
    {
      method: "PUT",
      headers: {
        Authorization: `Bearer ${API_TOKEN}:${API_SECRET}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({}),
    }
  );
  ```

  ```python Python theme={null}
  import httpx

  client_http = httpx.Client(base_url="https://api.corsa.finance")
  client_http.put(
      f"/v1/clients/individuals/client-uuid-123/current-risk/enable-auto-model",
      headers={"Authorization": f"Bearer {API_TOKEN}:{API_SECRET}"},
      json={"reason": "Client graduated from manual risk review process"},
  )
  ```
</CodeGroup>

| Field    | Required | Description                                                    |
| -------- | -------- | -------------------------------------------------------------- |
| `reason` | No       | Optional audit note explaining why automatic risk was enabled. |

***

## What's Next?

Once your clients are ingested, add their members, accounts, and transactional data.

<CardGroup cols={3}>
  <Card title="Ingest Members" icon="user-group" href="/api/ingesting-members">
    Add UBOs, directors, and signatories to corporate clients.
  </Card>

  <Card title="Accounts & Wallets" icon="building-columns" href="/api/ingesting-accounts-and-wallets">
    Ingest bank accounts and blockchain wallets.
  </Card>

  <Card title="Ingest Operations" icon="arrow-right-arrow-left" href="/api/ingesting-operations">
    Ingest deposits, withdrawals, and trades.
  </Card>
</CardGroup>
