# Rank a breakdown's hashtags

> For the complete documentation index, see [llms.txt](https://www.shortsintel.com/llms.txt). Every docs page is also available as markdown: add .md to its URL. To connect, read [agents.md](https://www.shortsintel.com/agents.md).

GET `/v1/breakdowns/{id}/hashtags`

A Breakdown's hashtags, lift basis `creator_median`, answered as `GET /v1/research/{id}/hashtags` answers them.

[Open in Playground](https://www.shortsintel.com/console/playground?op=listBreakdownHashtags&id=id_example&platforms=tiktok%2Cyoutube&order_by=video_count&sort=desc&limit=25&offset=0&as_of=run) (no API Key needed)

## Price

Free, forever, filtered or not. Collection is the only thing charged.

## Parameters

| Name | In | Type | Required | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `id` | path | `string` | Required | — | Breakdown id — the id of its Run. |
| `platforms` | query | `string` | Optional | — | Comma-separated, or repeated, each one of `tiktok`, `instagram`, `youtube`, `facebook`; any other value is a 400. Omit for every platform the research covered. A tag is kept if it was seen on any platform you name; its counts still cover every platform. |
| `order_by` | query | `string` one of `video_count`, `views` | Optional | `video_count` | `video_count` is how many of the shortlist carried the tag, `views` their views added up. Ties break on total views (most first), then the tag itself, whatever the `order_by` or `sort` — the same order as the 25 inline on the research, so under `as_of=run` (the default) the default first page is that list and `offset=25` continues it. |
| `sort` | query | `string` one of `asc`, `desc` | Optional | `desc` | Direction. `desc` is best-first for every `order_by`. Hashtags missing the value being sorted on come last in both directions: unknown is not the same as smallest. |
| `limit` | query | `integer` min 1; max 100 | Optional | `25` | Hashtags per page. Over the maximum, or negative, is a 400 rather than a silent clamp. |
| `offset` | query | `integer` min 0 | Optional | `0` | Hashtags to skip. Past the end returns an empty page with the true `total`. |
| `as_of` | query | `string` one of `run`, `latest` | Optional | `run` | Which snapshots to read. `run` (the default) is what the research saw, frozen, so the list agrees with the digest. `latest` serves the newest snapshot this API holds for each video, and filters and ordering run over those numbers (a `min_` filter means "over that many now"); `outlier` and `outlier_p90` are recomputed against the research's baseline, `velocity` and `percentile` stay as measured. `latest` is uneven until you refresh: a video is as fresh as the last time anything looked at it, else it keeps the research numbers; `POST /research/{id}/refresh` updates its refreshable videos (TikTok today). Every response states its basis. |

## Responses

### 200 OK

`{ items, total, limit, offset, as_of }`.

object

A page of one research read. `items` holds the page; it pages with `limit` and `offset` over a frozen set.

- `total` integer required Rows matching the filters, before `limit` and `offset`.
- `limit` integer required
- `offset` integer required
- `as_of` string required one of `run`, `latest` Which snapshots the numbers come from: `run` is what the research itself saw, frozen, so a read always agrees with the digest; `latest` is the newest snapshot this API holds for each video.
- `items` array of object required
  - `value` string required
  - `title` string nullable
  - `platforms` array of string required Every platform this tag was observed on in the shortlist. One rollup spans platforms; `video_ids` are `platform:id` if you want the split.
  - `video_count` integer required
  - `total_views` number required
  - `video_ids` array of string required

200 · `{ items, total, limit, offset, as_of }`.

```json
{
  "items": [
    {
      "value": "coldplunge",
      "platforms": [
        "instagram",
        "tiktok"
      ],
      "video_count": 34,
      "total_views": 18402000,
      "video_ids": [
        "tiktok:7300000000000000000",
        "instagram:C9xExampleShortcode"
      ]
    }
  ],
  "total": 62,
  "limit": 25,
  "offset": 0,
  "as_of": "run"
}
```

### 400 Bad Request

`invalid_request` — an unknown platform, an unknown `order_by`, `sort` or `as_of`, a `limit` outside 1 to 100, or a negative or non-integer `offset`.

Code: `invalid_request`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

### 401 Unauthorized

Codes: `missing_authorization`, `invalid_key`, `key_revoked`, `key_expired`, `invalid_token`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

### 404 Not Found

Code: `not_found`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

### 409 Conflict

`run_not_ready` — the research is still running, or failed with nothing to serve. If it is still running, poll `GET /v1/runs/{id}` and read again once it settles; a failed research never becomes readable.

Code: `run_not_ready`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

## Request samples

curl:

```bash
curl "https://www.shortsintel.com/v1/breakdowns/id_example/hashtags?platforms=tiktok%2Cyoutube&order_by=video_count&sort=desc&limit=25&offset=0&as_of=run" \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
```

TypeScript:

```typescript
const response = await fetch(
  "https://www.shortsintel.com/v1/breakdowns/id_example/hashtags?platforms=tiktok%2Cyoutube&order_by=video_count&sort=desc&limit=25&offset=0&as_of=run",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer sk_live_YOUR_KEY",
    },
  },
);

if (!response.ok) {
  throw new Error(`ShortsIntel ${response.status}`);
}

const data = await response.json();
```

Python:

```python
import requests

response = requests.get(
    "https://www.shortsintel.com/v1/breakdowns/id_example/hashtags?platforms=tiktok%2Cyoutube&order_by=video_count&sort=desc&limit=25&offset=0&as_of=run",
    headers={
        "Authorization": "Bearer sk_live_YOUR_KEY",
    },
)
response.raise_for_status()

data = response.json()
```

[Previous Read a breakdown's creators and medians](https://www.shortsintel.com/docs/reference/breakdowns/list-breakdown-creators)[Next Rank a breakdown's sounds](https://www.shortsintel.com/docs/reference/breakdowns/list-breakdown-sounds)
