# Instagram Ads Library Scraper (Meta Ad Library) (`pulsedata/instagram-ads-library-scraper`) Actor

Scrape ads that run on Instagram from the Meta Ad Library by keyword, advertiser page ID or Ad Library URL. Returns ad text, images and videos, carousel cards, links, call to action, start and end dates, days active and all platforms each ad runs on. No login.

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

## Pricing

from $3.00 / 1,000 ad scrapeds

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

## Instagram Ads Library Scraper (Meta Ad Library)

This Instagram ads scraper exports ads that run on Instagram from the [Meta Ad Library](https://www.facebook.com/ads/library/), which is where Meta publishes Instagram's ad library. You search by keyword, by advertiser page ID, or by pasting an Ad Library search URL, and get one row per ad with the ad text, headline, link, call to action, image and video URLs, carousel cards, start and end date, days active and the advertiser page. The actor asks Meta for Instagram placements only, so ads that run only on Facebook, Messenger, Threads or Audience Network are left out.

It works logged out, the same way the public Ad Library page does. You need no Instagram or Facebook account, no cookies and no Meta API token.

### Features

- **Scrape all Instagram ads of an advertiser** by numeric page ID, active and stopped.
- **Search the Instagram ad library by keyword** in one country or all countries. Wrap the keyword in double quotes for the exact phrase.
- **Scrape a Meta Ad Library URL** you set up in the browser. Its filters are used as they are, and the Instagram filter is added.
- **Filter Instagram ads by country, status and media type**: active or inactive, images, videos, memes or text only.
- **Download Instagram ad creatives**: image URLs, HD and SD video URLs with preview images, and every card of a carousel ad.
- **See how long each Instagram ad has been running** with `startDate`, `endDate` and `daysActive`.
- **Export Instagram ads to CSV, Excel or JSON** through the Apify dataset or API.

### Use cases

- **Competitor research on Instagram**: every creative a competitor runs on Instagram, when it started and whether it is still live. Ads that have run for months are usually the ones that convert.
- **Creative swipe files**: ad copy, headlines, calls to action and video URLs for one product category, for example video ads for running shoes in the UK.
- **Agency pitches and audits**: bring a prospect's current Instagram ads and run dates to the first meeting.
- **Influencer and brand monitoring**: find ads that mention a brand name, including ads from creators and resellers.
- **Market scans by country**: which brands advertise a product category on Instagram in Germany, France or the US right now.
- **Lead generation**: check which companies advertise on Instagram at all. Pass a list of page IDs and set `maxAdsPerQuery` to 1.

### Input

| Field | What it does |
|---|---|
| `queries` (required) | One search per line. A keyword such as `running shoes`, `"running shoes"` for the exact phrase, a numeric page ID such as `15087023444` for every Instagram ad of one advertiser, or a URL copied from facebook.com/ads/library. |
| `country` | ISO code (`US`, `DE`, `GB`), a country name such as `United Kingdom`, or `ALL`. Default `ALL`. |
| `activeStatus` | `all` (default), `active` or `inactive`. |
| `mediaType` | `all` (default), `image`, `video`, `meme` or `none` (text only). |
| `maxAdsPerQuery` | Stop after this many ads per line. Default 100, `0` for no limit. |
| `proxyConfiguration` | Residential Apify Proxy by default. Leave it as is; Meta keeps datacenter IPs on its challenge page. |

Example input:

```json
{
  "queries": ["nike", "\"running shoes\"", "15087023444"],
  "country": "US",
  "activeStatus": "active",
  "mediaType": "all",
  "maxAdsPerQuery": 200
}
```

A pasted Ad Library URL keeps its own country, status and media filters. For example `https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=DE&q=bakery&media_type=all` returns active bakery ads in Germany that run on Instagram. If the URL carries its own platform filter, for example Facebook only, that part is removed, because this actor always returns Instagram ads.

#### How to find a page ID

Page names and vanity URLs such as `instagram.com/nike` or `facebook.com/nike` cannot be resolved without logging in, so an advertiser search needs the numeric page ID. Open the advertiser in the Ad Library in your browser and copy the number after `view_all_page_id=` in the address bar. Lines the actor cannot use are skipped with a note in the log, and the other lines still run.

### Output

One item per ad:

```json
{
  "query": "15087023444",
  "country": "ALL",
  "adArchiveId": "1702938977100376",
  "adLibraryUrl": "https://www.facebook.com/ads/library/?id=1702938977100376",
  "pageId": "15087023444",
  "pageName": "Nike",
  "pageUrl": "https://www.facebook.com/nike/",
  "pageLikeCount": 39505027,
  "pageCategories": ["Sportswear", "Product/service"],
  "isActive": true,
  "startDate": "2025-04-07",
  "endDate": "2026-10-09",
  "daysActive": 550,
  "publisherPlatforms": ["FACEBOOK", "INSTAGRAM", "AUDIENCE_NETWORK", "MESSENGER"],
  "displayFormat": "DPA",
  "body": "Bring sports more fully into your day with the Nike App.",
  "caption": "itunes.apple.com",
  "linkUrl": "http://itunes.apple.com/app/id1095459556",
  "ctaText": "Install now",
  "ctaType": "INSTALL_MOBILE_APP",
  "imageUrls": [],
  "videos": [],
  "cards": [
    {
      "title": "Nike Run Swift 3 Women's Road Running Shoes",
      "linkUrl": "https://www.nike.com/ph/t/run-swift-3-road-running-shoes-2fHbzp/DR2698-002",
      "linkDescription": "₱3,995",
      "ctaText": "Install Now",
      "imageUrl": "https://scontent..."
    }
  ],
  "spend": null,
  "impressions": null,
  "currency": null,
  "scrapedAt": "2026-10-09T08:21:09.707Z"
}
```

`publisherPlatforms` lists every platform the ad runs on. Instagram is always one of them, and many ads also run on Facebook and other Meta platforms. Items also include `title`, `linkDescription`, `pageProfilePictureUrl`, `collationId`, `collationCount`, `categories`, `disclaimer`, `reachEstimate`, `targetedOrReachedCountries` and `containsSensitiveContent`. Each video has `hdUrl`, `sdUrl` and `previewImageUrl`; each carousel card has its own text, link, call to action and media. `collationCount` is the number of near-identical versions Meta groups under one ad. In our test runs 460 of 460 returned ads listed Instagram as a platform.

### What Meta publishes

Meta shows the creative, the advertiser and the run dates for every ad in the library. Spend, impressions and reach are published as ranges only for political and issue ads; for ordinary commercial ads these fields are `null`. The actor reads the Ad Library search results and does not open each ad's detail page, so the EU reach and targeting breakdown Meta shows there is not included. Organic Instagram posts, reels and stories that are not ads are not in the Ad Library and are not returned.

### Pricing

The actor is free to use until 23 October 2026. After that it is charged per ad returned plus a small fee per run, and the current price is always shown on the Pricing tab of this page. You can set a maximum cost per run in the run options; the actor then stops cleanly at that amount and keeps everything it collected.

### FAQ

**Do I need an Instagram account or a Meta API token?**
No. The actor reads the public Ad Library logged out and cannot see anything a logged-out visitor cannot see.

**Why does it use the Facebook Ad Library?**
Meta runs one ad library for all its platforms. Instagram ads are listed there with Instagram as a placement, and the actor applies that filter for you.

**Can I get all Instagram ads of an advertiser, not just 100?**
Set `maxAdsPerQuery` to `0`. The actor follows the Ad Library's pagination until the last page. Large advertisers have thousands of ads.

**How fast is it?**
In our test runs 100 ads took about 40 seconds and 300 ads from two searches took about a minute. All searches in one run share one browser session.

**How long do the image and video links work?**
Meta signs media URLs and they expire after some days. Download the files soon after the run if you need them.

**Can I get only ads that run on Instagram and nowhere else?**
The actor returns every ad that includes Instagram. Filter the dataset on `publisherPlatforms` if you want ads with Instagram as the only placement.

**Can I schedule it or use it via API?**
Yes. Save a task with your queries, add an Apify schedule, and pull the dataset as JSON, CSV or Excel through the API, or send it to Google Sheets, Make, Zapier or n8n.

**What can it not do?**
It does not return clicks, conversions, audience targeting or the EU reach breakdown, it does not download media files, and it does not read organic Instagram posts.

**Is it legal to use this data?**
The actor returns public ad data only. If you process ads from individuals, you are responsible for handling that personal data lawfully, for example under the GDPR.

### Example pages

Each of these opens a ready-made run with a real input:

- [Export every Instagram ad an advertiser runs](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/instagram-ads-by-page-id)
- [Nike ads on Instagram in the US](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/nike-instagram-ads-us)
- [Instagram video ads for running shoes in the UK](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/instagram-video-ads-running-shoes-uk)
- [Instagram ads for plumbing services in the US](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/instagram-ads-plumbers-us)
- [Scrape Instagram ads from a Meta Ad Library URL](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/instagram-ad-library-url-export)
- [Sephora ads on Instagram in the US](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/sephora-instagram-ads-us)
- [Instagram ads that mention Shein in Germany](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/shein-instagram-ads-germany)
- [Skincare image ads on Instagram in the UK](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/skincare-instagram-image-ads-uk)
- [Find the Instagram ads adidas has stopped running](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/stopped-instagram-ads-adidas)
- [Instagram ads for online courses in the US](https://apify.com/pulsedata/instagram-ads-library-scraper/examples/online-course-instagram-ads-us)

### Related actors

- [Facebook Ads Library Scraper](https://apify.com/pulsedata/facebook-ad-library-scraper): the same Ad Library for Facebook, Instagram, Messenger, Threads and Audience Network, with filters for political, housing, employment and credit ads.
- [Google Ads Transparency Center Scraper](https://apify.com/pulsedata/google-ads-transparency-scraper): the competitor view for Google Search, YouTube, Shopping, Maps and Play ads.
- [LinkedIn Ad Library Scraper](https://apify.com/pulsedata/linkedin-ad-library-scraper): B2B ads with impressions per country and targeting for EU ads.
- [TikTok Ad Library Scraper](https://apify.com/pulsedata/tiktok-ad-library-scraper): TikTok video ads shown in Europe, with run dates and audience size.

# Actor input Schema

## `queries` (type: `array`):

One search per line. A keyword such as `running shoes` (wrap it in double quotes for the exact phrase), a numeric Facebook page ID such as `15087023444` for every Instagram ad of one advertiser, or a URL copied from facebook.com/ads/library. Only ads that run on Instagram are returned.

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

Where the ads were shown: an ISO code such as `US`, `DE` or `GB`, a country name, or `ALL`.

## `activeStatus` (type: `string`):

Only ads that are running now, only ads that stopped, or both.

## `mediaType` (type: `string`):

Filter by the ad's creative.

## `maxAdsPerQuery` (type: `integer`):

Stop after this many ads per line of input. 0 means no limit.

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

Meta keeps datacenter browsers on its challenge page, so this actor uses residential proxies by default.

## Actor input object example

```json
{
  "queries": [
    "Nike"
  ],
  "country": "ALL",
  "activeStatus": "all",
  "mediaType": "all",
  "maxAdsPerQuery": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Results stored in the default dataset (JSON/CSV/Excel via the dataset API).

# 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 = {
    "queries": [
        "Nike"
    ],
    "country": "ALL",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("pulsedata/instagram-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 = {
    "queries": ["Nike"],
    "country": "ALL",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("pulsedata/instagram-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 '{
  "queries": [
    "Nike"
  ],
  "country": "ALL",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call pulsedata/instagram-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pulsedata/instagram-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/BvzJ3NS3ucBHqsvAg/builds/zPk5Py8Jc1hT5kRAl/openapi.json
