Blog/competitive-intelligence
1 min read

Turn a Brand Name Into a Competitor Ad Archive

A hands-on recipe: go from a brand or page name to a structured archive of the Facebook Ad Library ads it is running, using Apify on Monid.

Turn a Brand Name Into a Competitor Ad Archive

You can turn any brand name into a structured archive of the ads that brand is running right now, in about five minutes and for a few cents per pull. The Meta Ad Library is public, and the Apify Facebook Ads Library scraper reads it for you, so the only real work is bounding the query and keeping the fields you care about. This post is the recipe.

Copy this line to your agent to build a competitor ad archive from a brand name.

set up https://monid.ai/SKILL.md and use apify/curious_coder/facebook-ads-library-scraper to pull a brand's live ads into a structured archive

TL;DR

  • Point one Apify endpoint at a brand or page, get back every active ad it runs: creative text, start date and duration, spend and reach estimates, platform, and EU transparency data.
  • Pass a SINGLE search query with a small result limit. Cost scales with results returned (roughly queries times per-query limit), so bounding the limit bounds the bill.
  • Discover and inspect are free on Monid. You only pay on run, and the price is shown before you spend.
  • jq the four fields that matter (creative text, start date plus duration, spend or reach estimate, platform), snapshot to a dated file, and diff on a schedule.
  • End state: a competitor ad archive you own, versioned over time, for the price of a couple of espresso shots.

What you are building

The Meta Ad Library exposes every ad a page runs, but the web UI is built for one-off browsing, not for pulling a clean dataset. The Apify facebook-ads-library-scraper turns a page or search query into rows: ad identifiers, categories and labels, timestamps and duration, spend and impression estimates, advertiser attributes, creative snapshots, and publisher platform. Monid gives you one interface and one wallet to call that endpoint (and hundreds of other data endpoints) without a separate Apify signup or per-vendor billing.

Monid is a pay-per-call data API marketplace: one interface and one wallet to discover and execute hundreds of external data endpoints without a separate signup per vendor, billed pay-as-you-go at the price shown. Here is the full path from a brand name to a dataset you can diff.

Setup

For agents

Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:

set up https://monid.ai/SKILL.md

It learns the whole discover, inspect, run workflow itself. More details in the agent quickstart.

For humans

npm install -g @monid-ai/cli
monid keys add --label main --key <your-api-key>

More details in the CLI quickstart.

Step 1: inspect the endpoint (free)

Before you spend anything, read the input shape. inspect is free and tells you which fields the scraper accepts and how billing is metered.

monid inspect -p apify -e /curious_coder/facebook-ads-library-scraper

The important line to read here: this endpoint bills PER_RESULT, and total results are approximately your number of queries times the per-query limit. That is the whole cost lever. One search term with a limit of 20 gives you at most about 20 billable rows. That is why the next step uses a single query and a small count.

Step 2: run one bounded brand query

Feed the scraper one brand or page as a search term, cap the count, and wait inline with -w. Inputs go in the request body, so use -i.

monid run -p apify -e /curious_coder/facebook-ads-library-scraper -w \
  -i '{"searchTerms":["Allbirds"],"country":"US","activeStatus":"active","count":20}' \
  -o allbirds-ads.json

Swap Allbirds for the brand you are tracking, and set country to the market you care about. Keep count small on the first pull so you can eyeball the output before scaling. If you want a specific page rather than a keyword match, pass that page's Ad Library URL instead of a search term; inspect shows the exact field name.

For a longer run you can drop -w and let it go async, then collect the output later:

monid runs get -r <RunID> -o allbirds-ads.json

Step 3: jq the fields that matter

Raw ad objects are wide. For a competitor archive you rarely need all of it. Pull the creative text, the start date and how long the ad has run, a spend or reach estimate, and the platform it runs on. That is enough to see what a competitor is testing, what they keep alive, and where they push it.

jq '[.[] | {
  id: .adArchiveID,
  text: .snapshot.body.text,
  startDate: .startDate,
  endDate: .endDate,
  spend: .spend,
  impressions: .impressions,
  platforms: .publisherPlatform
}]' allbirds-ads.json > allbirds-archive-2026-07-21.json

Read the shape from your own output before trusting field names; the inspect step and a quick look at the first record confirm exactly what the scraper returned. A long-running ad with a wide reach estimate is a signal: that creative is working for them. A cluster of ads that all started this week is a signal too, usually a new campaign or a seasonal push.

Step 4: turn snapshots into a diffable archive

One pull is a photograph. The value is in the sequence. Name each file by date, keep them in a folder, and you have a versioned record of what the competitor runs over time.

diff <(jq -S '[.[].id]' allbirds-archive-2026-07-14.json) \
     <(jq -S '[.[].id]' allbirds-archive-2026-07-21.json)

New ad IDs are new creative launches. Disappeared IDs are ads they killed. IDs that persist with a growing duration are their proven winners. Run Step 2 and Step 3 on a weekly schedule (a cron job, or your agent on a timer) and the archive builds itself. Point the same recipe at three or four competitors and you have a rolling view of a whole category's ad activity.

The cost tally

Discover and inspect cost nothing. The only paid step is run, and because this endpoint bills per result, your bill is set by the limit you choose:

  • One brand, count: 20, one market: a few cents. See live per-call pricing at monid.ai/tools.
  • Four competitors, weekly, at the same small limit: still single-digit dollars a month, and every price is shown before you spend.

Bounding count is the entire cost story. Start small, confirm the fields, then raise the limit only if you actually need more depth.

FAQ

Is scraping the Facebook Ad Library allowed? The Ad Library is a public transparency tool that Meta publishes deliberately, and this recipe reads what is already visible there. Keep your queries bounded and your use within Meta's terms and your own legal guidance.

How do I track a specific page instead of a keyword? Pass that page's Ad Library URL as the input rather than a search term. Run monid inspect to see the exact field and format the scraper expects for URL-based input.

Why one query at a time? Because this endpoint bills per result and total results scale as queries times per-query limit, a single query with a small count keeps both the cost and the output predictable. Batching many queries at once makes the bill hard to reason about.

What does this cost? A few cents for a bounded single-brand pull, single-digit dollars a month for a small multi-competitor cadence. Prices are pay-as-you-go and shown before you run; current numbers live at monid.ai/tools.

Start with one brand and a count of 20. Once the archive has two dated snapshots in it, the diff does the analysis for you.

competitive-intelligencefacebook-ads-libraryapifyweb-scraping