# 🔥Snapchat Profile Scraper (`aimscrape/snapchat-profile-scraper`) Actor

Extract public Snapchat profile metadata from usernames and profile URLs, including display names, bios, images, subscriber counts, verification, categories, websites, locations, and Snapcodes when available.

- **URL**: https://apify.com/aimscrape/snapchat-profile-scraper.md
- **Developed by:** [AimScrape](https://apify.com/aimscrape) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

### What does Snapchat Profile Scraper do?

**Snapchat Profile Scraper** collects metadata that Snapchat publishes on public
web profiles. Submit known usernames or profile URLs and receive one structured
record per normalized profile, including the display name, bio, images,
subscriber count, verification status, category, website, location, and Snapcode
when Snapchat makes those values available.

The Actor reads signed-out public profile pages. It does not require a Snapchat
login, an OAuth app, or a Snapchat API token. It does not search by display name
or collect Stories, Spotlight posts, Lenses, comments, friend lists, private
content, or account analytics.

### How to scrape Snapchat profiles

1. Open **Input** and add one or more Snapchat usernames or profile URLs.
2. Start the Actor and follow progress in the run log.
3. Open **Profiles** in the **Output** tab.
4. Export the Dataset as JSON, CSV, Excel, or another format supported by Apify.

Use the Actor's **API** tab for programmatic runs and Apify scheduling for
recurring collection. Compare `crawledAt` values across separate runs when
tracking public profile changes.

### Input

```json
{
  "usernames": [
    "@nba",
    "https://www.snapchat.com/@nike"
  ],
  "skipInvalidInputs": true
}
```

`usernames` is required and accepts between **1 and 100,000 entries**.
The previous `profileUrls` field is no longer read; integrations must send
`usernames`.

| Accepted form | Example |
| --- | --- |
| Username | `nba` |
| @username | `@nba` |
| `/add/` profile URL | `https://www.snapchat.com/add/nba` |
| `/@` profile URL | `https://www.snapchat.com/@nba` |

Usernames are 3-15 characters. They must begin with a Latin letter, end with a
letter or digit, and may contain Latin letters, digits, hyphens, underscores,
and periods. Username matching is case-insensitive; normalized output uses
lowercase. A trailing slash is allowed on URLs. Query parameters, fragments,
credentials, other hosts, and other Snapchat paths are not accepted.

Aliases that normalize to the same username are processed once. For example,
`@NBA` and `https://www.snapchat.com/add/nba/` produce one request and one row.
The Actor does not discover a username from a display name.

The Actor fetches Snapchat's current `/@username` public page. Dataset profile
URLs also use this `/@username` form.

The input form first checks that each entry has the basic shape of a bare
username, an `@username`, or one of the supported profile URLs. This broad
check permits letters, digits, periods, underscores, or hyphens in the username
portion without imposing a length limit, so inputs that miss Snapchat's exact
length or first/last character rules can coexist with valid entries. During
startup, the Actor applies the stricter Snapchat rules above before creating
any request. Valid entries continue to scraping. By default,
`skipInvalidInputs` is `true`, so invalid entries are omitted from the Dataset.
Set it to `false` to store one `invalid_input` row per distinct invalid entry;
this does not affect valid entries. When invalid rows are stored, recognizable
credentials in the submitted string are redacted before output.

### What data can the Actor extract?

Every Dataset item contains the same fields. Missing optional values are
explicit `null`; an explicit subscriber count of zero remains `0`.

| Field | Meaning |
| --- | --- |
| `status` | `ok`, `not_found`, `restricted`, or `invalid_input`. |
| `username` | Normalized lowercase Snapchat username resolved from the page; for `invalid_input`, the redacted submitted string. |
| `inputProfileUrl` | Canonical `https://www.snapchat.com/@USERNAME` URL derived from the requested input, or `null` for `invalid_input`. |
| `profileUrl` | Canonical `https://www.snapchat.com/@USERNAME` URL for the resolved profile, or `null` for `invalid_input`. |
| `profileId` | Public business-profile UUID embedded in the page, when available. |
| `displayName` | Name shown on the public profile. |
| `bio` | Public profile bio. |
| `avatarUrl`, `bannerUrl` | Public Snapchat CDN image URLs when supplied by the page. |
| `subscriberCount` | Non-negative public subscriber count when Snapchat publishes it. |
| `verified` | `true` for Snapchat's official badge code, `false` for an explicit no-badge code, or `null` when unknown. |
| `category`, `subcategory` | Public Snapchat category identifiers. |
| `websiteUrl` | HTTPS website published on the profile. |
| `location` | Profile-published location text; it is not inferred. |
| `snapcodeUrl` | Public Snapcode image URL supplied by the profile page. |
| `crawledAt` | UTC ISO 8601 time when the result was normalized. |

Image and Snapcode URLs are upstream assets and may expire or change. Category
values are Snapchat identifiers rather than labels translated by this Actor.
When Snapchat canonically redirects one profile identity to another,
`inputProfileUrl` preserves the requested identity while `username` and
`profileUrl` identify the resolved profile. If no redirect occurred, the two
URL fields are equal.

### Output example

The following is a **synthetic example**, not a live profile record:

```json
{
  "status": "ok",
  "username": "example.user",
  "inputProfileUrl": "https://www.snapchat.com/@example.user",
  "profileUrl": "https://www.snapchat.com/@example.user",
  "profileId": "123e4567-e89b-42d3-a456-426614174000",
  "displayName": "Example Creator",
  "bio": "Synthetic public profile example.",
  "avatarUrl": "https://cf-st.sc-cdn.net/d/synthetic-avatar",
  "bannerUrl": "https://cf-st.sc-cdn.net/d/synthetic-banner",
  "subscriberCount": 12500,
  "verified": false,
  "category": "people",
  "subcategory": "creator",
  "websiteUrl": "https://example.com",
  "location": "Singapore",
  "snapcodeUrl": "https://app.snapchat.com/web/deeplink/snapcode?username=example.user&type=SVG&bitmoji=enable",
  "crawledAt": "2026-10-29T09:00:00Z"
}
```

### Statuses and partial results

| Status | Meaning |
| --- | --- |
| `ok` | The page contains a public profile whose username matches the request, a validated same-origin redirect target, or two trusted canonical profile links that agree with the returned username. |
| `not_found` | Snapchat returned HTTP 404, or its structured page state explicitly identifies the profile as absent. HTTP 404 is accepted without parsing the response body. |
| `restricted` | Page state explicitly identifies a private profile or an age, region, privacy, or access restriction. |
| `invalid_input` | Local validation rejected the submitted value before any network request. |

Challenge pages, consent pages, rate limits, missing state, malformed state, and
unverified identity conflicts are inconclusive. They are retried up to **3
times**, for at most **4 attempts per target**. A fresh client and proxy
assignment are used for each retry. When all attempts fail, the target is
counted as failed in the log and no Dataset row is fabricated. Proxy URLs do
not request sticky provider sessions; connection reuse is bounded by the
client pool and failed clients are retired before retrying.

Snapchat can change its public page format or vary access by location. A missing
subscriber count or other optional value does not mean the account is absent.

### Cost, stopping, and resuming

Check the Actor's **Pricing** tab for current rates and configure run limits for
your workload. On pay-per-event runs, every stored row counts toward Dataset-item
charges, including `not_found`, `restricted`, and any `invalid_input` rows not
omitted with `skipInvalidInputs`.

If the result or charge budget is reached, the Actor stops with partial results.
Increase the applicable budget and **resurrect the same run** to continue. Keep
the same normalized target set. When `skipInvalidInputs` is `false`, also keep
the same invalid input strings; target order and run memory may change. The Actor
reconciles actual Dataset rows before replaying completed results saved during
cleanup. It uses `inputProfileUrl`, rather than a possibly redirected
`profileUrl`, as the stable requested identity.

Use a **graceful abort** when you intend to resume. It stops new task claims while
already claimed requests, retries, Dataset writes, and acknowledgments drain.
Platform termination can interrupt cleanup, so a forced stop cannot guarantee
complete recovery. **Re-run** creates a new run; **Resurrect** continues the
existing run.

### FAQ

#### Can this Actor scrape Stories, Spotlight posts, or Lenses?

No. It collects public profile metadata only.

#### Does it use Snapchat's Public Profile API?

No. The official API requires an allowlisted OAuth application and access token.
This Actor reads signed-out public web profile pages instead.

#### Why are some fields null?

Snapchat does not publish every optional field on every public profile. The Actor
returns `null` rather than guessing a value.

#### Does `not_found` prove a username is available to register?

No. It describes an HTTP 404 or structured missing-page response and does not
establish registration availability.

#### Where can I report an issue?

Use the Actor's **Issues** tab when available. Include the public profile URL,
run URL, expected behavior, and whether an earlier run was aborted or resurrected.
Never include credentials, cookies, access tokens, or private account data.

### Legal and ethical notice

Snapchat Profile Scraper is an independent, third-party tool. It is not
affiliated with, endorsed by, or sponsored by Snap Inc. or Snapchat.

You are responsible for ensuring that collection and use comply with
[Snap's Terms of Service](https://www.snap.com/terms), applicable Snapchat terms,
and all privacy, data-protection, intellectual-property, and other laws that
apply to you. Public availability alone does not establish permission to
collect, reuse, or redistribute personal data or third-party content.

Only collect data you are authorized to access. Do not use results for
harassment, surveillance, spam, discrimination, or other abusive purposes.

# Actor input Schema

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

Add bare usernames, @usernames, https://www.snapchat.com/@USERNAME URLs, or https://www.snapchat.com/add/USERNAME URLs. The input form checks only the basic username or profile URL shape and allowed characters, without limiting username length, so mixed lists can run even when users do not know Snapchat's exact rules. Before queueing, the Actor applies Snapchat's stricter username rules. Invalid entries do not make network requests and are skipped by default; valid entries continue.

## `skipInvalidInputs` (type: `boolean`):

Do not store invalid_input results in the Dataset. Invalid entries are still rejected locally without a network request, while valid entries continue normally. Disable this option to store invalid_input rows.

## Actor input object example

```json
{
  "usernames": [
    "https://www.snapchat.com/@nba"
  ],
  "skipInvalidInputs": true
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "usernames": [
        "https://www.snapchat.com/@nba"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("aimscrape/snapchat-profile-scraper").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 = { "usernames": ["https://www.snapchat.com/@nba"] }

# Run the Actor and wait for it to finish
run = client.actor("aimscrape/snapchat-profile-scraper").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 '{
  "usernames": [
    "https://www.snapchat.com/@nba"
  ]
}' |
apify call aimscrape/snapchat-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,aimscrape/snapchat-profile-scraper"
        }
    }
}
```

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/rb0gqGmmCTP4YS4ns/builds/oWsF513yOes8DFFGJ/openapi.json
