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

# Visibility trends

> Time-series visibility, sentiment, and position data per competitor.

The visibility trends endpoint returns daily time-series metrics for every active competitor in a project. Use it to chart how brand visibility, sentiment, and position change over time across AI providers.

## Get visibility trends

```
GET /projects/{project_id}/visibility
```

Returns daily visibility, sentiment, and position values for each active competitor, averaged across selected providers.

### Path parameters

| Param        | Type          | Description    |
| ------------ | ------------- | -------------- |
| `project_id` | string (UUID) | The project ID |

### Query parameters

| Param           | Type    | Default | Description                     |
| --------------- | ------- | ------- | ------------------------------- |
| `duration_days` | integer | `7`     | Days to look back               |
| `date_from`     | string  | --      | Start date (`YYYY-MM-DD`)       |
| `date_to`       | string  | --      | End date (`YYYY-MM-DD`)         |
| `providers`     | string  | --      | Comma-separated provider filter |

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl "https://topify-customer-api-production.up.railway.app/api/public/v1/projects/{project_id}/visibility?duration_days=7" \
      -H "X-API-Key: tk_live_..."
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = client.get(f"/projects/{project_id}/visibility", params={"duration_days": 7})
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const resp = await fetch(`${BASE}/projects/${projectId}/visibility?duration_days=7`, { headers });
    ```
  </Tab>
</Tabs>

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "dates": ["2026-02-28", "2026-03-01", "2026-03-02", "2026-03-03"],
    "period": "2026-02-28 to 2026-03-03",
    "series": [
      {
        "competitor_id": "00000000-0000-0000-0000-000000000000",
        "name": "Acme Corp",
        "website": "https://acme.com",
        "icon_url": "https://logo.clearbit.com/acme.com",
        "is_own_brand": true,
        "visibility": [82.5, 85.0, 83.2, 86.1],
        "sentiment": [70.0, 72.0, 71.5, 73.0],
        "position": [1.8, 1.6, 1.9, 1.5]
      },
      {
        "competitor_id": "c1d2e3f4-...",
        "name": "Competitor A",
        "website": "https://competitor-a.com",
        "icon_url": "https://logo.clearbit.com/competitor-a.com",
        "is_own_brand": false,
        "visibility": [60.0, 62.5, null, 65.0],
        "sentiment": [55.0, 58.0, null, 60.0],
        "position": [3.2, 3.0, null, 2.8]
      }
    ]
  }
}
```

### VisibilityTrendsResponse fields

| Field    | Type                | Description                                                  |
| -------- | ------------------- | ------------------------------------------------------------ |
| `dates`  | string\[]           | Sorted date strings in `YYYY-MM-DD` format                   |
| `period` | string              | Human-readable date range (e.g., `2026-02-28 to 2026-03-03`) |
| `series` | CompetitorSeries\[] | One entry per active competitor                              |

### CompetitorSeries fields

| Field           | Type          | Nullable | Description                                                              |
| --------------- | ------------- | -------- | ------------------------------------------------------------------------ |
| `competitor_id` | string (UUID) | No       | Competitor ID                                                            |
| `name`          | string        | No       | Competitor brand name                                                    |
| `website`       | string        | No       | Competitor website URL                                                   |
| `icon_url`      | string        | Yes      | Primary logo URL                                                         |
| `is_own_brand`  | boolean       | No       | `true` if this is your own brand                                         |
| `visibility`    | float\[]      | No       | Daily visibility scores aligned to `dates`. `null` for days with no data |
| `sentiment`     | float\[]      | No       | Daily sentiment scores aligned to `dates`. `null` for days with no data  |
| `position`      | float\[]      | No       | Daily position values aligned to `dates`. `null` for days with no data   |

<Note>
  When multiple providers have data for the same day, values are averaged. A `null` entry means no data was collected for that competitor on that date.
</Note>

### Use cases

<Tabs>
  <Tab title="Chart over time">
    Plot each competitor as a line on a time-series chart. The `dates` array provides x-axis labels and each series' `visibility`, `sentiment`, and `position` arrays provide y-axis values.
  </Tab>

  <Tab title="Compare competitors">
    Use `is_own_brand` to highlight your brand against competitors. Compare trends to see if your visibility is growing faster or slower than the competition.
  </Tab>

  <Tab title="Filter by provider">
    Pass `?providers=chatgpt` to isolate trends for a single AI provider and compare performance across platforms.
  </Tab>
</Tabs>
