# Competitor ad intelligence

Meta and Google both run public ad transparency archives. Every active ad, the creative, the copy, roughly when it started running. It is the least guarded competitive intelligence in marketing and most teams check it manually once a quarter, if at all.

Manual checking gets you a snapshot. What you want is a diff: which creatives appeared this week, which ones quietly disappeared, and which have been running long enough to be obviously working.

## The pipeline

```
ads.search      →  live creatives from the Meta Ad Library or Google Ads Transparency
social.posts    →  the organic side of the same account
social.search   →  what the market says about the ad, unprompted
```

## Step 1: pull the ad set

```bash
curl -X POST https://api.jell.run/v1/run \
  -H "Authorization: Bearer $JELL_API_KEY" \
  -d '{
    "capability": "ads.search",
    "input": {"query": "competitor.com", "platform": "meta", "limit": 100}
  }'
```

`query` takes an advertiser or a keyword. An advertiser gives you one competitor's whole book; a keyword gives you everyone bidding on a theme, which is how you find competitors you did not know you had.

Switch `platform` to `google` for the Ads Transparency Center. The two archives cover different intent: Meta shows the interruption creative, Google shows the demand-capture copy. Teams that only check one usually miss half the strategy.

## Step 2: read duration, not volume

The instinct is to count ads. Volume mostly tracks budget, and budget is not a strategy.

The signal is **how long a creative has been running**. Paid teams kill losers in days. Anything still live after six to eight weeks survived that culling, which means it is producing an acceptable cost per acquisition. A creative running for three months is the closest thing to a published answer key that a competitor will ever give you.

So the useful read is:

- **Long-running creatives**: the positioning that works. Study the hook, the offer and the format.
- **Recently appeared**: a new test, a new segment, or a launch. Watch whether it survives.
- **Recently disappeared**: something they tried and abandoned. Worth noting before you try the same thing.

The last two require history, which means storing each pull and diffing. One weekly run per competitor is enough.

## Step 3: pair paid with organic

Ads show the message a company is willing to pay to distribute. Organic posts show what it says when distribution is free. The gap between them is informative.

```bash
curl -X POST https://api.jell.run/v1/run \
  -H "Authorization: Bearer $JELL_API_KEY" \
  -d '{"capability": "social.posts",
       "input": {"platform": "linkedin", "handle": "competitor", "limit": 30}}'
```

When paid and organic say the same thing, the positioning is settled and well tested. When they diverge, one of them is a bet. Usually the paid one, because it is the one with a number attached.

Then check what the market says back:

```bash
curl -X POST https://api.jell.run/v1/run \
  -H "Authorization: Bearer $JELL_API_KEY" \
  -d '{"capability": "social.search",
       "input": {"platform": "reddit", "query": "competitor.com pricing", "limit": 50}}'
```

Unprompted complaints about a competitor are the highest-value copy input available. They are the objections your own ads should pre-empt, written in your buyer's words rather than a marketer's.

## Step 4: make it a weekly diff

The workflow that produces decisions rather than screenshots:

1. Weekly, run `ads.search` for each competitor on both platforms.
2. Key each creative by its identifier and store it with the date first seen.
3. Compute three sets: new since last week, gone since last week, running over 45 days.
4. Alert on the first two. Review the third monthly, because that is your creative brief.

At the starting price this is a couple of cents per competitor per week. The output is a document that tells you what your market's best-funded testers have already learned.

## From intelligence to output

The point of reading competitor creative is shipping better creative. That handoff is one more capability: `creative.image` generates the visual from a prompt, and `creative.video` turns the winning still into short-form. The [ad creative production guide](/use-cases/ad-creative-production) covers that half.

The honest workflow is: read the long-running creatives, extract the structural pattern (not the artwork), write your own hook, generate variants, ship them, and check the archive again in six weeks to see which of yours survived.

## Where it breaks

- **Archives are not complete.** Meta's library covers all ads for some categories and only political and issue ads in some jurisdictions. Google's transparency center has its own scope. Absence from the archive is not proof an ad does not exist.
- **Duration is inferred.** Start dates in the archive are reliable; continuous running is an inference. A paused and relaunched ad can look like one long flight.
- **No performance data.** The archive shows what ran, never what it cost or converted. Duration is a proxy, not a metric.
- **Creative without context misleads.** An ad is one step in a funnel you cannot see. Copying the creative without the offer behind it usually underperforms.

## Run it as an agent

```bash
jell run -c ads.search -i '{"query":"competitor.com","platform":"meta","limit":50}'
jell run -c ads.search -i '{"query":"competitor.com","platform":"google","limit":50}'
jell run -c social.posts -i '{"platform":"linkedin","handle":"competitor"}'
```

An agent with the [skill](/SKILL.md) installed can run the weekly pass, hold the previous state, and report only the diff.

## FAQ

### Why does how long an ad has run matter more than how many ads there are?

Because ad count tracks budget, and budget is not evidence. Paid teams kill underperforming creative within days. A creative still live after six to eight weeks survived that culling, which means it is delivering an acceptable cost per acquisition. Duration is the closest thing to a published result a competitor will ever give you; volume just tells you how much they can afford to test.

### Do I need to check both Meta and Google?

Yes, if the competitor runs both. The archives cover different intent. Meta shows interruption creative aimed at people who were not looking for you, Google's transparency center shows demand-capture copy aimed at people already searching. A team that reads only one usually concludes the competitor has a simpler strategy than they do.

### Can I see how much a competitor spends or how well an ad performed?

No. The archives publish what ran, not what it cost or converted. Anything presenting itself as competitor spend data is an estimate built on assumptions, and the error bars are wide. Duration is the honest proxy available, and it is a good one precisely because it reflects a decision the competitor made with real performance data you cannot see.

### How often should the pull run?

Weekly is the right cadence. It is frequent enough to catch a new test before it finishes and cheap enough to leave running indefinitely at a couple of cents per competitor. The value is entirely in the diff, so the first run is worthless on its own and every run after it compounds.

### Is an ad missing from the library proof it does not exist?

No. Coverage differs by jurisdiction and category: Meta's library carries all ads in some regions and only political and issue ads in others, and Google's transparency center has its own scope. Treat absence as unknown rather than as evidence, particularly when comparing competitors operating in different markets.

### Is there an API to see a competitor's active ads and estimated ad spend?

`ads.search` returns a competitor's live creatives from the Meta Ad Library (by advertiser or keyword) and the Google Ads Transparency Center (by domain), with start dates. Spend estimates are a separate capability, `ads.spend_estimate`, which is listed in the catalog and marked coming soon until its provider account opens; the catalog page shows the live status. Duration of a live creative is the better signal anyway, and that one is available today.
