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

# Import client companies

> Add up to 1,000 client companies in one call

Adds many companies to your [client companies](/client-companies) at once, with
source `csv`. Send up to 1,000 rows per request; split a longer file into several
requests.

**Each row is checked on its own.** Valid rows are added, invalid rows come back
in `invalid` with their row number and the reason, and one bad row never blocks
the others. Every row needs a name and a LinkedIn company URL, following the same
rules as [Add a client company](/api-reference/add-client-company#linkedin-company-url).

**Re-running an import is safe.** A row whose LinkedIn company your manual or csv
rows already list is skipped and counted in `alreadyListed`, and so is a repeat of
the same company within one request.

## Body

<ParamField body="rows" type="object[]" required>
  At most 1,000.

  <Expandable title="fields">
    <ParamField body="row" type="integer">
      Your own row number, such as the spreadsheet line. Echoed back if the row is
      invalid so you can find it. When omitted, it is the row's position in `rows`,
      starting at 1.
    </ParamField>

    <ParamField body="name" type="string" required>Company name</ParamField>
    <ParamField body="linkedinUrl" type="string" required>LinkedIn company page URL</ParamField>
    <ParamField body="domain" type="string">A domain or website, stored as the registrable domain</ParamField>
  </Expandable>
</ParamField>

## Response

<ResponseField name="added" type="integer">Rows added to your list.</ResponseField>
<ResponseField name="alreadyListed" type="integer">Valid rows skipped because the company was already listed.</ResponseField>

<ResponseField name="invalid" type="object[]">
  Rows that were not imported. Each has `row` (your number) and `reason`, such as
  `That's a person's profile, not a company page` or `Company name is required`.
  When a row has both problems, the LinkedIn reason is the one reported.
</ResponseField>

## Errors

| Status | Code          | When                                                    |
| ------ | ------------- | ------------------------------------------------------- |
| 400    | `BAD_REQUEST` | The body is not valid JSON, or has more than 1,000 rows |

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.clustr-ai.com/api/public/client-companies/import \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"rows": [
          {"row": 2, "name": "Acme Corp", "linkedinUrl": "https://www.linkedin.com/company/acme-corp"},
          {"row": 3, "name": "Globex", "linkedinUrl": "https://www.linkedin.com/company/1035", "domain": "globex.com"},
          {"row": 4, "name": "Initech", "linkedinUrl": "https://www.linkedin.com/in/bill-lumbergh"}
        ]}'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "data": {
      "added": 1,
      "alreadyListed": 1,
      "invalid": [
        { "row": 4, "reason": "That's a person's profile, not a company page" }
      ]
    }
  }
  ```

  ```json 400 theme={null}
  {
    "success": false,
    "error": { "message": "Import at most 1000 rows per request", "code": "BAD_REQUEST" }
  }
  ```
</ResponseExample>
