# How to search the Meta Ad Library and follow an advertiser

> Search Facebook and Instagram ads in the Meta Ad Library by keyword, list one advertiser's ads, then re-check single ads: country, status, media and sort, code and cost.

Canonical page: https://okdata.online/guides/meta-ad-library-search/

Three endpoints, in this order: Meta Ad Library search to find ads by keyword, Meta advertiser ads to list what one Facebook page runs, and Meta Ad Library ad detail to re-check single ads later. The worked example is 7 calls and costs $0.028; a failed call is not charged.

Updated 2026-11-12

The job: you are entering a product category and want to see how the brands already in it advertise on Facebook and Instagram. Which hooks do they use, which offers, which landing pages, and how long do their ads keep running? Search the library by keyword to see who advertises, open the most active advertiser's full list, and save a shortlist of ads to check again later. You end with three tables: ads for the keyword, one advertiser's ads, and the status of your shortlist a week on.

No Meta developer app, access token or Facebook login is involved. Each call is an HTTPS request with your key.

## Step by step

### Step 1: search ads by keyword

Call [Meta Ad Library search](https://okdata.online/apis/meta/ads/search/) with `query`. Four filters narrow it:

- `country`: an ISO code such as `US` or `DE`; all countries when left out.
- `status`: `active` (the default, ads running now), `inactive` (stopped ads) or `all`.
- `media`: `all` (the default), `image` or `video`.
- `sort`: `impressions` (the default, most impressions first) or `newest`.

One call returns up to 30 ads for $0.004. Each ad has `id` (the library ID), `url`, `advertiser` (the Facebook page's `id`, `name` and `url`), `title`, the copy in `text`, `format` (`image`, `video`, `carousel`, `text` or `dynamic`), `images`, `videos`, `landing_url`, `cta`, `platforms` (such as `facebook` and `instagram`), `active` and `first_shown_at`.

```bash
curl -G "https://api.okdata.online/v1/meta/ads/search" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'query=electrolyte powder' \
  -d country=US -d status=active -d media=video -d sort=impressions
```

For the second page, send `page.next_cursor` back as `cursor`, unchanged. Then count the rows by `advertiser.id` to see who spends the most attention on the keyword.

### Step 2: list one advertiser's ads

Pass the page ID from step 1 to [Meta advertiser ads](https://okdata.online/apis/meta/advertisers/ads/list/) as `id`, or the brand's name as it appears on its Facebook page as `name`. Give one, not both; both or neither is `invalid_params`, which is not charged. The same `country`, `status`, `media` and `sort` filters apply, and each page holds up to 30 ads for $0.004.

```bash
curl -G "https://api.okdata.online/v1/meta/advertisers/ads/list" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  -d id=107364829105372 -d country=US -d status=active -d sort=newest
```

`sort=newest` puts the ads the brand launched most recently on top, which is what you want for a weekly look. The ID is safer than the name: several pages can share a name, and the ID points at exactly one.

### Step 3: re-check single ads

[Meta Ad Library ad detail](https://okdata.online/apis/meta/ads/get/) takes a library `id` or the ad's link as `url` and returns one ad for $0.004, with `active`, `first_shown_at` and `last_shown_at`. Save the IDs of the ads you shortlist; a week later, three detail calls tell you which of them still run and for how long they have run. An ad that has been running for months is usually one that works.

```bash
curl -G "https://api.okdata.online/v1/meta/ads/get" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  -d id=1290374658821904 \
  -d fields=id,active,first_shown_at,last_shown_at,landing_url
```

### Step 4: in Python

```python
import collections
import os
import requests

API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}


def pages(path, n, **params):
    cursor = None
    for _ in range(n):
        body = requests.get(API + path, headers=HEADERS, params={**params, **({"cursor": cursor} if cursor else {})}, timeout=60).json()
        if body["code"] != "ok":
            raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
        yield from body["data"]["items"]
        if not body["page"]["has_more"]:
            return
        cursor = body["page"]["next_cursor"]


ads = list(pages("/v1/meta/ads/search", 2, query="electrolyte powder", country="US", status="active", media="video"))
top_page = collections.Counter(a["advertiser"]["id"] for a in ads if a["advertiser"]["id"]).most_common(1)[0][0]
for a in pages("/v1/meta/advertisers/ads/list", 2, id=top_page, country="US", status="active", sort="newest"):
    print(a["first_shown_at"], a["format"], a["landing_url"], (a["text"] or "")[:80])
```

## Good to know

- **What Meta's own API returns.** Meta's [Ads Archive reference](https://developers.facebook.com/docs/graph-api/reference/ads_archive/) says ads that did not reach any location in the EU only come back if they are about social issues, elections or politics. For political ad research, or EU ads with Meta's own breakdowns, its API is the right tool. The endpoints here read the public library pages, so ordinary commercial ads in the US or Asia come back too.
- **Spend and reach.** The library publishes no spend or reach for commercial ads outside the EU, so `reach` is null there. For EU-delivered ads it carries Meta's EU reach figure.
- **Stopped ads.** `status=inactive` returns only the stopped ads the public library still shows, and for commercial ads outside the EU that is often few. If you want a brand's history, save each week's rows yourself.
- **Dynamic ads.** Catalog ads assembled per viewer have `format` set to `dynamic` and often no copy, because the library shows a template instead of text.
- **Extras.** `view=full` adds `ext.variants` (how many versions of the ad the library groups together), `ext.page_likes`, `ext.categories` and, for EU ads, `ext.eu_payer` and `ext.eu_beneficiary`.
- **Save creatives you keep.** Image and video links point at Meta's servers and can expire.
- **Retries without paying twice.** Send an `Idempotency-Key` header with each call; the same request with the same key within 24 hours returns the stored answer and no new charge.

For what the official API costs and requires, see [the Meta Ad Library API answer](https://okdata.online/answers/meta-ad-library-api-price-limits/). To track one competitor on Meta, Google and TikTok together, see [competitor ads on three libraries](https://okdata.online/answers/competitor-ads-meta-google-tiktok/).

## What the example costs

Two pages of active US video ads for electrolyte powder, two pages of one advertiser's active ads, then three shortlisted ads checked again a week later

| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| [Meta Ad Library search](https://okdata.online/apis/meta/ads/search/) | 2 | $0.004 | $0.008 |
| [Meta advertiser ads](https://okdata.online/apis/meta/advertisers/ads/list/) | 2 | $0.004 | $0.008 |
| [Meta Ad Library ad detail](https://okdata.online/apis/meta/ads/get/) | 3 | $0.004 | $0.012 |
| Total | 7 |  | $0.028 |

Prices in force when this page was built. A failed call costs nothing.

## In your AI (MCP)

Connect the MCP server once, then say what you want. The agent finds these endpoints, reads their prices and calls them on your balance.

Say: Search the Meta Ad Library for active video ads about electrolyte powder shown in the US, most impressions first, two pages. Tell me which advertisers appear most, then list two pages of active ads from the top one with copy, landing page and start date.

```json
{
  "endpoint": "meta.ads.search",
  "params": {
    "query": "portable espresso"
  },
  "idempotency_key": "<a new UUID>"
}
```

MCP: `https://api.okdata.online/mcp`

## Endpoints in this guide

- [Meta Ad Library search](https://okdata.online/apis/meta/ads/search/) `meta.ads.search`: $0.004 per call · about 30 ads per page
- [Meta advertiser ads](https://okdata.online/apis/meta/advertisers/ads/list/) `meta.advertisers.ads.list`: $0.004 per call · about 30 ads per page
- [Meta Ad Library ad detail](https://okdata.online/apis/meta/ads/get/) `meta.ads.get`: $0.004 per call

## More about Meta Ad Library

- [Meta Ad Library API](https://okdata.online/apis/meta/)
- [Is the Meta Ad Library API free, and what are its limits?](https://okdata.online/answers/meta-ad-library-api-price-limits/)
- [How do I see all the ads a competitor is running on Meta, Google and TikTok?](https://okdata.online/answers/competitor-ads-meta-google-tiktok/)
- [Ad detail API](https://okdata.online/roles/ads-get/)
- [Advertiser ads API](https://okdata.online/roles/advertisers-ads-list/)
- [Ad search API](https://okdata.online/roles/ads-search/)

## Sources

- [Meta Graph API reference: Ads Archive](https://developers.facebook.com/docs/graph-api/reference/ads_archive/) (read 2026-11-12)
