# Trends

> See which topics are trending on short-form video right now, worldwide or by country, with a momentum reading and example videos for each trend.

Source: https://dev.virlo.ai/docs/trends
Markdown: https://dev.virlo.ai/docs/trends.md
Section: Explore data

## About the Virlo API (applies to every page)

- Base URL: `https://api.virlo.ai/v1`. Every request needs the header `Authorization: Bearer YOUR_API_KEY` (keys start with `virlo_tkn_`).
- Responses are JSON inside a `data` field, except the `/v1/webhooks` endpoints, which return the object or array directly. Field names are snake_case.
- Prices are in US dollars from a prepaid balance. 1 credit = $0.01. The `X-Cost` response header on each successful response is the exact charge. Errors are free.
- Slow jobs return an ID. Check its status every 15 seconds (or whatever `retry_after_seconds` says) until `finalized` is `true`.
- All docs pages: https://dev.virlo.ai/llms.txt. Every page in one file: https://dev.virlo.ai/llms-full.txt. MCP server for AI assistants: https://dev.virlo.ai/api/mcp/mcp.

---

See what is taking off on short-form video right now, so you can post while it is still growing.

**At a glance**

- **What it does:** Shows what is trending on TikTok, YouTube and Instagram, worldwide or in one country.
- **You send:** Nothing required. Optionally a `region` like `gb`, or dates to see past days.
- **You get back:** Within seconds, a ranked list of trends, each with a summary, momentum label and example videos.
- **Cost:** $0.25 per request, even when nothing matches. Listing regions and failed requests are free.

Start with [today's trends](https://dev.virlo.ai/docs/trends#get-trends-digest). [Emerging trends](https://dev.virlo.ai/docs/trends#get-emerging-trends) shows only new and rising trends, and [trends by date](https://dev.virlo.ai/docs/trends#get-trends) covers past days.

## How trends work

A **trend** is a topic many people are posting about, like a news moment or a meme. Each region gets one ranked **daily list** (a "trend group" in the API), usually 15 to 20 trends.

- Regions are `global` (the default), `us`, `gb`, `au` and `sg`. Each region's list is made on local time for that audience, not cut from `global`.
- Virlo finds new trends at 7:00, 13:00 and 19:00 local time. The 7:00 run starts the day's list.
- About every 2 hours, Virlo re-checks [momentum](https://dev.virlo.ai/docs/trends#momentum) and re-sorts the list, so rankings shift.
- Virlo drops trends that still have no example videos and, beyond the top 20, the coldest ones. Trends under 6 hours old are never dropped. So a trend can vanish mid-day.
- Active trends carry over to the next day.
- Two trends can occasionally cover the same story.

Trends can't be filtered by platform, niche or keyword. For one niche, use a [Content Research Agent](https://dev.virlo.ai/docs/agents).

Example videos are the all-time most viewed, often months or years old. Check `publish_date`.

## Momentum

Momentum shows how fast a trend is growing. Each trend has a `momentum` object:

- `status` (string, optional)
  - `new`: first spotted less than 8 hours ago.
  - `rising`: views growing more than 15% faster than in the previous 2 hours.
  - `steady`: about the same speed.
  - `fading`: more than 15% slower.
- `score` (number, optional): 0 to 1. About 1,000 views an hour scores 0.6, 10,000 scores 0.8, and 100,000 or more scores 1.
- `views_per_hour` (integer, optional): Combined hourly view growth of the example videos between the last two checks.
- `updated_at` (string, optional): Time of the last check (UTC).

A new trend's numbers are rough until the 3rd check, usually within 6 hours.

**Details for developers**

- `momentum` is `null` until the first check. It stays `null`, sorted last, if fewer than 3 example videos can be re-checked.
- After the 1st check, `score` is a 0.3 to 0.7 placeholder and `views_per_hour` is `0`. The 2nd check measures both.
- Until the 3rd check, `status` is estimated from how many videos on the topic were posted the day before Virlo found it.
- Only the newest list gets updates. Past days keep their last reading.

## Get today's trends

**Endpoint:** `GET https://api.virlo.ai/v1/trends/digest`

Returns one region's latest daily list.

Cost per request: $0.25

- You get the newest list from the last 48 hours. Lists start at 7:00 local, so earlier you get yesterday's.
- `title` shows today's date even on yesterday's list. Use `local_date`.
- Lists under 15 trends get filled to 15 with earlier days' trends. These come last, with their old `trend_group_id`.
- If the newest list is empty, you get the latest one with trends, even an older one. With no list in 48 hours, `data` is empty.
- `region` (string, optional): Region code. Default `global`.
- `top_exemplars` (integer, optional): Example videos per trend, 0 to 20. Default 5. `0` makes the response much smaller.

It also accepts `limit`, `start_date` and `end_date`, but ignores them.

**cURL request:**

```bash
curl -G https://api.virlo.ai/v1/trends/digest \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d region=au
```

**JavaScript request:**

```js
const res = await fetch('https://api.virlo.ai/v1/trends/digest?region=au', {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
})
const { data } = await res.json()
const todaysList = data[0]
```

**Python request:**

```python
import requests

res = requests.get(
    'https://api.virlo.ai/v1/trends/digest',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={'region': 'au'},
)
data = res.json()['data']
todays_list = data[0] if data else None
```

**Response 200 OK:**

```json
{
  "data": [
    {
      "id": "7cf7a841-e7a7-4844-8ac4-ed9823615bae",
      "title": "Trends for Sep 25",
      "region": "au",
      "local_date": "2026-09-24",
      "trends": [
        {
          "ranking": 9,
          "trend": {
            "id": "745ff63d-09d7-483b-94e2-3c7a6bf5c527",
            "name": "AFL Grand Final training buzz: Freo, Lions, and imminent crowd energy",
            "description": "On September 23, 2026, thousands of Fremantle Dockers fans gathered at Cockburn ARC for an open training session ahead of the AFL Grand Final against the Brisbane Lions...",
            "trend_type": "content"
          },
          "momentum": {
            "score": 0.6456,
            "status": "fading",
            "views_per_hour": 1690,
            "updated_at": "2026-09-24T16:00:01.056Z"
          },
          "velocity_today_count": 0,
          "velocity_median_views": 0,
          "detected_at": "2026-09-23T21:06:49.273+00:00",
          "last_seen_at": "2026-09-23T21:06:49.273+00:00",
          "origin_region_codes": null,
          "global_confidence": null,
          "exemplar_count": 6,
          "scrape_status": "success",
          "id": "04a9f0c1-988c-4f38-844a-3e15e9a80b4e",
          "trend_id": "745ff63d-09d7-483b-94e2-3c7a6bf5c527",
          "trend_group_id": "7cf7a841-e7a7-4844-8ac4-ed9823615bae",
          "top_exemplars": [
            {
              "video_id": "411eabfc-1074-4c5a-b04c-c4deb43174b6",
              "url": "https://www.tiktok.com/@9news/video/7687586729653783815",
              "platform": "tiktok",
              "views": 457017,
              "thumbnail_url": "https://auth.virlo.ai/storage/v1/object/public/thumbnails/c3cdffed0e38dd1c3ac48e836c169367feaca911cc77fb2708bf40fd328663f0.jpg",
              "publish_date": "2026-09-20T12:02:55",
              "author": {
                "username": "9news",
                "avatar_url": "https://auth.virlo.ai/storage/v1/object/public/avatars/efb8c840b5308a468320874e1f818cfb2214455b4b9afa8e4ea31828454f902f.heic",
                "verified": false
              }
            }
          ]
        }
      ]
    }
  ]
}
```

**Response 400 Bad input:**

```json
{
  "message": "Unknown region \"xx\". Available regions: au, gb, global, sg, us",
  "error": "Bad Request",
  "statusCode": 400,
  "code": "unknown_region"
}
```

**Full field reference**

Times are UTC. Each daily list has `id`, `region`, `trends` and:

- `title` (string, optional): Display text. [Trends by date](https://dev.virlo.ai/docs/trends#get-trends) shows the UTC start date, a day early for `au` and `sg`. Use `local_date`.
- `local_date` (string | null, optional): The list's day in the region's timezone. `null` on `global` lists before July 7, 2026, and a few from August 2026.

Each trend has:

- `ranking` (integer, optional): 1 has the most momentum.
- `trend` (object, optional): `id`, `name`, `description` and `trend_type` (`content` since mid-October 2025, older ones `twitter`, `native` or `null`).
- `momentum` (object | null, optional): See [Momentum](https://dev.virlo.ai/docs/trends#momentum). Always present, `null` until the first check.
- `top_exemplars` (array, optional): Example videos, most-viewed first.
- `exemplar_count` (integer, optional): Total example videos linked.
- `detected_at` (string | null, optional): When the trend entered the list. Carried-over trends keep it, so it can predate `local_date`.
- `last_seen_at` (string | null, optional): The last run that found it. If older than today's list, the trend carried over unconfirmed.
- `id` (string, optional): This entry. New each day.
- `trend_id` (string, optional): The trend itself, stable across days. Store this one.
- `trend_group_id` (string, optional): The list it came from.
- `velocity_today_count` (integer | null, optional): Videos on the topic in the 24 hours before Virlo found it. A one-time snapshot, often `0` or `null`.
- `velocity_median_views` (integer | null, optional): Their median views.
- `origin_region_codes` (string[] | null, optional): On `global`, the countries that also had the trend, like `["gb", "us"]`.
- `global_confidence` (number | null, optional): How sure Virlo is (0 to 1) that those are one story.
- `scrape_status` (string | null, optional): Whether example videos are linked yet: `pending`, `success` or `failed`.

Each example video has `video_id`, `url`, `platform` (`tiktok`, `youtube` or `instagram`), `views`, `thumbnail_url`, `publish_date` (can be much older than the trend) and `author` (`username`, `avatar_url`, `verified`).

## Get emerging trends

**Endpoint:** `GET https://api.virlo.ai/v1/trends/emerging`

Returns only the `new` and `rising` trends from a region's latest list, highest momentum first.

Cost per request: $0.25

- You get one flat list, not daily lists. Often fewer than `limit`, sometimes none (still $0.25).
- Momentum comes as flat fields: `status`, `momentum_score` and `views_per_hour`.
- `region` (string, optional): Region code. Default `global`.
- `limit` (integer, optional): Most trends to return, a whole number from 1 to 50. Default 20.
- `top_exemplars` (integer, optional): Example videos per trend, 0 to 20. Default 5.

**cURL request:**

```bash
curl -G https://api.virlo.ai/v1/trends/emerging \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d region=gb \
  -d limit=20
```

**JavaScript request:**

```js
const params = new URLSearchParams({ region: 'gb', limit: '20' })
const res = await fetch(`https://api.virlo.ai/v1/trends/emerging?${params}`, {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
})
const { data } = await res.json()
```

**Python request:**

```python
import requests

res = requests.get(
    'https://api.virlo.ai/v1/trends/emerging',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={'region': 'gb', 'limit': 20},
)
data = res.json()['data']
```

**Response 200 OK:**

```json
{
  "region": "gb",
  "generated_at": "2026-09-24T17:26:34.614Z",
  "data": [
    {
      "ranking": 1,
      "trend": {
        "id": "d968f93c-be19-4598-9100-cad47a732a4c",
        "name": "Drama & memes around Rory Stewart BBC Newsnight moment",
        "description": "On September 18, 2026, former MP Rory Stewart appeared on BBC's Newsnight, where he dramatically spun in his chair to stare at Ailbhe Rea...",
        "created_at": "2026-09-24T06:05:44.925004+00:00",
        "trend_type": "content"
      },
      "status": "rising",
      "momentum_score": 1,
      "views_per_hour": 257371,
      "region": "gb",
      "detected_at": "2026-09-24T06:05:45.122+00:00",
      "last_seen_at": "2026-09-24T12:06:30.905+00:00",
      "exemplar_count": 13,
      "id": "8ff9f920-2804-4f6a-91ec-08cddfa5d7db",
      "trend_id": "d968f93c-be19-4598-9100-cad47a732a4c",
      "top_exemplars": [
        {
          "video_id": "367da5d1-5510-4e73-b9a5-fd6207e9915e",
          "url": "https://www.tiktok.com/@thesun/video/7688710703854767392",
          "platform": "tiktok",
          "views": 5050311,
          "thumbnail_url": "https://auth.virlo.ai/storage/v1/object/public/thumbnails/5f78a37402cb781959c245240f08b7ea1672b0867346cf35771adb32f177e612.jpg",
          "publish_date": "2026-09-23T12:44:27",
          "author": {
            "username": "thesun",
            "avatar_url": "https://auth.virlo.ai/storage/v1/object/public/avatars/7a926491c16af666224735afecb62c829a4e11f774fd221b2514238a4ef6a231.webp",
            "verified": false
          }
        }
      ]
    }
  ]
}
```

**Response 400 Bad input:**

```json
{
  "message": ["limit must not be greater than 50"],
  "error": "Bad Request",
  "statusCode": 400,
  "code": "validation_error"
}
```

**Response 429 Too many calls:**

```json
{
  "statusCode": 429,
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded",
  "error": "Too Many Requests",
  "limit": 60,
  "remaining": 0,
  "reset_at": 1790271060,
  "reset_at_formatted": "September 24th, 2026, 5:31 PM UTC",
  "retry_after": 54
}
```

**Full field reference**

Top level: `region`, `generated_at`, `data`. Each trend has `region`, `id`, `trend_id`, `detected_at`, `last_seen_at`, `exemplar_count` and `top_exemplars` as on [today's trends](https://dev.virlo.ai/docs/trends#get-trends-digest), plus:

- `ranking` (integer, optional): Position in the full daily list, so numbers can skip.
- `trend` (object, optional): Adds `created_at`, when Virlo first recorded the trend. It can be much older than `detected_at`.
- `status` (string, optional): `new` or `rising`. Before the first check it is estimated, so a just-found trend shows `rising`, not `new`.
- `momentum_score` (number, optional): Like `momentum.score`. Before the first check it is an estimate (0.7 or 0.9) where the daily list shows `null`. Trends with under 3 example videos keep it.
- `views_per_hour` (integer | null, optional): `null` before the first check.

## Get trends by date

**Endpoint:** `GET https://api.virlo.ai/v1/trends`

Returns one region's daily lists in a date range, newest first. With no dates, you get the last 24 hours: normally today's list, topped up to 15. Date-range lists are not topped up.

Cost per request: $0.25

### How the dates work

Dates match each list's 7:00 local start, in UTC, and a plain date means midnight UTC. So for `global`, `us` and `gb`, set `end_date` to the day after your last day. `au` and `sg` lists start the evening before in UTC, so set `start_date` to the day before your first day instead.

History starts September 15, 2025 for `global`, July 6, 2026 for `us` and `gb`, July 7 for `au` and July 29 for `sg`. Before July 7, 2026, `global` lists have no `local_date`, and a day can have two. Read the day from `title` and tell them apart by `id`.

- `region` (string, optional): Region code. Default `global`.
- `start_date` (string, optional): `2026-07-14` or a UTC time like `2026-07-14T00:00:00Z`. Default 24 hours ago.
- `end_date` (string, optional): Same format. Default now.
- `limit` (integer, optional): Most daily lists to return, 1 to 100. Default 50. Higher counts as 100.
- `top_exemplars` (integer, optional): Example videos per trend, 0 to 20. Default 5.

This gets UK lists for July 14 to 16.

**cURL request:**

```bash
curl -G https://api.virlo.ai/v1/trends \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d region=gb \
  -d start_date=2026-07-14 \
  -d end_date=2026-07-17
```

**JavaScript request:**

```js
const params = new URLSearchParams({
  region: 'gb',
  start_date: '2026-07-14',
  end_date: '2026-07-17',
})
const res = await fetch(`https://api.virlo.ai/v1/trends?${params}`, {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
})
const { data } = await res.json() // daily lists, newest first
```

**Python request:**

```python
import requests

res = requests.get(
    'https://api.virlo.ai/v1/trends',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={'region': 'gb', 'start_date': '2026-07-14', 'end_date': '2026-07-17'},
)
data = res.json()['data']  # daily lists, newest first
```

**Response 200 OK:**

```json
{
  "data": [
    {
      "id": "8108e2f4-3a40-4f85-9f2a-3c9ec1ccf79c",
      "title": "Trends for Jul 16th",
      "region": "gb",
      "local_date": "2026-07-16",
      "trends": [
        {
          "ranking": 1,
          "trend": {
            "id": "7002bfb2-8261-4c64-9921-c6797533e8ba",
            "name": "World Cup Final Tease & Pre-Show Buzz (Banner & Flags)",
            "description": "Ahead of the 2026 FIFA World Cup final on July 19, 2026, excitement is building as Argentina, led by Lionel Messi, prepares to face Spain...",
            "trend_type": "content"
          },
          "momentum": {
            "score": 1,
            "status": "rising",
            "views_per_hour": 2617163,
            "updated_at": "2026-07-17T05:00:00.708Z"
          },
          "velocity_today_count": 96,
          "velocity_median_views": 329031,
          "detected_at": "2026-07-16T12:05:34.855+00:00",
          "last_seen_at": "2026-07-16T12:05:34.855+00:00",
          "origin_region_codes": null,
          "global_confidence": null,
          "exemplar_count": 144,
          "scrape_status": "success",
          "id": "2460d76e-5641-43a0-afb7-82f4e0cd33f7",
          "trend_id": "7002bfb2-8261-4c64-9921-c6797533e8ba",
          "trend_group_id": "8108e2f4-3a40-4f85-9f2a-3c9ec1ccf79c",
          "top_exemplars": [
            {
              "video_id": "a4397cf9-35b9-45ec-a4e3-7ab414c2aadf",
              "url": "https://www.tiktok.com/@fifaworldcup/video/7662504667452099862",
              "platform": "tiktok",
              "views": 154919730,
              "thumbnail_url": "https://auth.virlo.ai/storage/v1/object/public/thumbnails/2fdf43d6-0a47-4616-a21f-0c7dc51c67b8.jpg",
              "publish_date": "2026-07-14T21:51:39",
              "author": {
                "username": "fifaworldcup",
                "avatar_url": "https://auth.virlo.ai/storage/v1/object/public/avatars/ccd523186bc6d0b89762cb4bb4c9c7d60bc6266497dc5ddedb24ae3c5b50e0f5.heic",
                "verified": false
              }
            }
          ]
        },
        {
          "ranking": 9,
          "trend": {
            "id": "1e15ebc7-7b09-4118-a092-c5788cc3728d",
            "name": "New Music from ROLE MODEL",
            "description": "On July 10, 2026, Role Model (Tucker Pillsbury) released his new single 'Joy,' the second track from his upcoming album...",
            "trend_type": "content"
          },
          "momentum": null,
          "velocity_today_count": 0,
          "velocity_median_views": 0,
          "detected_at": "2026-07-16T06:04:53.03+00:00",
          "last_seen_at": "2026-07-16T06:04:53.03+00:00",
          "origin_region_codes": null,
          "global_confidence": null,
          "exemplar_count": 2,
          "scrape_status": "success",
          "id": "70a03e12-4624-4641-a84b-37a0a10ca6fc",
          "trend_id": "1e15ebc7-7b09-4118-a092-c5788cc3728d",
          "trend_group_id": "8108e2f4-3a40-4f85-9f2a-3c9ec1ccf79c",
          "top_exemplars": [
            {
              "video_id": "6d6bd156-c88f-4de0-bc9a-54ef6493506c",
              "url": "https://www.tiktok.com/@popgirly.era/video/7660846467308916000",
              "platform": "tiktok",
              "views": 136426,
              "thumbnail_url": "https://auth.virlo.ai/storage/v1/object/public/thumbnails/8ca67ff9-a8e5-4af5-af10-e6111b615ba9.jpg",
              "publish_date": "2026-07-10T10:36:58",
              "author": {
                "username": "popgirly.era",
                "avatar_url": "https://auth.virlo.ai/storage/v1/object/public/avatars/fd82bc9bebdbb037c7162c4c33a8f1702e6e3d356df52436d0eaa04af19ddc7c.webp",
                "verified": false
              }
            }
          ]
        }
      ]
    }
  ]
}
```

**Response 400 Bad input:**

```json
{
  "message": ["start_date must be a valid ISO 8601 date string"],
  "error": "Bad Request",
  "statusCode": 400,
  "code": "invalid_date_range"
}
```

The fields match [Get today's trends](https://dev.virlo.ai/docs/trends#get-trends-digest).

## List regions

**Endpoint:** `GET https://api.virlo.ai/v1/trends/regions`

Free. Returns every region code with its name and timezone. New regions get added, so check here. `AU` and `au` both work.

**cURL request:**

```bash
curl https://api.virlo.ai/v1/trends/regions \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**JavaScript request:**

```js
const res = await fetch('https://api.virlo.ai/v1/trends/regions', {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
})
const { data } = await res.json()
```

**Python request:**

```python
import requests

res = requests.get(
    'https://api.virlo.ai/v1/trends/regions',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
data = res.json()['data']
```

**Response 200 OK:**

```json
{
  "data": [
    { "code": "au", "name": "Australia", "timezone": "Australia/Sydney" },
    { "code": "gb", "name": "United Kingdom", "timezone": "Europe/London" },
    { "code": "global", "name": "Global", "timezone": "America/New_York" },
    { "code": "sg", "name": "Singapore", "timezone": "Asia/Singapore" },
    { "code": "us", "name": "United States", "timezone": "America/New_York" }
  ]
}
```

## Errors

Failed requests count toward your rate limit.

- `400 Bad Request`
  - A bad date (`invalid_date_range`). Use `2026-07-14`.
  - `limit` below 1 or not a number. Decimals round down, except on emerging, where decimals and values over 50 fail.
  - `top_exemplars` outside 0 to 20, or not a whole number.
  - An unknown `region` (`unknown_region`).
  - A parameter these calls don't take, like `platform`.
  `message` is an array of strings, except for `unknown_region`.
- `401 Unauthorized`: Missing or invalid API key.
- `402 Payment Required`: Balance too low. [Add funds](https://dev.virlo.ai/dashboard/billing).
- `429 Too Many Requests`: Wait `retry_after` seconds. Today's trends and trends by date each allow 50 a minute, 500 an hour and 5,000 a day. Emerging allows 60, 600 and 6,000. Some accounts have lower limits; the `X-RateLimit-Limit` header shows yours.

More in [Errors](https://dev.virlo.ai/docs/errors) and [Rate limits](https://dev.virlo.ai/docs/rate-limits).

---

More in Explore data:

- [Sounds](https://dev.virlo.ai/docs/sounds.md)
- [Hooks](https://dev.virlo.ai/docs/hooks.md)
- [Hashtags](https://dev.virlo.ai/docs/hashtags.md)
- [Videos](https://dev.virlo.ai/docs/videos.md)
