To track a competitor's Facebook ads: resolve their Facebook Page to its numeric Page ID, query the Meta Ad Library by that ID rather than by brand name, and snapshot the results daily. Scavio's Meta Ads API returns that per-advertiser library as JSON at one credit per call. Brand-name search returns any advertiser whose ad text merely mentions them, and stopped ads are deleted from the library rather than archived, so a daily snapshot is the only way to build the history the interface does not keep.
That takes an afternoon to set up. The rest of this post is the method in full, and what it produced when we ran it against four meal-kit brands on 20 August 2026:
- Blue Apron has gone dark. All 35 ads in its US library are inactive. The last one started 6 August and nothing is running now.
- Hungryroot has an ad that has been live for 276 days, since November 2025, and its median creative survives 91 days.
- HelloFresh replaces creative every two weeks. Median lifespan: 13 days, across 120 ads.
- Only Hungryroot builds variants systematically. 74% of its ads are multi-version tests. For HelloFresh that number is 2%.
None of that is visible in the Ad Library interface, and not because the data is hidden. It is because the interface has no memory and no arithmetic.
Creative lifespan is the tell
The single most useful number you can compute about a competitor is how long their ads survive. It separates a brand testing its way toward something from a brand that already found it.
Two clusters, and they imply opposite strategies.
Hungryroot and Factor have winners and are milking them. A 91-day median means the typical ad earns its place for three months. Their oldest live creative dates to November 2025. When a brand leaves an ad running that long, it is because the economics work and they would rather scale spend than replace the asset.
HelloFresh is in permanent test mode. A 13-day median across 120 ads is a firehose: write, launch, kill, repeat. That is not indecision, it is a deliberate volume strategy, and it costs real creative production budget to sustain.
If you are competing with these brands, those two facts imply completely different responses. You do not out-test HelloFresh cheaply. You might well out-last Hungryroot by finding a fresher angle.
Variant depth shows where the budget went
The Ad Library groups near-identical creative into what it calls a collation. The count is how many versions of one concept the advertiser built.
Hungryroot is the outlier and it is the more sophisticated operation. Three quarters of its ads are multi-variant, topping out at six versions of a single concept, which is what disciplined creative testing looks like: hold the idea, vary the execution, let delivery pick.
HelloFresh at 98% single-variant is doing the opposite. Each ad is a fresh swing. High volume, low depth.
What the interface shows you, and what it withholds
Here is the same HelloFresh library in Meta's own UI:

Look at what it gives you. "~330 results" — an approximation, not a count. Each card carries a Library ID, a start date, platform icons, and the phrase "This ad has multiple versions" with no number attached. Every chart above was built from fields this screen either rounds off, hides, or renders as an icon.
Three specific gaps:
No end date. The card says when an ad started. It never tells you when one stopped, because stopped ads are removed rather than marked. Lifespan is uncomputable here.
"Multiple versions" is not a number. The API returns collation_count: 6. The UI shows the same words for a 2-variant ad and a 6-variant one.
No arithmetic, no history. Nothing sums, averages, or compares across advertisers, and nothing tells you what changed since last week. You would be scrolling ~330 cards for one brand, then repeating it for each competitor, then doing it again next week from scratch.
The full table
| Brand | Ads sampled | Active | Median life | Longest run | Multi-variant | Landing domain |
|---|---|---|---|---|---|---|
| Hungryroot | 120 | 120 | 91 days | 276 days | 77% | eat.hungryroot.com |
| Factor | 120 | 120 | 77 days | 176 days | 23% | factor75.com |
| HelloFresh | 120 | 120 | 13 days | 112 days | 2% | hellofresh.com |
| Blue Apron | 35 | 0 | 13 days | 30 days | 6% | blueapron.app.link |
Two details worth noticing in that last column. Blue Apron sends traffic to blueapron.app.link, a deep link, so its campaigns were pushing app installs while the others drove to web. And Hungryroot runs a dedicated eat. subdomain, which usually signals a landing-page stack separate from the main site.
Sampling note: 120 ads per advertiser is the most recent slice, not the whole library. Meta's UI reports ~330 for HelloFresh. Blue Apron's 35 is its complete US library. Medians are computed on the sample.
Reproducing this
The mechanism is three steps, and the first one is where most people go wrong.
Do not search your competitor's brand name. Keyword search matches the text of the ad, not the advertiser. Searching nike in the US library returns an anime league, a phone-widget app, and Travis Scott alongside actual Nike ads, because each of those mentions Nike in the body copy. Searching home chef returns Walmart and a cookware brand.
Resolve each competitor to a numeric Page ID once, then query by that.
curl -X POST https://api.scavio.dev/api/v1/meta-ads/advertiser \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"page_id": "320774061283785", "country": "US"}'{
"data": {
"count": 30,
"has_next_page": true,
"next_cursor": "...",
"ads": [
{
"ad_archive_id": "798835303036169",
"page_name": "HelloFresh",
"is_active": true,
"start_date": "2026-04-29T07:00:00.000Z",
"end_date": null,
"collation_count": 2,
"publisher_platform": ["FACEBOOK", "INSTAGRAM", "MESSENGER", "THREADS"],
"link_url": "https://www.hellofresh.com/...",
"cta_text": "Sign Up"
}
]
},
"credits_used": 1
}start_date plus is_active gives you lifespan. collation_count gives you the variant number the UI withholds. link_url gives you the offer. Page through with next_cursor while has_next_page is true.
Four competitors cost four credits per sweep. The free tier is 50 credits, so the whole analysis above fits inside it with room to spare.
What you cannot get
spend, impressions, and reach_estimate come back null for ordinary commercial ads. That is not a limitation of any particular tool. Meta only publishes those figures for political and issue ads, where disclosure is legally required. Set ad_type to political_and_issue_ads and they populate; for a meal-kit brand they never will.
Any product claiming to show you a competitor's Facebook ad spend is modelling it from other signals. Price that accordingly.
Snapshot, because the library forgets
The Blue Apron finding is the one that decays. Right now you can see 35 ads that ran between 14 July and 6 August and then stopped. In a few weeks those records will be gone, because ads leave the library when they stop running, and no archive of finished commercial creative exists.
That is the argument for a daily snapshot rather than an on-demand check:
- Store
ad_archive_idas your key. Setfirst_seenon insert, updatelast_seenevery run. - Download the creative asset the day you see it. Image and video URLs are CDN links with expiring signatures, so a link saved last month will 404. Rehost it.
- An ad present yesterday and missing today has stopped. That, and only that, is how you build the end dates Meta never gives you.
After a fortnight you can answer questions no interface can: which creative did they kill quietly, when did the offer in link_url change, and which concept did they quietly scale from two variants to six.
We are running exactly this loop against these four brands and will update this post with the first change data.
Common questions
How can I analyse competitors in Meta Ads?
Query the Ad Library per advertiser by Page ID and aggregate across ads. Scavio's /api/v1/meta-ads/advertiser endpoint returns one advertiser's library as structured JSON, which is what makes the aggregation possible. The three metrics that carry most of the signal are creative lifespan (start_date against is_active), variant depth (collation_count), and the offer (link_url). Spend and impressions are unavailable for commercial advertisers.
How do I see what ads a competitor is running right now?
Filter to active_status: "active" on the advertiser endpoint. That returns only live creative. Anything that stopped has already been removed from the library, which is why historical tracking requires your own snapshots.
How do I find out where my competitors are advertising?
Read publisher_platform on each ad. It returns the placements the ad ran on, such as ["FACEBOOK", "INSTAGRAM", "MESSENGER", "THREADS"]. Aggregated across a competitor's library it shows which surfaces they actually buy.
Can I see how much a competitor spends on Facebook ads?
No. Meta publishes spend, impressions, and reach_estimate only for political and issue ads, where disclosure is legally required. For commercial advertisers those fields are null in the Ad Library and in every tool built on it. Any product showing you a competitor's spend figure is estimating it.
Is the Meta Ad Library API free? Meta's own Ad Library API is free but requires identity verification and an approved app, and it is scoped mainly to political and issue ads. Public commercial ad data is readable without that approval process, for example through Scavio, whose free tier covers 50 calls.
Reference for the endpoints used here: advertiser, library search, and single ad detail. For the same technique against Google's library, Google Ads Transparency search.