> ## 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 Competitor Team Refreshes

> What each monthly team refresh found at a competitor

Every month, before collecting a competitor's activity, Clustr searches its Sales and CS team
again for newcomers, then checks the LinkedIn profile of **every** monitored and paused person on
the [Team](https://docs.clustr-ai.com/api-reference/list-competitor-team.md), whether or not the search still finds them:

* **Joiners**: people the search found who were not on the Team. They are added as to
  validate and take no slot until someone monitors them.
* **Leavers**: people whose LinkedIn profile now shows another employer. They are marked Left
  the company with their new company, their slot is freed, and their past activity stays.
* **Role changes**: people still at the competitor whose current title is no longer a Sales or
  CS title. They stay monitored and are flagged so you can keep or remove them.

Nobody is marked on doubt. A profile that cannot be read, shows no current position, or names a
company Clustr cannot match is counted in `unconfirmed` and checked again three days later, up to
three times a month. People a refresh did not reach before its time ran out, or could not check
because its search failed, are counted in `deferred` and checked within the hour. Those follow-up
checks are listed here too, with `origin: "recheck"`; they search nothing, so they have no
joiners. `profiles_checked` is how many profiles each pass read.

Each entry lists the three counts and the names behind them, newest first. A refresh runs at the
start of the scheduled collection it rides on, once a month (`origin: "run"`) or when you
[run one now](https://docs.clustr-ai.com/api-reference/run-competitor-team-refresh.md) (`origin: "manual"`). A refresh whose
search failed has `status: "failed"` and an `error` code: `SEARCH_FAILED`, `SEARCH_EMPTY` (the
search found nobody), `SEARCH_DEGRADED` or `ABANDONED`. Its profile checks still happen, in the
recheck.

```bash cURL theme={null}
curl https://api.clustr-ai.com/api/public/competitors/cmp_r0jpyyqyeh0txpgdhb604j2g9s/team-refreshes \
  -H "Authorization: Bearer YOUR_API_KEY"
```

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

requests.get(
    "https://api.clustr-ai.com/api/public/competitors/cmp_r0jpyyqyeh0txpgdhb604j2g9s/team-refreshes",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
```

```javascript JavaScript theme={null}
await fetch("https://api.clustr-ai.com/api/public/competitors/cmp_r0jpyyqyeh0txpgdhb604j2g9s/team-refreshes", {
  headers: { Authorization: "Bearer YOUR_API_KEY" },
});
```

```json 200 theme={null}
{
  "success": true,
  "data": {
    "refreshes": [
      {
        "clustr_competitor_team_refresh_id": "ctr_wwwbbvg5sws305swx1rybwdrw2",
        "clustr_competitor_id": "cmp_r0jpyyqyeh0txpgdhb604j2g9s",
        "clustr_run_id": "crun_xzjxypt9zx42h7xxe39c620dme",
        "id": "8b1f2c3d-4e5f-4a6b-9c7d-0e1f2a3b4c5d",
        "competitor_id": "c1a2b3c4-d5e6-7890-abcd-ef1234567890",
        "run_id": "2f4e6a8c-0b1d-4c3e-8f5a-7b9c1d3e5f70",
        "origin": "run",
        "status": "completed",
        "started_at": "2026-11-02T06:00:04Z",
        "finished_at": "2026-11-02T06:03:41Z",
        "joiners": 3,
        "leavers": 1,
        "function_changes": 0,
        "joiner_names": ["Sam Lee", "Priya Nair", "Tom Becker"],
        "leaver_names": ["Jane Doe"],
        "function_change_names": [],
        "profiles_checked": 42,
        "unconfirmed": 2,
        "deferred": 0,
        "error": null,
        "notified_at": "2026-11-02T06:05:00Z"
      }
    ]
  }
}
```


## OpenAPI

````yaml GET /competitors/{id}/team-refreshes
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/{id}/team-refreshes:
    get:
      tags:
        - Competitor Monitoring
      summary: List Competitor Team Refreshes
      description: >-
        Lists the competitor's team refreshes, newest first. Once a month, a
        scheduled refresh searches the competitor's Sales and CS team again and
        adds new people with the status To validate (`pending`). It then checks
        the LinkedIn profile of every monitored and paused person: people who
        left are marked Left the company, and people now in a role outside Sales
        and CS are flagged. A profile that cannot be placed is checked again
        three days later, up to three times a month, and people a refresh did
        not reach in time are checked within the hour. Those rechecks are listed
        too, with `origin: "recheck"`.
      operationId: listCompetitorTeamRefreshes
      parameters:
        - name: id
          in: path
          required: true
          description: >-
            The competitor's Clustr ID (`cmp_…`), from [List
            Competitors](/api-reference/list-competitors).

            The id from earlier responses also works.
          schema:
            type: string
          example: cmp_npzx94r6v4wa97cvw15fefe2yz
        - name: limit
          in: query
          description: >-
            The maximum number of refreshes to return, from 1 to 100. Defaults
            to 12.
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        '200':
          description: The refreshes
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      refreshes:
                        type: array
                        items:
                          $ref: '#/components/schemas/CompetitorTeamRefresh'
        '401':
          description: Invalid or missing API key
        '403':
          description: Competitor monitoring is not enabled for this workspace
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Competitor not found
components:
  schemas:
    CompetitorTeamRefresh:
      type: object
      description: One refresh of a competitor's team, with what it found.
      properties:
        clustr_competitor_team_refresh_id:
          type: string
          description: >-
            The refresh's Clustr ID, for example
            `ctr_pn06afv3jafbq6hgdr4q241908`. Use it to refer to this

            refresh.
          example: ctr_pn06afv3jafbq6hgdr4q241908
        clustr_competitor_id:
          type: string
          description: >-
            The competitor's Clustr ID, for example
            `cmp_xaq6r4fscsd9w4wzp7r6kwt6f9`.
          example: cmp_xaq6r4fscsd9w4wzp7r6kwt6f9
        clustr_run_id:
          type: string
          description: >-
            The Clustr ID of the scheduled collection run this refresh was part
            of, for example

            `crun_emh34mf2pxqb8hpy8465zgabwq`. Null for a refresh run on demand.
          example: crun_emh34mf2pxqb8hpy8465zgabwq
        id:
          type: string
          description: >-
            Kept for integrations built before Clustr IDs. New integrations
            should use `clustr_competitor_team_refresh_id`.
        competitor_id:
          type: string
          description: >-
            Kept for integrations built before Clustr IDs. New integrations
            should use `clustr_competitor_id`.
        run_id:
          type: string
          nullable: true
          description: >-
            Kept for integrations built before Clustr IDs. New integrations
            should use `clustr_run_id`.
        origin:
          type: string
          enum:
            - run
            - manual
            - recheck
          description: >-
            What started the refresh: `run` for the scheduled monthly
            collection, `manual` for POST /competitors/{id}/team-refresh, and
            `recheck` for a second employment check of people an earlier refresh
            could not confirm or did not reach. A recheck only checks people
            already on the Team, so its `joiners` is always 0.
        status:
          type: string
          enum:
            - running
            - completed
            - failed
        started_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
          nullable: true
        joiners:
          type: integer
          description: >-
            How many people the search found who were new to the Team. They are
            added as To validate.
          example: 3
        leavers:
          type: integer
          description: >-
            How many people left the competitor. They are marked Left the
            company.
          example: 1
        function_changes:
          type: integer
          description: >-
            How many people still at the competitor moved to a role outside
            Sales and CS.
          example: 0
        joiner_names:
          type: array
          items:
            type: string
        leaver_names:
          type: array
          items:
            type: string
        function_change_names:
          type: array
          items:
            type: string
        profiles_checked:
          type: integer
          description: >-
            How many LinkedIn profiles were read to check where each monitored
            and paused person works now.
          example: 42
        unconfirmed:
          type: integer
          description: >-
            How many people could not be placed: their profile could not be
            read, it shows no current position, or its company could not be
            matched. Their status stays as it is, and each is checked again
            three days later, up to three times a month.
          example: 2
        deferred:
          type: integer
          description: >-
            How many people this pass left for later, because it ran out of time
            or its search failed. They are checked within the hour.
          example: 0
        error:
          type: string
          nullable: true
          enum:
            - SEARCH_FAILED
            - SEARCH_EMPTY
            - SEARCH_DEGRADED
            - ABANDONED
          description: >-
            Why the refresh failed. When the search fails, the refresh's
            employment checks are deferred and run later.
        notified_at:
          type: string
          format: date-time
          nullable: true
          description: When the recap was sent to Slack or the webhook.
    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
  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.