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

# Preview Competitors

> Check LinkedIn company URLs, the people found and the slots needed, before adding competitors

Check one or more LinkedIn company URLs before you [register them](https://docs.clustr-ai.com/api-reference/register-competitor.md).
Nothing is created. For each URL Clustr says:

* which company page it resolves to: name, logo, domain and headcount;
* whether that company is already one of your competitors, with its id (`existing_competitor_id`);
* how many Sales and CS people the team search finds there (`people_found`), read from the first
  page of the search, which reports the total;
* the first page of those people (`people`: `public_identifier`, `name`, `title`, `photo_url`,
  `function` and `group`), to follow or skip when you register. `group` is the role group of the
  person's title in your title list (`sales`, `cs`, `exec`, `founder`, `customer_facing`), the
  same groups `title_groups` takes; `custom` when no title in your list matches;
* how many slots those people would take (`slots_needed`, at most 200 per competitor).

The totals add up the new companies and compare them with your free slots. Each monitored person
takes one slot, whatever the competitor. When a batch needs more slots than are free, the people
beyond the free slots are added **Paused (no slot)**, and you choose later who to monitor.

A URL that is a person's profile (`linkedin.com/in/...`) answers `status: "person_profile"` with the
message "That's a person's profile, not a company page". The other URLs are checked anyway.

Clustr keeps the people count for 24 hours, so registering right after the preview reuses the
same search instead of paying for it twice.

## Response

Each entry of `companies` has `status`:

| Status | Meaning |
| - | - |
| `ok` | Resolved. `people_found` and `slots_needed` are set. |
| `invalid_url` | Not a LinkedIn company URL. |
| `person_profile` | A person's profile, not a company page. |
| `not_found` | No LinkedIn company page answers to it. |
| `error` | LinkedIn could not be reached. Try again. |

`slots_needed` is 0 for a company that is already registered (`already_registered: true`).

```bash cURL theme={null}
curl -X POST https://api.clustr-ai.com/api/public/competitors/preview \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "urls": ["https://www.linkedin.com/company/globex", "https://www.linkedin.com/in/jane-doe"] }'
```

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

requests.post(
    "https://api.clustr-ai.com/api/public/competitors/preview",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"urls": ["https://www.linkedin.com/company/globex", "https://www.linkedin.com/in/jane-doe"]},
)
```

```javascript JavaScript theme={null}
await fetch("https://api.clustr-ai.com/api/public/competitors/preview", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    urls: ["https://www.linkedin.com/company/globex", "https://www.linkedin.com/in/jane-doe"],
  }),
});
```

```json 200 theme={null}
{
  "success": true,
  "data": {
    "companies": [
      {
        "clustr_existing_competitor_id": null,
        "clustr_account_id": "acc_0v7tgcp9dspw8x9zc6teb5qx8z",
        "input": "https://www.linkedin.com/company/globex",
        "status": "ok",
        "name": "Globex Inc",
        "logo": "https://media.licdn.com/dms/image/globex.png",
        "domain": "globex.com",
        "employee_count": 420,
        "linkedin_url": "https://www.linkedin.com/company/globex",
        "linkedin_numeric_id": "1035",
        "linkedin_vanity_name": "globex",
        "already_registered": false,
        "existing_competitor_id": null,
        "people_found": 37,
        "slots_needed": 37
      },
      {
        "clustr_existing_competitor_id": null,
        "input": "https://www.linkedin.com/in/jane-doe",
        "status": "person_profile",
        "message": "That's a person's profile, not a company page",
        "already_registered": false,
        "existing_competitor_id": null,
        "people_found": null,
        "slots_needed": 0
      }
    ],
    "slots_needed": 37,
    "slots_free": 18,
    "slot_usage": { "used": 182, "total": 200, "paused": 4, "pending": 2, "plan": "l200", "active": 182, "limit": 200 }
  }
}
```


## OpenAPI

````yaml POST /competitors/preview
openapi: 3.1.0
info:
  title: Clustr Public API
  description: >
    Programmatic access to your Clustr network: import connectors, search warm
    intros (opportunities), and manage target accounts.


    ## Authentication

    All endpoints require a Bearer token (API key) in the `Authorization`
    header.


    ```

    Authorization: Bearer <your_api_key>

    ```


    API keys can be created and managed from the [API settings
    page](https://app.clustr-ai.com/api).
  version: '1.0'
  contact:
    name: Clustr Support
    url: https://clustr-ai.com
servers:
  - url: https://api.clustr-ai.com/api/public
    description: Production
security:
  - BearerAuth: []
paths:
  /competitors/preview:
    post:
      tags:
        - Competitor Monitoring
      summary: Preview Competitors
      description: >
        Check LinkedIn company URLs before adding them: the company each
        resolves to,

        whether it is already registered, the Sales and CS people found and the
        slots they

        would take. The preview saves nothing; register the competitors with
        Register

        Competitor.
      operationId: previewCompetitors
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - urls
              properties:
                urls:
                  type: array
                  description: >-
                    One to 20 LinkedIn company page URLs
                    (`https://www.linkedin.com/company/...`).
                  minItems: 1
                  maxItems: 20
                  items:
                    type: string
                  example:
                    - https://www.linkedin.com/company/globex
                title_groups:
                  type: array
                  description: >-
                    The roles to search for: `sales`, `cs`, `exec`, `founder`,
                    `customer_facing` and `custom`. Omit

                    for your enabled job titles.
                  items:
                    type: string
                    enum:
                      - sales
                      - cs
                      - exec
                      - founder
                      - customer_facing
                      - custom
                  example:
                    - sales
                    - cs
                max_people:
                  type: integer
                  minimum: 0
                  maximum: 200
                  description: >-
                    How many people to return per company. The search reads page
                    after page until

                    it has them; each page holds about 10. Omit for the first
                    page.
                  example: 50
      responses:
        '200':
          description: One entry per URL, plus the slots they would take
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      companies:
                        type: array
                        items:
                          $ref: '#/components/schemas/CompetitorPreviewCompany'
                      slots_needed:
                        type: integer
                        example: 37
                      slots_free:
                        type: integer
                        example: 18
                      slot_usage:
                        $ref: '#/components/schemas/SlotUsage'
        '400':
          description: No URL, or more than 20
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Invalid or missing API key
        '403':
          description: Competitor monitoring is not enabled for this workspace
components:
  schemas:
    CompetitorPreviewCompany:
      type: object
      description: One URL checked by Preview Competitors.
      properties:
        clustr_account_id:
          type: string
          description: >-
            The company's Clustr ID, for example
            `acc_4tkr2a2rt899w35g86q9npspy4`.
          example: acc_4tkr2a2rt899w35g86q9npspy4
        clustr_existing_competitor_id:
          type: string
          description: >-
            The Clustr ID of the competitor you already track for this company,
            for example

            `cmp_jzcjcqwb4r950371sc8nayrcqb`.
          example: cmp_jzcjcqwb4r950371sc8nayrcqb
        input:
          type: string
          description: The URL as sent.
        status:
          type: string
          enum:
            - ok
            - invalid_url
            - person_profile
            - not_found
            - error
        message:
          type: string
          example: That's a person's profile, not a company page
        name:
          type: string
          example: Globex Inc
        logo:
          type: string
        domain:
          type: string
          example: globex.com
        employee_count:
          type: integer
          example: 420
        linkedin_url:
          type: string
        linkedin_numeric_id:
          type: string
        linkedin_vanity_name:
          type: string
        already_registered:
          type: boolean
        existing_competitor_id:
          type: string
          nullable: true
          description: >-
            Kept for integrations built before Clustr IDs. New integrations
            should use `clustr_existing_competitor_id`.
        people_found:
          type: integer
          nullable: true
          description: >-
            How many Sales and CS people the team search finds. Null when
            unknown.
          example: 37
        slots_needed:
          type: integer
          description: >-
            How many slots those people would take. 0 when the competitor is
            already registered or `status` is other than `ok`.
          example: 37
        people:
          type: array
          description: >-
            The first page of the people search, to follow or skip when
            registering. Omitted when the search has not run.
          items:
            $ref: '#/components/schemas/CompetitorPreviewPerson'
    SlotUsage:
      type: object
      description: >-
        Your competitor monitoring slots. Each monitored person takes one slot,
        whatever the competitor. The limit comes from your workspace's plan,
        which Clustr sets.
      properties:
        used:
          type: integer
          description: How many people are monitored.
          example: 182
        total:
          type: integer
          description: The slot limit.
          example: 200
        paused:
          type: integer
          description: How many people are paused, for lack of a slot or manually.
          example: 12
        pending:
          type: integer
          description: How many joiners are waiting for you to validate them.
          example: 3
        plan:
          type: string
          enum:
            - s50
            - m100
            - l200
            - custom
          example: l200
        active:
          type: integer
          description: The same count as `used`.
          example: 182
        limit:
          type: integer
          description: The same limit as `total`.
          example: 200
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            message:
              type: string
              example: Invalid request body
            code:
              type: string
              example: BAD_REQUEST
    CompetitorPreviewPerson:
      type: object
      description: One person the setup search found at a competitor.
      properties:
        clustr_person_id:
          type: string
          description: >-
            The person's Clustr ID, for example
            `per_804sj4q4892mgd7mwsenp59vnh`.
          example: per_804sj4q4892mgd7mwsenp59vnh
        linkedin_url:
          type: string
          example: https://www.linkedin.com/in/jane-smith
        public_identifier:
          type: string
          description: >-
            The profile's handle. Pass it as `people[].linkedin_id` to Register
            Competitor.
          example: jane-smith
        name:
          type: string
          example: Jane Smith
        title:
          type: string
          example: Account Executive
        photo_url:
          type: string
        function:
          type: string
          enum:
            - sales
            - cs
            - other
          example: sales
        group:
          type: string
          enum:
            - sales
            - cs
            - exec
            - founder
            - customer_facing
            - custom
          description: >-
            The role group of the title in your title list that gives
            `function`; `custom` when none matches.
          example: sales
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: The API key you created on the API settings page of the Clustr app.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.