# Snapchat Discover Publisher Show Extractor (`nimbryxo-studio/snapchat-discover-publisher-show-extractor`) Actor

Pull the publisher shows currently featured on Snapchat's Discover feed, with each show's creator profile, cover art, publish time and a preview snap's media link.

- **URL**: https://apify.com/nimbryxo-studio/snapchat-discover-publisher-show-extractor.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (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 Discover Publisher Show Extractor

Read Snapchat's public Discover surface without a Snapchat account. This actor collects the current Discover feed for a chosen country and locale, looks up publisher and show pages, expands a show's full season history, and pulls the snaps and HLS video URL of individual episodes.

Everything is read from public, anonymous web endpoints. No cookies, login, API key, or proxy setup is needed.

### What this actor does

- **Three modes** - the Discover feed, publisher/show profiles, or individual episode pages
- **Country and locale aware** - choose from 249 countries and 61 Snapchat locales
- **Story filters** - shows, public user stories, publishers or all
- **Publisher depth** - profile, subscriber count, seasons, latest episodes and optional full history
- **Episode media** - HLS playback URLs and every snap preview, with optional per-episode enrichment
- **Reliable pagination** - tap-ID cursor pagination with retries, host fallback, a circuit breaker and migration-safe state
- **Empty fields are omitted** - never `null`, blank or placeholder values

### Data source

Snapchat serves Discover as a server-rendered page plus a public web GraphQL endpoint used by its own web player. This actor reads both:

- `snapchat.com/discover` for a small embedded snapshot (used as an automatic fallback)
- the public web-stories GraphQL endpoint for the paginated Discover feed, publisher season lists, and episode media
- `snapchat.com/p/<publisherId>` for publisher profiles and the latest episodes

All requests are ordinary HTTP requests from the actor container. Media links point at Snapchat's public CDN and were verified to return `200` from a clean client.

### Modes

| Mode | What you get | Typical input |
|---|---|---|
| `discover` (default) | One row per story currently in the Discover feed. Shows include the episode title, creator profile, preview snap, and HLS track. | `country`, `locale`, `storyTypes`, `maxStories` |
| `byPublisher` | One row per publisher/show: profile, subscriber count, season summary, the latest episodes, and optionally every episode in every season plus episode media. | `publisherUrlsOrIds`, `includeEpisodes`, `maxEpisodesPerPublisher`, `includeEpisodeMedia` |
| `byEpisodeUrl` | One row per episode URL with publisher context, every snap preview, and the playable HLS URL. | `episodeUrls` |

The Discover feed is paginated automatically: the actor keeps requesting the next batch and stops at `maxStories`, when Snapchat returns no new stories, or when the safety round limit is reached.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `discover` | Which surface to collect. |
| `maxStories` | integer (1-500) | `50` | Maximum records pushed. Discover stories, publisher rows, and episode rows all count one each. |
| `country` | select | `US` | ISO 3166-1 alpha-2 country context. All countries are listed. |
| `locale` | select | `en-US` | Language and region hint for the Discover feed (61 common Snapchat locales). |
| `storyTypes` | select | `all` | `all`, `shows`, `publicUserStories`, or `publishers`. Discover mode only. |
| `publisherUrlsOrIds` | string list | `[]` | Publisher/show page URLs, `story.snapchat.com` links, or bare business profile UUIDs. `byPublisher` only. |
| `episodeUrls` | string list | `[]` | Episode URLs shaped like `snapchat.com/p/<publisherId>/<storyId>`. `byEpisodeUrl` only. |
| `includeEpisodes` | boolean | `false` | Expand every season into its full episode list. `byPublisher` only. |
| `maxEpisodesPerPublisher` | integer (1-2000) | `100` | Episode cap across all seasons of one publisher. |
| `includeEpisodeMedia` | boolean | `false` | Fetch each episode's snap list and HLS URL. `byPublisher` only. |
| `proxyConfiguration` | proxy | empty | Optional advanced override. Leave empty; the actor works without a proxy. |

#### Example: Discover feed

```json
{
  "mode": "discover",
  "country": "US",
  "locale": "en-US",
  "storyTypes": "shows",
  "maxStories": 40
}
```

#### Example: publisher with full episode history

```json
{
  "mode": "byPublisher",
  "publisherUrlsOrIds": ["https://www.snapchat.com/p/efd8a13d-b69a-41d0-9c04-d19f87829798"],
  "includeEpisodes": true,
  "maxEpisodesPerPublisher": 80
}
```

#### Example: one episode

```json
{
  "mode": "byEpisodeUrl",
  "episodeUrls": ["https://www.snapchat.com/p/dcb36ae8-b313-4eef-b24c-ccc20fe4d872/3137397659916288"]
}
```

### Output per record type

The dataset contains one object per record. Every record has a `recordType`, a `sourceUrl`, and a `scrapedAt` timestamp. Empty fields are omitted instead of written as `null`.

#### `recordType: "discoverStory"`

| Field | Description |
|---|---|
| `storyKey`, `storyId`, `storyType`, `title`, `tapId` | Story identity and type (`SHOW`, `PUBLIC_USER_STORY`, or `PUBLISHER`). `storyKey` is the unique feed key; `storyId` is Snapchat's story ID and equals the creator's username for public user stories, so it can repeat when one creator has several stories in the feed. |
| `thumbnailUrl` | Cover image URL. |
| `publishedAt` | Publish time in ISO 8601 UTC. |
| `videoTrackUrl` | HLS playlist for show episodes. |
| `creator` | `businessProfileId`, `title`, `bio`, `username`, `badge`, profile images, `primaryColor`. |
| `previewSnap` | `snapId`, `mediaUrl`, `mediaPreviewUrl`, `mediaType`, `index`. |
| `totalSnaps` | Number of snaps in the story. |

#### `recordType: "publisher"`

| Field | Description |
|---|---|
| `publisherId`, `publisherTitle`, `publisherUrl` | Publisher identity and public page. |
| `bio`, `subscriberCount`, `publisherType`, `username`, `badge` | Profile metadata. |
| `profilePictureUrl`, `squareHeroImageUrl`, `snapcodeImageUrl`, `primaryColor` | Brand images and color. |
| `websiteUrl` | Present only when the profile lists one. |
| `seasonCount`, `seasons` | Season IDs, season numbers, declared episode counts, and actual counts when expanded. |
| `declaredEpisodeCount` | Sum of the season list's declared counts. |
| `latestEpisodes` | The 13-14 latest episodes embedded in the page. |
| `episodes`, `episodesReturned` | Full season history and its size when `includeEpisodes` is on. |
| `episode objects` | `storyId`, `title`, `storyType`, `thumbnailUrl`, `videoTrackUrl`, `publishedAt`, `seasonNumber`, `episodeNumber`, `storyUrl`; with `includeEpisodeMedia`: `snapCount` and `snaps[]`. |

#### `recordType: "episode"`

| Field | Description |
|---|---|
| `storyId`, `title`, `storyType`, `storyUrl` | Episode identity. |
| `publisherId`, `publisherTitle` | Publisher context. |
| `seasonNumber`, `episodeNumber` | Present when the publisher page exposes them. |
| `thumbnailUrl`, `videoTrackUrl` | Cover image and playable HLS URL. |
| `snapCount`, `snaps` | Each snap's `snapId`, `index`, `mediaType`, `mediaUrl`, `mediaPreviewUrl`, `intervalStartTimeMs`. |

#### `recordType: "error"`

Invalid or unavailable inputs produce a diagnostic row instead of failing the run:

```json
{
  "recordType": "error",
  "status": "not_found",
  "message": "Snapchat has no public publisher page for this ID.",
  "sourceUrl": "https://www.snapchat.com/p/3c33e049-a638-4b4e-9960-78a2b87a9992",
  "scrapedAt": "2026-11-11T14:00:00+00:00"
}
```

### Use cases

- **Media monitoring** - track which publishers and shows are on Discover
- **Publisher research** - profile publishers, their subscriber counts and season output
- **Content benchmarking** - compare show formats, episode cadence and media availability
- **Trend analysis** - collect regional Discover feeds over time
- **Episode and media archives** - resolve episode pages into snap previews and HLS playback URLs

### FAQ

**Do I need a Snapchat account, cookies, or a proxy?**
No. Every surface used here is public and works anonymously. The optional proxy field exists only for users who want a specific connection.

**Why does the Discover feed return fewer rows than `maxStories`?**
The feed is finite and changes constantly. The actor keeps paginating until Snapchat returns no new stories. A run that asks for 500 rows can legitimately end with the size of the current feed.

**Why do some publisher IDs return a `not_found` error?**
Discover contains public user stories and retired shows that do not have a publisher page. The actor reports the missing page per input and continues with the remaining inputs.

**Why is `videoTrackUrl` missing from some publisher season rows?**
Snapchat's season list does not include the HLS track. Enable `includeEpisodeMedia` to fetch each episode's media detail, or use `byEpisodeUrl` for a single episode.

**Can I get every episode of a long-running show?**
Yes. Set `includeEpisodes` to `true` and raise `maxEpisodesPerPublisher`. The actor walks each season's cursor. A small number of rows can differ from the season list's declared count because Snapchat's declaration and its episode endpoint do not always agree.

**Are the media URLs permanent?**
They are public CDN URLs that returned `200` during verification. Snapchat may rotate or expire individual assets; the actor stores the URL it received, not a copy of the media.

### Limitations

- Discover availability and publisher pages depend on the country context. Some pages answer `451` (region-restricted); the actor reports that as an error row.
- Per-snap `mediaUrl` is populated by Snapchat for only a small subset of snaps (usually the first snaps of an episode). Preview images are available for almost every snap.
- Publisher season lists occasionally declare more episodes than the season endpoint returns. The actor reports both numbers.
- Snapchat's web GraphQL schema is undocumented and can change. The `/discover` server-rendered snapshot is kept as an automatic fallback, but it only carries a small number of stories.
- Spotlight posts, creator profiles, comments, and transcripts are separate surfaces and are not part of this actor.

# Actor input Schema

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

What to collect: the current Discover feed, publisher/show profiles, or individual episode URLs.

## `maxStories` (type: `integer`):

Maximum dataset records this run may push. In Discover mode this counts stories; in the other modes it counts publisher or episode records. Nested episode lists are not counted separately.

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

ISO 3166-1 alpha-2 country context used for the Discover feed and episode requests. Availability is set by Snapchat and some publishers are region-restricted.

## `locale` (type: `string`):

Language and region hint for the Discover feed, for example en-US or de-DE. Snapchat decides which stories match.

## `storyTypes` (type: `string`):

(mode=discover) Keep every story, only publisher shows, only public user stories, or only publisher stories.

## `publisherUrlsOrIds` (type: `array`):

(mode=byPublisher) Publisher or show page URLs (snapchat.com/p/<id>), story.snapchat.com links, or bare businessProfileId UUIDs. One record is produced per publisher, with the latest episodes nested inside.

## `episodeUrls` (type: `array`):

(mode=byEpisodeUrl) Episode page URLs of the form snapchat.com/p/<publisherId>/<storyId>. Each URL returns one episode record with its snap list and playable HLS URL.

## `includeEpisodes` (type: `boolean`):

(mode=byPublisher) Fetch every season's full episode history instead of only the 13-14 episodes embedded in the page. Adds one request per 50 episodes and respects the episode cap.

## `maxEpisodesPerPublisher` (type: `integer`):

(mode=byPublisher with includeEpisodes) Maximum episodes collected across all seasons of one publisher.

## `includeEpisodeMedia` (type: `boolean`):

(mode=byPublisher) Fetch each episode's snap list and HLS video URL. Adds one request per episode; off by default.

## `proxyConfiguration` (type: `object`):

Optional advanced override. The actor works without a proxy; set this only if you want to route requests through a specific Apify Proxy configuration.

## Actor input object example

```json
{
  "mode": "discover",
  "maxStories": 20,
  "country": "US",
  "locale": "en-US",
  "storyTypes": "all",
  "publisherUrlsOrIds": [],
  "episodeUrls": [],
  "includeEpisodes": false,
  "maxEpisodesPerPublisher": 10,
  "includeEpisodeMedia": false
}
```

# Actor output Schema

## `stories` (type: `string`):

Dataset items with recordType=discoverStory: the current Snapchat Discover feed for the selected country and locale.

## `publishers` (type: `string`):

Dataset items with recordType=publisher: profile, season summary, latest episodes, and optional full season history.

## `episodes` (type: `string`):

Dataset items with recordType=episode: one episode per input URL, with its snap list and playable HLS URL.

# 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": "discover",
    "maxStories": 20,
    "country": "US",
    "locale": "en-US",
    "storyTypes": "all",
    "includeEpisodes": false,
    "maxEpisodesPerPublisher": 10,
    "includeEpisodeMedia": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/snapchat-discover-publisher-show-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": "discover",
    "maxStories": 20,
    "country": "US",
    "locale": "en-US",
    "storyTypes": "all",
    "includeEpisodes": False,
    "maxEpisodesPerPublisher": 10,
    "includeEpisodeMedia": False,
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/snapchat-discover-publisher-show-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": "discover",
  "maxStories": 20,
  "country": "US",
  "locale": "en-US",
  "storyTypes": "all",
  "includeEpisodes": false,
  "maxEpisodesPerPublisher": 10,
  "includeEpisodeMedia": false
}' |
apify call nimbryxo-studio/snapchat-discover-publisher-show-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/snapchat-discover-publisher-show-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/7YZlGlAToX668i4b0/builds/ckps3hivvjQEj1a8K/openapi.json
