# Viral & Thumbnail Search

Find outlier videos and search channels by thumbnail image.

### `GET /api/viral-videos/search`

Search for viral videos across Shorts and Longform channels, find videos similar to a specific video, or browse by filters alone. Filter by video views, channel size, growth metrics, upload recency, outlier score, and more. `q`, `video_id`, and `video_url` are all optional — omit them to browse by filters (e.g. “biggest outliers from the last 7 days”).

**Query Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| q | string | Optional | — | Search query. Matches video titles and channel names with similarity scoring. Also accepts `search` as an alias. Omit along with `video_id` / `video_url` to browse by filters alone. |
| video_id | string | Optional | — | YouTube video ID (e.g. `dQw4w9WgXcQ`). Finds videos similar to this video using title similarity. |
| content_type | string | Optional | shorts | Content type: `shorts` or `longform` |
| sort_by | string | Optional | views | Sort by: `views` (most viewed), `recent` (newest fetched), `upload_date` (newest uploaded), `similarity` (most similar — requires `q`/`video_id`/`video_url`; auto-selected when one is given), `outlier_score` (biggest over-performers — video views vs channel average) |
| page | integer | Optional | 1 | Page number (1-indexed, max 20) |
| per_page | integer | Optional | 20 | Results per page (max 50) |
| min_video_views | integer | Optional | — | Minimum video view count |
| max_video_views | integer | Optional | — | Maximum video view count |
| min_subs | integer | Optional | — | Minimum channel subscriber count |
| max_subs | integer | Optional | — | Maximum channel subscriber count |
| min_uploads | integer | Optional | — | Minimum channel video count |
| max_uploads | integer | Optional | — | Maximum channel video count |
| min_channel_age | integer | Optional | — | Minimum channel age in days |
| max_channel_age | integer | Optional | — | Maximum channel age in days |
| min_upload_date | integer | Optional | — | Newest allowed upload (days ago, 0 = today) |
| max_upload_date | integer | Optional | — | Oldest allowed upload (days ago, e.g. 365 = 1 year) |
| min_duration | integer | Optional | — | Minimum video duration in minutes (longform only) |
| max_duration | integer | Optional | — | Maximum video duration in minutes (longform only) |
| min_views_24h | integer | Optional | — | Minimum channel views gained in last 24h (shorts only) |
| max_views_24h | integer | Optional | — | Maximum channel views gained in last 24h (shorts only) |
| min_views_48h | integer | Optional | — | Minimum channel views gained in last 48h (shorts only) |
| max_views_48h | integer | Optional | — | Maximum channel views gained in last 48h (shorts only) |
| min_outlier_score | float | Optional | — | Minimum outlier score. A video's `outlier_score` = its view count ÷ its channel's average views per video, so `2.5` means “video got 2.5× the channel's typical views.” Use to surface videos over-performing their channel. |
| max_outlier_score | float | Optional | — | Maximum outlier score. Rarely needed — usually pair with `min_outlier_score`. |

**Example Requests**

```
# Find viral gaming Shorts with 1M+ views from small channels
curl "https://api.algrow.online/api/viral-videos/search?q=gaming&content_type=shorts&min_video_views=1000000&max_subs=50000" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Longform fitness videos uploaded in last 7 days, sorted by views
curl "https://api.algrow.online/api/viral-videos/search?q=fitness+workout&content_type=longform&max_upload_date=7&sort_by=views" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Find videos similar to a specific video by ID
curl "https://api.algrow.online/api/viral-videos/search?video_id=dQw4w9WgXcQ&content_type=longform" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Search for cooking videos from channels under 100k subs
curl "https://api.algrow.online/api/viral-videos/search?q=cooking&max_subs=100000" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response**

```
{
  "success": true,
  "content_type": "shorts",
  "page": 1,
  "per_page": 20,
  "count": 20,
  "videos": [
    {
      "video_id": "dQw4w9WgXcQ",
      "title": "This cooking hack changed everything",
      "channel_name": "Chef Secrets",
      "channel_id": "UCxxxxxxxxxxxxxxxxxxxxxx",
      "view_count": 4200000,
      "outlier_score": 4.2,
      "thumbnail_url": "https://i.ytimg.com/vi/.../maxresdefault.jpg",
      "upload_date": "2026-03-15T00:00:00+00:00",
      "url": "https://www.youtube.com/shorts/dQw4w9WgXcQ",
      "subscriber_count": 32000,
      "duration": 58,
      "view_increase_24h": 180000,
      "view_increase_48h": 320000
    }
  ]
}
```

**Response Fields (per video)**

| Field | Type | Description |
| --- | --- | --- |
| video_id | string | YouTube video ID |
| title | string | Video title |
| channel_name | string | Channel name |
| channel_id | string | YouTube channel ID |
| view_count | integer | Total video views |
| outlier_score | float\|null | Outlier multiplier — video's view count ÷ its channel's average views per video. `4.2` = video got 4.2× the channel's typical views. `null` for brand-new uploads before the channel average is computed. |
| thumbnail_url | string | Video thumbnail URL |
| upload_date | string\|null | Upload date (ISO 8601) |
| url | string | Full YouTube URL |
| subscriber_count | integer | Channel subscriber count |
| duration | integer\|null | Video duration in seconds |
| view_increase_24h | integer\|null | Channel views gained in last 24h (shorts with realtime filters only) |
| view_increase_48h | integer\|null | Channel views gained in last 48h (shorts with realtime filters only) |
| similarity_score | integer\|null | Similarity score (0–100) when using search. Higher = more similar. |

### `POST /api/thumbnail-search`

Search for longform videos by thumbnail similarity. Provide a YouTube video URL, an image URL, or a text description to find videos with visually similar thumbnails using similarity matching.

**Request Body (JSON)**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| image_url | string | One of three | — | URL of a thumbnail image to search with. Supports JPEG, PNG, WebP, and GIF formats. |
| video_url | string | One of three | — | YouTube video URL — automatically extracts its thumbnail. Accepts watch, shorts, and youtu.be links. |
| q | string | One of three | — | Text description of the thumbnail style to search for (e.g. “red arrow pointing at shocked face”, “before and after transformation”). |
| limit | integer | Optional | 20 | Maximum number of results to return (1–50) |
| min_similarity | float | Optional | 0.3 | Minimum similarity threshold (0–1). Higher values return fewer but more visually similar results. |
| min_views | integer | Optional | — | Minimum video view count filter |

**Example Requests**

```
# Search by image URL — find videos with similar thumbnails
curl -X POST "https://api.algrow.online/api/thumbnail-search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"image_url": "https://i.ytimg.com/vi/abc123/maxresdefault.jpg", "limit": 10}'

# Search by text — describe the thumbnail style you're looking for
curl -X POST "https://api.algrow.online/api/thumbnail-search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "red arrow pointing at shocked face", "limit": 20}'

# Text search with filters — only high-view results
curl -X POST "https://api.algrow.online/api/thumbnail-search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "before and after transformation", "min_views": 100000, "min_similarity": 0.5}'
```

**Response**

```
{
  "success": true,
  "count": 10,
  "videos": [
    {
      "video_id": "abc123",
      "title": "How I Made $10k in 30 Days",
      "channel_name": "Finance Tips",
      "channel_id": "UCxxxxxxxxxxxxxxxxxxxxxx",
      "view_count": 1500000,
      "thumbnail_url": "https://i.ytimg.com/vi/abc123/maxresdefault.jpg",
      "upload_date": "2026-03-20",
      "url": "https://www.youtube.com/watch?v=abc123",
      "duration": 612,
      "subscriber_count": 85000,
      "similarity_score": 78
    }
  ]
}
```

**Response Fields (per video)**

| Field | Type | Description |
| --- | --- | --- |
| video_id | string | YouTube video ID |
| title | string | Video title |
| channel_name | string | Channel name |
| channel_id | string | YouTube channel ID |
| view_count | integer | Total video views |
| thumbnail_url | string | Video thumbnail URL |
| upload_date | string\|null | Upload date (ISO 8601) |
| url | string | Full YouTube URL |
| duration | integer\|null | Video duration in seconds |
| subscriber_count | integer | Channel subscriber count |
| similarity_score | integer | Visual similarity score (0–100). Higher = more similar thumbnail. |

### `POST /api/terminated-thumbnail-search`

Search terminated/deleted channel videos by thumbnail similarity. Same as `/api/thumbnail-search` but searches the terminated channels archive instead of active longform channels. Provide a YouTube video URL, an image URL, or a text description.

**Request Body (JSON)**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| image_url | string | One of three | — | URL of a thumbnail image to search with. Supports JPEG, PNG, WebP, and GIF formats. |
| video_url | string | One of three | — | YouTube video URL — automatically extracts its thumbnail. Accepts watch, shorts, and youtu.be links. |
| q | string | One of three | — | Text description of the thumbnail style to search for (e.g. “red arrow pointing at shocked face”, “before and after transformation”). |
| limit | integer | Optional | 20 | Maximum number of results to return (1–50) |
| min_similarity | float | Optional | 0.3 | Minimum similarity threshold (0–1). Higher values return fewer but more visually similar results. |
| min_views | integer | Optional | — | Minimum video view count filter |
| max_views | integer | Optional | — | Maximum video view count filter |

**Example Requests**

```
# Search by image URL — find terminated videos with similar thumbnails
curl -X POST "https://api.algrow.online/api/terminated-thumbnail-search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"image_url": "https://i.ytimg.com/vi/abc123/maxresdefault.jpg", "limit": 10}'

# Search by text — describe the thumbnail style
curl -X POST "https://api.algrow.online/api/terminated-thumbnail-search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "red arrow pointing at shocked face", "limit": 20}'

# Search by YouTube video URL
curl -X POST "https://api.algrow.online/api/terminated-thumbnail-search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video_url": "https://www.youtube.com/watch?v=abc123", "min_views": 50000}'
```

**Response**

```
{
  "success": true,
  "count": 10,
  "videos": [
    {
      "video_id": "abc123",
      "title": "How I Made $10k in 30 Days",
      "channel_name": "Finance Tips",
      "channel_id": "UCxxxxxxxxxxxxxxxxxxxxxx",
      "view_count": 1500000,
      "thumbnail_url": "https://audio.algrow.online/thumbnails/abc123.jpg",
      "url": "https://www.youtube.com/watch?v=abc123",
      "subscriber_count": 85000,
      "similarity_score": 78
    }
  ]
}
```

**Response Fields (per video)**

| Field | Type | Description |
| --- | --- | --- |
| video_id | string | YouTube video ID |
| title | string | Video title |
| channel_name | string | Channel name |
| channel_id | string | YouTube channel ID |
| view_count | integer | Total video views |
| thumbnail_url | string | Video thumbnail URL |
| url | string | Full YouTube URL |
| subscriber_count | integer | Channel subscriber count |
| similarity_score | integer | Visual similarity score (0–100). Higher = more similar thumbnail. |
