# Snapchat Ads Library Scraper: EU Ads & Impressions (`kyungminlee/snapchat-ads-library-scraper`) Actor

Returns ads from Snapchat's public EU Ads Library (EU-27 + Turkey) by advertiser name: impressions per country, targeting, dates, media and landing URLs, products. No login. Example: advertiserNames=\["Nike"]. Pay per event: $0.001 per ad.

- **URL**: https://apify.com/kyungminlee/snapchat-ads-library-scraper.md
- **Developed by:** [Kyungmin Lee](https://apify.com/kyungminlee) (community)
- **Categories:** Marketing, Social media, Lead generation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 ads

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Ads Library Scraper do?

**Snapchat Ads Library Scraper** pulls every ad a company runs on Snapchat in Europe from the **Snapchat Ads Gallery**, Snap's EU ad transparency library, using **Snap's publicly documented Ads Library API**. You get one row per ad. Each row has the paying advertiser, brand profile, headline, call to action, video or image download link, landing page, start date, **impressions per country**, targeting (age, gender, languages, devices) and, for dynamic product ads, the **catalog products** shown.

Type one or more advertiser names (`Nike`, `Zalando`, `Netflix`), choose countries and a date range, and click Start. No Snapchat account, no browser, no proxy needed.

The data comes from the EU Digital Services Act (DSA) ad repository. Snap publishes ads shown in the **27 EU countries and Turkey** only, so ads shown only in the US, UK or elsewhere are not included.

This is an **unofficial** tool. It is not affiliated with, endorsed by or sponsored by Snap Inc. It only calls the open Ads Library endpoints that Snap documents for third-party use (`adsapi.snapchat.com/v1/ads_library`). It never scrapes the adsgallery.snap.com website and never touches creator or personal profiles.

### Why use Snapchat Ads Library Scraper?

- **Competitor ad intelligence**: see which Snapchat ads a competitor runs in Europe, how long each one has been live and how many people saw it in each country.
- **Creative research**: download the actual MP4 and image files, headlines and calls to action across a whole category.
- **Market sizing**: compare `impressionsTotal` and `impressionsByCountry` across brands and markets.
- **Agency reporting**: schedule a weekly run per client and send new ads to Sheets, Slack or your BI tool.
- **Cross-channel view**: use it with our [Google Ads Transparency Center Scraper](https://apify.com/kyungminlee/ads-transparency-scraper) to see a brand's Google and Snapchat ads side by side.

Compared with other Snapchat ad scrapers, this one handles **several advertisers and several countries in one run**. It returns impressions as numbers, flattens targeting into simple fields, includes DPA catalog products and gives media download links for video ads. It runs without residential proxies, so it is fast and cheap.

### How to use Snapchat Ads Library Scraper

1. Enter one or more **Advertiser names**. Snap matches them partially: `Nike` finds `Nike, Inc.`. Turn on **Exact advertiser match** to drop other advertisers whose names only contain yours.
2. Choose **Countries** (lowercase codes such as `de`, `fr`, `it`). Leave the list empty to search all 27 EU countries and Turkey.
3. Optionally set **Active from / Active until**. The default is the last 90 days. Set **Ad status** to `ACTIVE` or `PAUSED` to narrow the results.
4. Set **Max ads per advertiser** (default 100) and click **Start**.
5. Download the results from the **Dataset** tab as JSON, CSV, Excel or HTML, or fetch them through the Apify API.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `advertiserNames` | array (required) | `["Nike"]` (prefill) | Paying advertiser names, partial match |
| `countries` | array | all 28 | `at` `be` `bg` `hr` `cy` `cz` `dk` `ee` `fi` `fr` `de` `el` `hu` `ie` `it` `lv` `lt` `lu` `mt` `nl` `pl` `pt` `ro` `sk` `si` `es` `se` `tr` (`gr` is accepted for Greece) |
| `dateFrom`, `dateTo` | `YYYY-MM-DD` | last 90 days | Ads running in this window |
| `status` | `ALL` / `ACTIVE` / `PAUSED` | `ALL` | Delivery status |
| `maxAdsPerAdvertiser` | integer | `100` | Limit per advertiser name (max 5,000) |
| `exactAdvertiserMatch` | boolean | `false` | Keep only ads whose paying advertiser or brand profile name equals the searched name (ignoring case, punctuation and legal suffixes such as Inc., GmbH, SE). Skipped ads are not charged |
| `includeProducts` | boolean | `true` | Add the catalog products of dynamic product ads |
| `proxyConfiguration` | object | off | Only needed if Snap throttles you |

```json
{
  "advertiserNames": ["Zalando", "About You"],
  "countries": ["de", "at", "nl"],
  "dateFrom": "2026-07-01",
  "status": "ACTIVE",
  "maxAdsPerAdvertiser": 200
}
```

### Quick API example

Minimal input (also the prefill style used in the Apify Console):

```json
{"advertiserNames": ["Nike"], "maxAdsPerAdvertiser": 20}
```

Run synchronously and get the dataset items in one call (replace `<TOKEN>` with your Apify API token):

```
POST https://api.apify.com/v2/acts/kyungminlee~snapchat-ads-library-scraper/run-sync-get-dataset-items?token=<TOKEN>
Content-Type: application/json

{"advertiserNames": ["Nike"], "maxAdsPerAdvertiser": 20}
```

AI agents using the Apify MCP server can call this Actor as `kyungminlee/snapchat-ads-library-scraper` with the same JSON input.

### Output

An ad from a search for `Zalando` (long URLs shortened):

```json
{
  "adId": "4c97f2f7-f0eb-4946-86a2-46851e9967ea",
  "campaignName": "SA-1-M",
  "adAccountName": "Zalando Marketing Services GmbH",
  "payingAdvertiserName": "Zalando Marketing Services GmbH",
  "brandProfileName": "Zalando",
  "brandLogoUrl": "https://cf-st.sc-cdn.net/aps/bolt/...FMjpeg",
  "status": "ACTIVE",
  "reviewStatus": "APPROVED",
  "creativeType": "WEB_VIEW",
  "adType": "REMOTE_WEBPAGE",
  "mediaType": "VIDEO",
  "headline": "Brandneu: Der Stiefel der Saison",
  "callToAction": "SHOP NOW",
  "mediaDownloadUrl": "https://cf-st.sc-cdn.net/d/5XvNxPigzlfC62EyvNVGW.67?mo=...",
  "landingUrl": "https://www.zalando.de/campaigns/converse-puffed-up/?wmc=...",
  "deepLinkUrl": null,
  "startDate": "2025-11-20T16:00:22.000Z",
  "endDate": null,
  "daysActive": 328,
  "impressionsTotal": 65004,
  "impressionsByCountry": { "de": 65004 },
  "topCountry": "de",
  "targeting": {
    "minAge": 18, "maxAge": 34, "ageGroups": [], "gender": "FEMALE", "languages": [],
    "advancedDemographics": [], "devices": [], "regulatedContent": false
  },
  "languages": ["de"],
  "isDynamicProductAd": false,
  "productCount": 0,
  "products": [],
  "adDetailApiUrl": "https://adsapi.snapchat.com/v1/ads_library/ads/4c97f2f7-f0eb-4946-86a2-46851e9967ea",
  "searchedName": "Zalando",
  "scrapedAt": "2026-10-15T02:56:16+00:00"
}
```

Dynamic product ads (`isDynamicProductAd: true`) add a `products` array, e.g. `{"title": "...", "link": "https://www.nike.com/de/t/...", "imageUrl": "https://cf-st.sc-cdn.net/d/...", "brand": "Nike", "availability": "IN STOCK", "condition": "NEW", "productType": ["Kids > Shoes > Casualwear"]}`. Story ads (`creativeType: COMPOSITE`) add `storySnaps`, one entry per snap with its own headline, media link and landing page.

A `SUMMARY` record in the run's key-value store lists the ads per name, the names with no ads and any failures.

### Data fields

| Field | Description |
|---|---|
| `adId`, `adDetailApiUrl` | Snap's ad ID and its official Ads Library API URL |
| `campaignName`, `adAccountName` | Ad name and ad account set by the advertiser |
| `payingAdvertiserName`, `brandProfileName`, `brandLogoUrl` | Legal payer, public brand profile and its logo |
| `status`, `reviewStatus`, `rejectionReasons` | Delivery and review state |
| `creativeType`, `adType`, `renderType`, `mediaType` | Format, e.g. `WEB_VIEW` + `VIDEO`, `COLLECTION`, `COMPOSITE` (story ads) |
| `headline`, `callToAction` | Ad copy shown on the Snap |
| `mediaDownloadUrl` | Direct MP4/image file (not available for dynamic ads) |
| `landingUrl`, `deepLinkUrl` | Website or app destination |
| `startDate`, `endDate`, `daysActive` | When the ad started (and ended, if Snap publishes it). `daysActive` is the days since the start for active ads (empty for paused ads without an end date) |
| `impressionsTotal`, `impressionsByCountry`, `topCountry` | Impressions in the EU and Turkey, per country (zeros removed) |
| `targeting` | `minAge`, `maxAge`, `ageGroups`, `gender`, `languages`, `advancedDemographics`, `devices`, `regulatedContent` |
| `languages` | Creative languages |
| `storySnaps` | Each snap of a story (composite) ad |
| `isDynamicProductAd`, `productCount`, `products` | Catalog products: title, link, image, brand, availability, condition, type, colour, size, gender, age group, description |
| `searchedName`, `scrapedAt` | Which input name found the ad, and when |

### Pricing

This Actor uses **pay per event** pricing: **$1 per 1,000 ads** ($0.001 per ad saved to the dataset). There is no start fee and no subscription. Names that return no ads, failed requests and duplicate ads are never charged. Example: 5 competitors × 100 ads = 500 ads ≈ **$0.50**. The run stops as soon as your maximum charge per run is reached.

### Tips

- **Partial matching**: `Nike` may also return small advertisers whose name contains "Nike" (e.g. "Oya Nike Botanica"). The final status message shows what each name matched, e.g. `Nike → Nike, Inc. (58), Oya Nike Botanica (2)`. Turn on **Exact advertiser match** to keep only the company itself (`Nike` = "Nike, Inc.", `Zalando` = "Zalando SE" or the "Zalando" brand profile). The other advertisers' ads are then skipped and not charged.
- Use the shortest distinctive name (`Zalando` rather than `Zalando SE Berlin`).
- One request returns 10 ads, about 1 second each, so 1,000 ads take roughly 2 minutes.
- An ad found by two names is saved once, under the first name.
- For weekly monitoring, schedule a run with `status: ACTIVE` and a 7-day date range.
- **Also check Bing search ads:** the same advertiser's Bing ads are in [Microsoft Ads Library Scraper](https://apify.com/kyungminlee/microsoft-ads-library-scraper).

### FAQ

**Is this the official Snapchat API?** It uses Snap's official, publicly documented Ads Library API, which Snap says is open for third-party use without an OAuth token. The Actor itself is unofficial and not affiliated with Snap Inc.

**Why only Europe and Turkey?** The Ads Gallery exists because of the EU Digital Services Act. Snap does not publish US or other ads there.

**Can I search by keyword or list all ads in a country?** No. Snap's API requires an advertiser name.

**Does it collect personal data?** No. It returns company-level advertising data only. Snap's creator "sponsored content" search is intentionally not used.

**Something broke?** Open an issue in the **Issues** tab with your input and run ID.

# Actor input Schema

## `advertiserNames` (type: `array`):

REQUIRED. List of advertiser names, e.g. \["Nike", "Zalando"]. Matched partially ("Nike" also finds "Nike, Inc."); use short brand names. Each name is searched separately with its own maxAdsPerAdvertiser limit. Snap's API cannot list ads by country or keyword alone.

## `countries` (type: `array`):

Optional list of lowercase 2-letter codes, e.g. \["de", "fr"]: only ads delivered there. Allowed: 27 EU codes (at be bg hr cy cz dk ee fi fr de el hu ie it lv lt lu mt nl pl pt ro sk si es se; gr accepted for Greece) and tr. Empty = all 28.

## `dateFrom` (type: `string`):

Optional date string YYYY-MM-DD, e.g. "2026-01-01": only ads running on or after it. Empty = 90 days before dateTo. Snap keeps about 12 months.

## `dateTo` (type: `string`):

Optional date string YYYY-MM-DD, e.g. "2026-10-01": only ads running on or before it. Empty = today.

## `status` (type: `string`):

Enum ALL, ACTIVE or PAUSED (default ALL): ACTIVE = still delivering, PAUSED = stopped, ALL = both.

## `maxAdsPerAdvertiser` (type: `integer`):

Integer, default 100 (prefill 20): max ads saved per advertiser name (10 ads per request). Ads already saved for an earlier name in the run are skipped, not charged twice, and not counted. Each ad saved is one charged 'ad' event ($0.001).

## `exactAdvertiserMatch` (type: `boolean`):

Boolean (default false). true = keep only ads whose advertiser or brand profile name equals the searched name, ignoring case, punctuation and legal suffixes ("Nike" = "Nike, Inc."); skipped ads are not saved or charged. false = partial matches included.

## `includeProducts` (type: `boolean`):

Boolean (default true). true = for dynamic product ads add a products array (title, link, image, brand, availability). false = smaller rows. No effect on price.

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

Apify proxy settings object, default {"useApifyProxy": false} (works from Apify servers). Enable {"useApifyProxy": true} if you see repeated throttling (error E1009).

## Actor input object example

```json
{
  "advertiserNames": [
    "Nike"
  ],
  "countries": [
    "de",
    "fr"
  ],
  "status": "ALL",
  "maxAdsPerAdvertiser": 20,
  "exactAdvertiserMatch": false,
  "includeProducts": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `ads` (type: `string`):

No description

## `allItems` (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 = {
    "advertiserNames": [
        "Nike"
    ],
    "countries": [
        "de",
        "fr"
    ],
    "maxAdsPerAdvertiser": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kyungminlee/snapchat-ads-library-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 = {
    "advertiserNames": ["Nike"],
    "countries": [
        "de",
        "fr",
    ],
    "maxAdsPerAdvertiser": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("kyungminlee/snapchat-ads-library-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 '{
  "advertiserNames": [
    "Nike"
  ],
  "countries": [
    "de",
    "fr"
  ],
  "maxAdsPerAdvertiser": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call kyungminlee/snapchat-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kyungminlee/snapchat-ads-library-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/JuXvKgFuxCvsN3j2I/builds/iCteR9FtXGsBSb7gb/openapi.json
