# Snapchat Spotlight Hashtag Video Extractor (`vexaloom-labs/snapchat-spotlight-hashtag-video-extractor`) Actor

Pull Snapchat Spotlight videos published under a hashtag or topic, with engagement stats, creator details, AI-generated descriptions and related topic tags.

- **URL**: https://apify.com/vexaloom-labs/snapchat-spotlight-hashtag-video-extractor.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Social media, Videos, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Snapchat Spotlight Hashtag Video Extractor

Snapchat's public Spotlight surface publishes short videos under hashtags, long-tail topic hubs, and an anonymous up-next feed. This actor collects those videos — by hashtag, topic URL, specific Spotlight link, or a paginated feed walk — and returns creator identity, engagement counts, media links, captions, hashtags, Snapchat's AI metadata, and hashtag context. No Snapchat account, cookie, API key, or proxy is needed.

### Modes

| Mode | What it collects | Input |
|---|---|---|
| **Hashtag or topic videos** | One combined, deduplicated pool per hashtag: the tag page (about 28-32 videos) plus Explore results when Snapchat serves them, with optional video-detail enrichment | `hashtags` |
| **Paginated Spotlight feed** | The anonymous Spotlight up-next feed, page by page, until `feedPages` or `maxItems` is reached | `feedPages`, optional `spotlightUrls` seed |
| **Specific Spotlight URLs** | One row per public Spotlight link or raw Snap ID | `spotlightUrls` |

Tag pages do not paginate (`?page`, `?cursor`, `?offset`, `?limit` are ignored by Snapchat), so hashtag mode widens coverage by combining the tag page with Explore when it is available and — when enabled — enriching each video from Snapchat's public `fetchSpotlight` endpoint. Explore is best-effort: Snapchat sometimes returns 404 for `/explore/<query>`, in which case the tag page is still returned. Feed mode uses the same up-next API the public Spotlight viewer calls.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `hashtagFeed` | `hashtagFeed`, `spotlightFeed`, or `spotlightUrls` |
| `hashtags` | array | `[]` | Bare words, `#tags`, Snapchat tag/topic/Explore paths or URLs, or a Spotlight video URL |
| `resultsPerHashtag` | integer | `50` | Keep up to this many videos per hashtag after merge (1-200) |
| `includeVideoUrls` | boolean | `true` | Include watermarked and unwatermarked MP4 CDN links |
| `includeRelatedTopics` | boolean | `true` | Include related topics, related hashtags, and S2I tags |
| `includeLlmMetadata` | boolean | `true` | Include Snapchat AI title, description, and keywords |
| `includeHashtagMetadata` | boolean | `true` | Include hashtag id/name/URL/source/description/video count |
| `enrichDetails` | boolean | `true` | Batch-fetch public video details (unwatermarked URL, hashtags, AI metadata, exact counts) |
| `spotlightUrls` | array | `[]` | Spotlight links/IDs for URL mode, or an optional feed seed |
| `feedPages` | integer | `5` | Up-next pages to request in feed mode (1-50, about 20-23 videos/page) |
| `maxItems` | integer | `1000` | Hard cap on total rows (1-10,000) |
| `minViews` | integer | `0` | Keep videos with at least this many views |
| `minLikes` | integer | `0` | Keep videos with at least this many likes |
| `sinceDate` | string | `""` | Keep videos uploaded on or after `YYYY-MM-DD` |
| `sortBy` | select | `source` | Order within each hashtag group: `source`, `newest`, `mostViewed`, or `mostLiked` |

#### Example: one hashtag

```json
{
  "mode": "hashtagFeed",
  "hashtags": ["food"],
  "resultsPerHashtag": 50,
  "maxItems": 50
}
```

#### Example: several hashtags with a view filter

```json
{
  "mode": "hashtagFeed",
  "hashtags": ["#travel", "humor", "https://www.snapchat.com/topic/cappuccino-foam-technique"],
  "resultsPerHashtag": 40,
  "minViews": 10000,
  "sortBy": "mostViewed",
  "maxItems": 100
}
```

#### Example: paginated Spotlight feed

```json
{
  "mode": "spotlightFeed",
  "feedPages": 5,
  "maxItems": 75
}
```

#### Example: specific Spotlight videos

```json
{
  "mode": "spotlightUrls",
  "spotlightUrls": [
    "https://www.snapchat.com/@sema_janu/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYYm1lZmlnbGh2AZ_JQccIAZ_JQLedAAAAAQ",
    "W7_EDlXWTBiXAEEniNoMPwAAYZWF3aHF1eGNoAZ7bAR9JAZ7bAR8hAAAAAQ"
  ]
}
```

### Output

Each row is one Spotlight video.

- `snap_id`, `story_id`, `composite_story_id`, `story_subtype`, `snap_url` — Snapchat identifiers and public URL
- `video_url`, `video_url_unwatermarked`, `thumbnail_url`, `video_thumbnail_url`, `large_thumbnail_url`, `embed_url` — media links (CDN tokens expire)
- `duration_seconds`, `width`, `height`, `encoding_format` — media facts
- `creator_username`, `creator_display_name`, `creator_profile_url` — creator identity
- `view_count`, `like_count`, `share_count`, `comment_count`, `pending_comment_count`, `remix_count`, `recommend_count`, `rewatch_count`, `screenshot_count`, `score` — engagement and ranking signals
- `description`, `caption`, `keywords`, `hashtags`, `sub_titles`, `attachment_url` — text content
- `upload_date`, `latest_update_at`, `scraped_at` — ISO 8601 UTC timestamps
- `llm_title`, `llm_description`, `llm_keywords`, `s2i_tags`, `detected_language` — Snapchat AI and content classification
- `sound_title`, `sound_artist`, `sound_thumbnail_url` — sound context when Snapchat exposes it
- `searched_hashtag`, `hashtag_id`, `hashtag_name`, `hashtag_url`, `hashtag_source`, `hashtag_description`, `hashtag_video_count` — hashtag/topic context
- `related_topics`, `related_s2i_tags`, `related_hashtags` — related topic graph and Explore topic rows
- `record_type`, `source_type`, `rank`, `feed_page` — provenance (which surface produced the row)

Empty fields are omitted, never written as `null`, `""`, `[]`, or `{}`. A field is present only when Snapchat actually supplied it.

### Use cases

- **Trend research** — see which Spotlight videos a hashtag is pushing right now
- **Creator discovery** — find active creators in a niche with exact view/like/share counts
- **Social listening** — repeat runs to track engagement movement for the same videos
- **Brand-safety review** — scan `s2i_tags`, `hashtags`, and AI descriptions before associating a campaign with a hashtag
- **Media archiving** — collect CDN MP4 and thumbnail links for a bounded set of videos

### FAQ

**Do I need a Snapchat account, cookies, or a proxy?**
No. Every surface used here is public and server-rendered, and the actor sends plain HTTP requests with no login, cookie jar, API key, or proxy configuration.

**Why does hashtag mode return about 30-50 videos and not thousands?**
Snapchat's tag pages cap at roughly 28-32 cards and the public tag page ignores page/cursor/offset parameters. Explore adds about 20-25 more with little overlap when Snapchat serves it, so the merged pool is usually about 40-55. This actor does not invent pagination that Snapchat does not expose. Use `spotlightFeed` mode for open-ended pagination, or run several related hashtags.

**How does `spotlightFeed` paginate?**
It starts from a public Spotlight video and repeatedly calls Snapchat's up-next endpoint with the last video ID and the accumulated `tapStoryKey` values, exactly as the public viewer does. `feedPages` bounds the walk and `maxItems` caps the output.

**Why are some videos missing `video_url_unwatermarked`?**
Not every tag-page card includes the clean flat URL. `enrichDetails` batch-fetches Snapchat's public detail endpoint to fill it when available; some videos still only have the watermarked URL.

**How long do video and thumbnail links stay valid?**
They carry Snapchat CDN tokens. Treat them as short-lived: download or re-host media soon after scraping.

**Why do some rows have no `description` or `caption`?**
Feed and detail cards do not always expose creator text; those rows keep the AI `llm_description` and omit `description` rather than fabricating one.

**Can I pass `#food` and a full tag URL?**
Yes. `food`, `#food`, `https://www.snapchat.com/tag/food`, and topic/Explore URLs are all accepted. A full Spotlight video link is also accepted in `hashtags` and is routed to the video-detail path.

**What happens to my old input?**
The legacy keys `hashtags`, `resultsPerHashtag`, `includeVideoUrls`, `includeRelatedTopics`, and `includeLlmMetadata` still work. Old-style inputs that omit `mode` run in hashtag mode. An old `proxyConfiguration` key is accepted but ignored.

### Limitations

- Tag pages are capped by Snapchat (about 28-32 videos) and do not paginate. Hashtag mode combines tag + Explore when Explore is available and is intentionally bounded by `resultsPerHashtag`.
- Snapchat intermittently returns 404 for `/explore/<query>`; the actor treats that as a missing surface and returns the tag/topic page rows instead of failing.
- `spotlightFeed` follows Snapchat's up-next recommendations; it is a discovery feed, not a hashtag-filtered feed. Rows carry `source_type=spotlightFeed` so they can be filtered.
- Comment text and transcripts are not collected; only public engagement counts and metadata are included.
- Media URLs are signed by Snapchat and can expire. The actor does not re-host media.
- Feed and detail responses vary by country and can omit fields; those fields are omitted per record.
- With several hashtags, rows stay grouped in input order; `sortBy` orders videos within each hashtag group (feed mode sorts the entire feed).

# Actor input Schema

## `mode` (type: `string`):

Choose what to collect: videos for hashtags/topics, a paginated Spotlight feed, or specific Spotlight URLs.

## `hashtags` (type: `array`):

Used in Hashtag or topic videos mode. Bare words (food), hash-prefixed tags (#travel), path forms (/tag/food, /topic/cappuccino-foam-technique), or full Snapchat URLs (https://www.snapchat.com/tag/food, https://www.snapchat.com/topic/cappuccino-foam-technique).

## `resultsPerHashtag` (type: `integer`):

Maximum videos to keep for each hashtag after combining the tag/topic page with Explore results. Snapchat serves about 32 videos per tag page plus about 20-25 Explore cards.

## `includeVideoUrls` (type: `boolean`):

Include the watermarked and unwatermarked MP4 CDN URLs. These URLs carry expiring Snapchat tokens, so download or re-host media soon after scraping.

## `includeRelatedTopics` (type: `boolean`):

Include related topics, related hashtags, and scene-to-interest (S2I) content tags when the page provides them.

## `includeLlmMetadata` (type: `boolean`):

Include Snapchat's AI-generated title, description, and keywords when present.

## `includeHashtagMetadata` (type: `boolean`):

Include hashtag identity fields (id, name, URL, source, description, and total video count when Snapchat exposes it) in every record.

## `enrichDetails` (type: `boolean`):

Batch-fetch Snapchat's public video details endpoint to fill unwatermarked MP4 URLs, hashtags, AI metadata, duration, and exact engagement counts. Adds one request per 30 videos.

## `spotlightUrls` (type: `array`):

Used in Specific Spotlight URLs mode, or as the optional first seed in Paginated Spotlight feed mode. Accepts full Spotlight links (https://www.snapchat.com/@user/spotlight/ID), /spotlight/ID links, or raw IDs.

## `feedPages` (type: `integer`):

How many pages of the Spotlight up-next feed to request in Paginated Spotlight feed mode. Each page adds about 20-23 videos; pagination stops early when Snapchat runs out.

## `maxItems` (type: `integer`):

Hard cap on the total number of video rows saved across the whole run.

## `minViews` (type: `integer`):

Keep only videos with at least this many views. Use 0 to keep everything.

## `minLikes` (type: `integer`):

Keep only videos with at least this many likes. Use 0 to keep everything.

## `sinceDate` (type: `string`):

Keep only videos uploaded on or after this date. Use YYYY-MM-DD (for example 2026-01-01). Leave empty to keep all dates.

## `sortBy` (type: `string`):

Order within each hashtag/topic group. Hashtags stay in the order you enter them; feed mode sorts the whole feed. Source order keeps Snapchat's own ranking.

## Actor input object example

```json
{
  "mode": "hashtagFeed",
  "hashtags": [
    "food"
  ],
  "resultsPerHashtag": 3,
  "includeVideoUrls": true,
  "includeRelatedTopics": false,
  "includeLlmMetadata": true,
  "includeHashtagMetadata": true,
  "enrichDetails": false,
  "spotlightUrls": [],
  "feedPages": 2,
  "maxItems": 3,
  "minViews": 0,
  "minLikes": 0,
  "sinceDate": "",
  "sortBy": "source"
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset with scraped Snapchat Spotlight videos

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "hashtagFeed",
    "hashtags": [
        "food"
    ],
    "resultsPerHashtag": 3,
    "includeVideoUrls": true,
    "includeRelatedTopics": false,
    "includeLlmMetadata": true,
    "includeHashtagMetadata": true,
    "enrichDetails": false,
    "spotlightUrls": [],
    "feedPages": 2,
    "maxItems": 3,
    "minViews": 0,
    "minLikes": 0,
    "sinceDate": "",
    "sortBy": "source"
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/snapchat-spotlight-hashtag-video-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "hashtagFeed",
    "hashtags": ["food"],
    "resultsPerHashtag": 3,
    "includeVideoUrls": True,
    "includeRelatedTopics": False,
    "includeLlmMetadata": True,
    "includeHashtagMetadata": True,
    "enrichDetails": False,
    "spotlightUrls": [],
    "feedPages": 2,
    "maxItems": 3,
    "minViews": 0,
    "minLikes": 0,
    "sinceDate": "",
    "sortBy": "source",
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/snapchat-spotlight-hashtag-video-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "hashtagFeed",
  "hashtags": [
    "food"
  ],
  "resultsPerHashtag": 3,
  "includeVideoUrls": true,
  "includeRelatedTopics": false,
  "includeLlmMetadata": true,
  "includeHashtagMetadata": true,
  "enrichDetails": false,
  "spotlightUrls": [],
  "feedPages": 2,
  "maxItems": 3,
  "minViews": 0,
  "minLikes": 0,
  "sinceDate": "",
  "sortBy": "source"
}' |
apify call vexaloom-labs/snapchat-spotlight-hashtag-video-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/snapchat-spotlight-hashtag-video-extractor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/PRHVlSkm14JTKundY/builds/Y6tGkzMqVIlFeVcQD/openapi.json
