> ## 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.

# List client companies

> Your client companies, one entry per company

Returns your [client companies](/client-companies), ordered by name.

**One item per company.** A company can be on your list more than once: added by
hand, imported from a CSV and marked in your CRM. Those rows are grouped into one
item, and each one appears in its `sources`. Rows are grouped by the Clustr
company they matched, else by LinkedIn numeric id, else by LinkedIn slug.

**Companies marked "Not a client" are included**, with `excluded: true` and the
`exclusionId` you need to [undo it](/api-reference/undo-not-a-client). They count
toward `total` here, but not in the [summary](/api-reference/get-client-companies-summary).

## Query parameters

<ParamField query="source" type="string">
  `manual`, `csv` or `crm`. Only companies with at least one row from that source.
  The item still lists all of its sources.
</ParamField>

<ParamField query="q" type="string">
  Case-insensitive search on the company name, LinkedIn slug or domain.
</ParamField>

<ParamField query="cursor" type="string">
  The `nextCursor` from the previous page. Leave it out for the first page.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Companies per page, from 1 to 200. Larger values are treated as 200.
</ParamField>

## Response

<ResponseField name="items" type="object[]">
  <Expandable title="fields">
    <ResponseField name="key" type="string">
      Identifies the item and stays the same across reads while its rows do not
      change: `c:<companyId>`, `n:<LinkedIn numeric id>`, `v:<LinkedIn slug>` or
      `r:<row id>`.
    </ResponseField>

    <ResponseField name="name" type="string">
      The name from the oldest manual or csv row, else from a CRM row.
    </ResponseField>

    <ResponseField name="linkedinUrl" type="string">LinkedIn company URL as entered. Empty when no row has one.</ResponseField>
    <ResponseField name="domain" type="string">Registrable domain, such as `acme.co.uk`. Empty when no row has one.</ResponseField>
    <ResponseField name="companyId" type="string">The Clustr company the rows matched. Empty when they matched none yet.</ResponseField>
    <ResponseField name="inNetwork" type="boolean">At least one person in your network currently works there.</ResponseField>
    <ResponseField name="excluded" type="boolean">The company is marked "Not a client".</ResponseField>
    <ResponseField name="exclusionId" type="string">The exclusion to delete to undo "Not a client". Empty when `excluded` is false.</ResponseField>

    <ResponseField name="sources" type="object[]">
      One entry per row behind the company.

      <Expandable title="fields">
        <ResponseField name="id" type="string">
          The row id. Use it to [remove](/api-reference/remove-client-company) a
          manual or csv row, or to [mark the company not a client](/api-reference/mark-not-a-client).
        </ResponseField>

        <ResponseField name="source" type="string">`manual`, `csv` or `crm`.</ResponseField>
        <ResponseField name="crmProvider" type="string">For a CRM row, the CRM, such as `hubspot`. Otherwise empty.</ResponseField>
        <ResponseField name="crmCompanyId" type="string">For a CRM row, the company's record id in that CRM. Otherwise empty.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="nextCursor" type="string">
  Pass as `cursor` for the next page. An empty string means this is the last page.
</ResponseField>

<ResponseField name="total" type="integer">
  Companies matching `source` and `q`, across all pages.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.clustr-ai.com/api/public/client-companies?source=crm&limit=50" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

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

  items, cursor = [], ""
  while True:
      page = requests.get(
          "https://api.clustr-ai.com/api/public/client-companies",
          headers={"Authorization": "Bearer YOUR_API_KEY"},
          params={"limit": 200, "cursor": cursor},
      ).json()["data"]
      items += page["items"]
      cursor = page["nextCursor"]
      if not cursor:
          break
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "data": {
      "items": [
        {
          "key": "c:5b1f7c2e-8d0a-4c47-9d3e-2f6a1b9c0e11",
          "name": "Acme Corp",
          "linkedinUrl": "https://www.linkedin.com/company/acme-corp",
          "domain": "acme.com",
          "companyId": "5b1f7c2e-8d0a-4c47-9d3e-2f6a1b9c0e11",
          "inNetwork": true,
          "excluded": false,
          "exclusionId": "",
          "sources": [
            { "id": "0e7d6a52-...", "source": "manual", "crmProvider": "", "crmCompanyId": "" },
            { "id": "a3c9f1b4-...", "source": "crm", "crmProvider": "hubspot", "crmCompanyId": "18823401776" }
          ]
        }
      ],
      "nextCursor": "50",
      "total": 128
    }
  }
  ```

  ```json 400 theme={null}
  {
    "success": false,
    "error": { "message": "source must be manual, csv or crm", "code": "BAD_REQUEST" }
  }
  ```

  ```json 401 theme={null}
  {
    "success": false,
    "error": { "message": "Invalid or missing API key", "code": "UNAUTHORIZED" }
  }
  ```
</ResponseExample>
