Luka Mrkić
Head of BD
Insights, strategies, and real-world playbooks on AI-powered marketing.
MAY 29, 2026
If you are evaluating who should build this for your team, this guide gives you both the technical blueprint and the standards to evaluate the work.
Wire daily creative pulls from official ad libraries into a normalized table, run a weekly Claude pass to cluster and diff, and ship the output to Slack and Notion. That is the entire system. The rest of this guide is how each layer actually works in 2026, what data you can and cannot trust, and what good looks like.

Six layers cover most of what you need. The first four are official platform-owned ad libraries. The last two are paid intel tools that estimate spend from panel data and ad-server pings.
Every active Meta ad is exposed: creative, run dates, advertiser page, and for EU political and social-issue ads, a spend range. You can hit it manually or with an API access token. Estimated spend for normal commercial ads is not published. Treat creative count and run duration as your real signal.
Search, display, and video ads are surfaced by advertiser page. You see creatives, formats, and first-seen dates. Spend is shown for political ads only. For commercial monitoring, use the creative volume per format as the signal.
B2B ads by company, last 12 months. Useful for sales-led and account-based competitors. Pull both the creative and the targeting tags when visible.
Top performing ads by industry, region, and date. Strong for hook patterns and creative format research. Pair with rough impressions buckets to spot which angles are scaling.
Traffic estimates, paid keyword bids, and ad copy samples. These tools rely on panel data. Use as directional, not precise. Cross-check anything important with the official ad libraries.
Display intel: spend estimates, placements, and ad-server data. Costs more than the others. Worth it once you have at least 10 advertisers you watch every week.

The pipeline has six stages. A fetcher runs daily per source and writes raw creatives plus metadata to object storage. A normalizer maps each platform into one shared schema. Claude then clusters by message and angle, computes a week-over-week diff, and writes a summary. Slack and Notion receive the brief. A reviewer can override before anything goes wide.
The normalized schema looks like this: advertiser, platform, creative_id, first_seen, last_seen, est_spend_range, creative_text, cta, landing_url. Every fetcher writes into that shape. Anything platform-specific (targeting tags, EU spend ranges, format) goes in a sidecar JSON column so you do not lose it.
Run this against the weekly delta JSON. The output is structured so Notion and Slack can render it without a second LLM pass.
System: You are a competitive ad analyst. You read normalized ad data and produce concise weekly briefs. You never state exact spend numbers; you describe qualitative direction. Output valid JSON only.
User: Here is the week-over-week delta for {advertiser} across {platforms}. For each advertiser, return:
{
"advertiser": "...",
"new_angles_spotted": [ "...", "..." ],
"angles_paused": [ "..." ],
"suspected_budget_direction": "increasing | flat | decreasing | unclear",
"evidence": "one short sentence citing creative counts and dates",
"watch_next_week": [ "..." ]
}
Be specific about angles. Do not invent numbers.
import os, json, anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
with open("delta-2026-W22.json") as f:
delta = json.load(f)
resp = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4000,
system=SYSTEM_PROMPT,
messages=[{"role": "user", "content": json.dumps(delta)}],
)
brief = json.loads(resp.content[0].text)
with open("brief-2026-W22.json", "w") as f:
json.dump(brief, f, indent=2)
If you want this set up cleanly inside your stack with logging, retries, and a feedback loop into a CRM, that is the kind of work we ship at Espressio.

Manual screenshots in a Google Doc give you a snapshot. They tell you what a competitor is running today. They do not tell you what changed this week, which angles cluster together, or which advertisers are accelerating. A weekly AI brief does. Same raw inputs, different operating cadence.

Use this to brief a vendor or grade your own internal build. Each row is something you can verify in under five minutes by asking for an artifact (a connector list, a diff JSON, a sample summary, an override log).
Pull from official ad libraries first. They exist specifically for this use case. Respect each platform’s terms of service. Rate limit your fetchers so you do not look like a scraper. Attribute estimated numbers to the tool that produced them. Do not scrape behind login walls.
These are the metrics worth tracking. Watch how they move as you tighten the pipeline. Do not set targets.
For EU political and social-issue ads, yes. Spend ranges are published by Meta and Google. For everything else, you are reading estimates from panel-based tools. Treat the direction as the signal. Treat the absolute number as a vibe.
Only for EU political ads in Meta and Google’s transparency centers. Commercial spend is not disclosed. SimilarWeb, Adbeat, and Pathmatics produce estimates with their own methodology. Cite the source whenever you quote a number.
Official ad libraries are public. Meta, Google, LinkedIn, and TikTok each publish them under their own terms. Use the official APIs where they exist, rate limit your fetchers, and do not bypass authentication walls. Legal review is your call (and your lawyer’s).
Anything with a long context window and reliable JSON output. Claude Sonnet 4.5 and GPT-4o both work well for the weekly summarization pass. The prompt matters more than the model.
Daily for fetchers. Weekly for the Claude summarization and the human-reviewed Slack and Notion brief. Anything more frequent is noise; anything less and you miss creative launches.
If you want competitive intelligence set up cleanly inside your growth stack, let’s talk.