# Snapchat Spotlight Video Transcript Extractor (`xyrelith-data/snapchat-spotlight-video-transcript-extractor`) Actor

Turn Snapchat Spotlight video URLs into timestamped transcripts, using native captions when Snapchat provides them and AI speech recognition otherwise, plus duration, caption and upload metadata.

- **URL**: https://apify.com/xyrelith-data/snapchat-spotlight-video-transcript-extractor.md
- **Developed by:** [Xyrelith Data](https://apify.com/xyrelith-data) (community)
- **Categories:** Social media, Videos, Automation
- **Features:** Limited permissions
- **Stats:** 1 total users, 0 monthly users, 0.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 Video Transcript Extractor

Public Snapchat Spotlight clips carry spoken words that Snapchat does not always show as text in a reusable form. This actor returns a clean transcript for each clip — first trying the caption track Snapchat already published, then, when asked, generating one from the audio with speech recognition.

You can feed it exact Spotlight links, a creator's pinned Spotlight videos, a hashtag page, or a country's trending Spotlight feed. Every row also includes the creator, engagement counts, video timing and thumbnail so the transcript can be joined to the rest of your data.

### What you get

- **Published captions when available.** Snapchat exposes a WebVTT caption file for many videos. The actor downloads it, parses the cue timings, and returns both `segments` and the concatenated `fullText`.
- **Speech recognition as a fallback.** For videos without published captions, `auto` mode transcribes the audio with Whisper. Three model sizes trade speed for accuracy.
- **Four ways to choose videos.** Paste links, pull a creator's pinned Spotlight highlights, browse a hashtag, or page through a country feed.
- **Metadata alongside text.** Creator handle and display name, avatar, title, description, embedded caption, keywords, hashtags, duration, upload date, resolution, and view/share/comment/like counts.
- **Smaller datasets on demand.** Turn off timed segments to keep `fullText`, `wordCount` and `segmentCount` without the per-cue array.
- **Clean rows.** Empty values are omitted instead of written as `null`, and each row carries `recordType`, `sourceUrl` and `scrapedAt`.

### Modes

| Mode | What it reads | Typical input |
|---|---|---|
| `bySpotlightUrls` | The exact videos you paste | `https://www.snapchat.com/spotlight/<id>`, `https://www.snapchat.com/@user/spotlight/<id>`, `https://t.snapchat.com/<code>`, or a bare snap ID |
| `byUsername` | A public creator's pinned Spotlight highlights | `brentrivera`, `@brentrivera`, `https://www.snapchat.com/@brentrivera` |
| `byTopic` | Videos listed on a hashtag page | `comedy`, `#comedy`, `https://www.snapchat.com/tag/comedy` |
| `byFeed` | A country's trending Spotlight feed, 25 videos per page | `US`, `GB`, `PK` |

Discovery modes stop after `maxVideosPerSource` videos per handle, hashtag or feed. `maxItems` caps the total number of rows in the run.

### Output fields

| Field | Description |
|---|---|
| `recordType` | Always `spotlightTranscript` |
| `snapId` | Spotlight snap ID |
| `sourceUrl` | Canonical Snapchat page for the video |
| `mode` | `bySpotlightUrls`, `byUsername`, `byTopic` or `byFeed` |
| `inputUrl` | The link you supplied (paste-URL mode only) |
| `discoveredVia` | Handle, hashtag or country that surfaced the video (discovery modes only) |
| `title` | Snapchat's generated title, when present |
| `description` | Snapchat's generated description, when present |
| `caption` | Caption embedded in the video |
| `username` | Creator's Snapchat handle |
| `creatorName` | Creator's display name |
| `creatorUrl` | Creator profile link |
| `creatorAvatarUrl` | Creator avatar image link |
| `videoUrl` | Direct CDN video link (may expire) |
| `thumbnailUrl` | Thumbnail image link |
| `durationSeconds` | Video length in seconds |
| `uploadedAt` | Upload time, ISO 8601 UTC |
| `width`, `height` | Video dimensions in pixels |
| `keywords` | Keywords Snapchat associates with the video |
| `hashtags` | Hashtag entries from the keyword list |
| `viewCount`, `shareCount`, `commentCount`, `likeCount` | Public engagement counts at scrape time |
| `transcriptSource` | `native` for published captions, `whisper` for generated text |
| `transcriptAvailable` | Whether a usable transcript was produced |
| `transcriptUrl` | WebVTT caption file link, when one exists |
| `language` | `en` for published captions; detected or hinted code for generated transcripts |
| `languageProbability` | Language-detection confidence (0-1) for generated transcripts |
| `whisperModel` | Model size used for generated transcripts |
| `segments` | Timed cues: `[{startTime, endTime, text}]` |
| `segmentCount` | Number of cues |
| `fullText` | Whole transcript as one string |
| `wordCount` | Word count of `fullText` |
| `scrapedAt` | When the row was produced, ISO 8601 UTC |
| `error` | Explanation when fetching or transcription failed for that row |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `bySpotlightUrls` | Which discovery path to use. |
| `spotlightUrls` | array | – | Links or IDs; required when `mode` is `bySpotlightUrls`. |
| `usernames` | array | – | Creator handles; used when `mode` is `byUsername`. |
| `topics` | array | – | Hashtags or topics; used when `mode` is `byTopic`. |
| `country` | string | `US` | Two-letter feed country; used when `mode` is `byFeed`. |
| `transcriptionMethod` | string | `auto` | `auto`, `native` or `whisper`. |
| `whisperModel` | string | `base` | `tiny`, `base` or `small`. |
| `language` | string | `auto` | Optional language hint for speech recognition. |
| `includeSegments` | boolean | `true` | Include the timed `segments` array. |
| `maxItems` | integer | `100000` | Maximum rows to push, including error rows. |
| `maxVideosPerSource` | integer | `20` | Videos collected per handle, hashtag or feed. |

Legacy keys from the previous version (`spotlightUrl`, `urls`, `startUrls`, `maxResults`, `method`, `model`) are still accepted and mapped to the current fields when the new key is absent.

#### Paste a handful of links

```json
{
  "mode": "bySpotlightUrls",
  "spotlightUrls": [
    "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYYmViYXF5amNyAZXOAULlAZXOAOzLAAAAAQ",
    "https://t.snapchat.com/example"
  ],
  "maxItems": 5
}
```

#### Transcribe a creator's pinned Spotlight videos

```json
{
  "mode": "byUsername",
  "usernames": ["brentrivera"],
  "maxVideosPerSource": 10,
  "transcriptionMethod": "auto"
}
```

#### Browse a hashtag with a fixed transcript style

```json
{
  "mode": "byTopic",
  "topics": ["comedy"],
  "maxVideosPerSource": 20,
  "transcriptionMethod": "whisper",
  "whisperModel": "small",
  "language": "en"
}
```

#### Page a country feed

```json
{
  "mode": "byFeed",
  "country": "GB",
  "maxVideosPerSource": 50,
  "includeSegments": false
}
```

### How it reads Snapchat

All requests are anonymous: no login, cookie, API key or proxy account is needed. The actor reads the public video page, its embedded Schema.org `VideoObject` data, the published WebVTT caption file, and the public Spotlight discovery surfaces (profile highlights, tag pages and the feed's public GraphQL query). When a page is unavailable, the transcript endpoint for that snap ID is used as a fallback.

### Limits and notes

- Published captions exist only for some videos. In a mixed 34-video probe, 8 had native captions; the rest need `auto` or `whisper` if you want text.
- Native captions are returned with `language: en`, matching Snapchat's published caption behaviour.
- Creator mode uses pinned Spotlight highlights (usually around 16 videos), not a creator's complete posting history.
- Tag pages usually list 20-35 videos; feed pages return 25 videos per page and are paged until `maxVideosPerSource` is reached.
- CDN video and thumbnail links can expire. Re-run the actor or copy the files if you need durable media.
- A video with no speech, only music, or very low confidence returns `transcriptAvailable: false` plus an `error` instead of invented text.
- A removed, expired or region-blocked clip returns a row with `transcriptAvailable: false` and an explanatory `error`.
- Follower counts, sound/lens names and recommendation counts are not published on the clip page, so they are not returned.
- Comments, downloads, private profiles and login-gated content are outside this actor's scope.

### FAQ

#### Do I need a Snapchat account?

No. The actor only reads public pages and public caption files.

#### What happens when a video has no published captions?

With `auto`, the actor downloads the video and runs speech recognition. With `native`, it returns `transcriptAvailable: false` and explains why.

#### Which Whisper model should I pick?

`base` is the usual choice. `tiny` is faster and cheaper for clear speech. `small` helps with accents and non-English audio.

#### Can I request transcripts in a particular language?

Set `language` to an ISO 639-1 code for speech recognition. Published captions are returned as Snapchat provides them.

#### Why is a transcript missing segments?

The video may have text but no caption file, or you may have turned off `includeSegments`. `fullText`, `wordCount` and `segmentCount` remain available.

#### Are results identical on every run?

Transcript text and metadata are stable, but engagement counters and CDN links change over time, and discovery modes can surface a slightly different set as feeds rotate.

# Actor input Schema

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

Choose how to find Spotlight videos. Paste links, pull a creator's pinned Spotlight videos, browse a hashtag, or page through a country's trending Spotlight feed.

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

Required when mode is 'Spotlight URLs or IDs'. Accepts snapchat.com/spotlight/... links, profile-scoped @user/spotlight links, t.snapchat.com short links, and bare snap IDs.

## `usernames` (type: `array`):

Used when mode is 'Creator handle'. One or more public Snapchat handles, with or without '@'. The actor reads the creator's pinned Spotlight videos.

## `topics` (type: `array`):

Used when mode is 'Hashtag'. One or more hashtags, with or without '#', or /tag/ and /explore/ links.

## `country` (type: `string`):

Used when mode is 'Trending feed'. Two-letter country code that selects the regional Spotlight feed.

## `transcriptionMethod` (type: `string`):

'Auto' uses Snapchat's published captions first and falls back to speech recognition. 'Native only' never runs AI. 'Whisper only' ignores published captions.

## `whisperModel` (type: `string`):

AI model size used when speech recognition runs. Larger models are slower but better with accents and non-English speech.

## `language` (type: `string`):

Optional language for speech recognition. 'Auto-detect' is best for most runs; pick a language when the audio is clearly non-English.

## `includeSegments` (type: `boolean`):

When on, each record includes the timestamped 'segments' array. Turn it off for a smaller dataset; 'fullText', 'wordCount' and 'segmentCount' are still returned.

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

Stop after this many transcript records. The limit counts pushed rows, including failed-input rows.

## `maxVideosPerSource` (type: `integer`):

How many videos to collect from each handle, hashtag or trending feed before moving on. Paste-URL mode is not affected by this cap.

## Actor input object example

```json
{
  "mode": "bySpotlightUrls",
  "spotlightUrls": [
    "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYYmViYXF5amNyAZXOAULlAZXOAOzLAAAAAQ"
  ],
  "country": "US",
  "transcriptionMethod": "auto",
  "whisperModel": "base",
  "language": "auto",
  "includeSegments": true,
  "maxItems": 1,
  "maxVideosPerSource": 1
}
```

# Actor output Schema

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

Dataset containing transcript records

# 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": "bySpotlightUrls",
    "spotlightUrls": [
        "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYYmViYXF5amNyAZXOAULlAZXOAOzLAAAAAQ"
    ],
    "country": "US",
    "transcriptionMethod": "auto",
    "whisperModel": "base",
    "language": "auto",
    "includeSegments": true,
    "maxItems": 1,
    "maxVideosPerSource": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("xyrelith-data/snapchat-spotlight-video-transcript-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": "bySpotlightUrls",
    "spotlightUrls": ["https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYYmViYXF5amNyAZXOAULlAZXOAOzLAAAAAQ"],
    "country": "US",
    "transcriptionMethod": "auto",
    "whisperModel": "base",
    "language": "auto",
    "includeSegments": True,
    "maxItems": 1,
    "maxVideosPerSource": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("xyrelith-data/snapchat-spotlight-video-transcript-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": "bySpotlightUrls",
  "spotlightUrls": [
    "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYYmViYXF5amNyAZXOAULlAZXOAOzLAAAAAQ"
  ],
  "country": "US",
  "transcriptionMethod": "auto",
  "whisperModel": "base",
  "language": "auto",
  "includeSegments": true,
  "maxItems": 1,
  "maxVideosPerSource": 1
}' |
apify call xyrelith-data/snapchat-spotlight-video-transcript-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xyrelith-data/snapchat-spotlight-video-transcript-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/DqbsMlefjDv9CrR46/builds/fEBA5L0ln2HYivGyi/openapi.json
