Skip to main content
Liorry Herisnor
Status: ProductionMarketing and Growth2026 — present

AdSpy — Competitive Ad Intelligence

A pipeline that captures native ads and their landing pages at scale, deduplicates them visually, resolves advertiser identities, and connects the findings directly to campaign creation.

At a glance

Choosing what to promote used to mean guessing. AdSpy captures what advertisers are actually running — the native ads, the landing pages behind them, and how long each keeps spending — then makes that corpus searchable and one click away from a campaign draft. Every fetch is delegated to a separately owned service, AdFetch. Collection runs in production; the one-click build path is deliberately gated behind human review.

  • 66,870 ads · 114,098 pages

    Corpus

    Native and programmatic ads captured from publisher sites across six ad networks, each with the landing pages behind it and a daily observation history.

    Source: Measured from platform records, July 2026; the same figures are visible in the product header.

  • 21K+ ads / month

    Collection rate

    Ads first seen in the 30 days to July 30, alongside 31,327 landing-page captures in the same window.

    Source: Measured from platform records, July 2026.

  • 1.29M crawl jobs

    Provenance

    Every captured ad and page traces back to the crawl job that scheduled it — which publisher, which network placement, which day.

    Source: Measured from platform records, July 2026.

Status
Status: Production
Category
Marketing and Growth
Dates
2026 — present
My role
Product owner, architect and delivery lead
Target users
Operators researching which offers and creatives are actually spending, Campaign managers turning a proven ad into a campaign draft, Me, deciding where the agency's creative effort goes
Technology
Go, PostgreSQL, Perceptual hashing, PostgreSQL full-text search, Claude / Gemini / OpenAI APIs

What I owned

  • Product vision
  • Discovery
  • Requirements
  • Prioritization
  • Architecture decisions
  • Delivery coordination
  • Testing
  • Production operations

Areas this project actually involved. Anything not listed, I did not own.

Who and what supported delivery

AI coding assistants
Implementation assistance under the documented delivery workflow — context packs, task cards, automated pre-commit checks and human approval on every production change.
Operations team members
The operators who research ads, keep boards, and decide what becomes a campaign. Their complaints about manual spying are the requirements document this started from.

One service, one owner: I set the product direction, made the architecture calls, and run it in production. Every fetch is delegated to AdFetch — a separately owned service with its own case study — implemented with AI assistance under review, like everything else in this portfolio.

The business problem

Marketing spend follows a simple rule: an ad that keeps running is an ad that keeps paying. Native ad networks are the closest thing to a public ledger of what works — every promoted headline on a publisher site is someone spending real money — but that ledger is unreadable by hand.

Research was a person with twenty browser tabs. Finding what advertisers in a niche were running meant browsing publisher sites, screenshotting promoted widgets, and pasting links into a spreadsheet. Hours of work produced a snapshot that was stale by the afternoon and answered none of the questions that matter: how long has this ad run, on how many sites, and what does the page behind it actually sell?

The signal is longevity, and longevity needs history. A single sighting of an ad is trivia. The same creative observed daily across 48 publishers for 97 days is evidence that it converts. No manual process produces that history.

The same ad appears everywhere, slightly different. Networks recut images, append tracking parameters and rotate headlines. Without visual deduplication a collection fills with hundreds of copies of one ad, and the interesting question — how many distinct winners exist in this niche — becomes unanswerable.

Commercial spy tools stop at the report. They show ads; they do not connect to anything. What the business needed was intelligence one click away from action inside its own sending platform — see a proven ad, generate assets, and launch through the same suppression-gated pipeline every other campaign uses.

Previous workflow

Before: competitive research by hand

Nothing here accumulates. Every research session starts from zero and its output rots in a folder.

  1. Human action

    Operator browses publisher sites

    Manually visiting sites known to carry native ad widgets in the target niche.

    • Problem: Coverage limited to the sites one person thinks to check
    • Problem: No record of what was already seen last week
  2. Human action

    Screenshots and links into a spreadsheet

    • Problem: No dedup — the same ad recut three ways counts three times
    • Problem: No landing-page capture; links die when campaigns end
  3. Human action

    Judgment call from a snapshot

    Decision point: Does this ad look like a winner, based on having seen it once?

    • Problem: Longevity — the actual signal — is invisible in a snapshot
    • Problem: No advertiser view: one operator running ten creatives reads as ten advertisers
  4. Human action

    Template built from the hunch

    A creative brief written from memory of what the ad looked like.

    • Problem: The landing page that made the ad work is gone by build time
    • Problem: Nothing links the campaign back to the evidence it came from
  • Human action

Goals and non-goals

Goals

  1. Capture native ads and their landing pages continuously, with per-day observation history, so longevity becomes a queryable number.
  2. Deduplicate visually at ingestion — perceptual hashing on creatives — so the corpus counts distinct ads, not recuts.
  3. Resolve advertiser identity across networks from sponsor names, click-chain hosts and creative clusters.
  4. Make the corpus searchable the way an analyst thinks: keyword plus facets for network, geo, device, tracker signature, landing platform and days alive.
  5. Connect intelligence to action: from any ad, generate assets or start a campaign draft in the sending platform — behind human review.
  6. Stay inside AdFetch's shared proxy-bandwidth ceiling — a property of the fetch service this pipeline depends on, not something built here.

Non-goals

  • No interaction with ads beyond capture. The pipeline records what is publicly served; it does not click, vote or engage.
  • No autonomous sending. Nothing this system produces reaches a recipient without passing the platform's suppression gate and a person's decision to launch.
  • Not a resale product. This is an internal instrument for one business's creative decisions, which is why it can stay opinionated.

My role

I own AdSpy on my own: product direction, requirements, architecture decisions, prioritization, delivery coordination, testing and production operations — with implementation built under the documented AI-assisted workflow. AdSpy calls a separately owned service, AdFetch, for every page it touches — that service's own story, and its own ownership, live on its own case study.

The three decisions I would point to as mine:

  • Delegate fetching entirely. AdSpy never touches a browser, a proxy or an anti-bot challenge directly. Every fetch goes through AdFetch's HTTP API, which means AdSpy's own codebase is exactly as large as the ad-intelligence problem, and not one line larger.
  • Dedup before storage, not after. Perceptual hashes are computed at ingestion, so the corpus never accumulates the recut-duplicates problem that would otherwise need a cleanup project later.
  • Gate the exciting part. The one-click ad-to-campaign build is the demo everyone wants — and it is the part held behind a risk gate, human review and an empty production ledger until the surrounding controls earn trust.

What was built

AdSpy is one service with one job: turn captured ads into decisions about what to promote. It does not fetch pages itself — every fetch is delegated to AdFetch, a separately owned service consumed over HTTP.

AdSpy, and how the pieces connect

Collection is delegated entirely. Intelligence in the middle, action at the top — the proxy budget and the human review gate are load-bearing, not decoration.

Collection

Fetching is delegated entirely — this pipeline never touches a browser or a proxy directly.

  • AdFetch

    Automated

    Separately run fetch, scrape, search and map service, consumed over HTTP. Also used by the lead-discovery pipeline. See the separate case study.

Intelligence — AdSpy

The product layer inside the platform: pipeline, corpus and analysis.

  • Publisher crawl pipeline

    Automated

    Scheduled crawl jobs against publisher sites across six native ad networks; 1.29 million jobs recorded to date.

  • Ad ingestor

    Automated

    Normalizes captured ads, computes dedup signals and writes provenance for every record.

  • Landing capture

    Automated

    Follows ad click-throughs, snapshots the destination and classifies it — advertorial, sales page, lead form, quiz, article.

  • Visual dedup and signatures

    Automated

    Perceptual hashing collapses recut creatives; a tracker-signature registry identifies the analytics and affiliate stacks on each page.

  • Advertiser resolution

    Automated

    Fuzzy-matches operator identity across networks from sponsor names, click-chain hosts and creative clusters.

  • Corpus store

    Data store

    Ads, landing pages, daily observations, publishers and advertisers — every row traceable to the crawl job that produced it.

  • Search and facets

    Automated

    Weighted full-text search over headlines, sponsors and landing-page text, faceted by network, geo, device, tracker and platform.

Action — product surface

Where intelligence meets the sending platform.

  • Research UI

    Human

    Grid, ad detail with observation history, landings, advertisers, boards, favorites, analyst notes and saved watches.

  • Analytics dashboards

    Monitoring

    Creative reuse, cross-publisher spread, top hosts and trending views over the corpus.

  • Auto-build (gated)

    AI / LLM

    Four sequential LLM stages turn a proven ad into a landing page and email template — with saga-style rollback, idempotent retries and a risk gate before anything is committed.

  • Human launch decision

    Approval gate

    Campaign drafts route into the sending platform, where the mandatory suppression gate and a person's approval stand between intelligence and an actual send.

Diagram is sanitized for publication: it shows responsibilities and data flow, not hostnames, addresses or credentials.

The corpus numbers on the day of writing: 66,870 distinct ads, 114,098 captured landing pages, 120,076 publisher placements and a daily observation history that answers "how long has this run" for any of them.

How it connects to the rest of the stack

This system earns its place by being wired into everything else, not by being a standalone report.

  • Into campaign creation. From any ad detail page an operator can generate assets or start a campaign draft in MailerClub. The auto-build path produces a landing page and an email template using the platform's own link-routing macros, so anything it drafts inherits click tracking and unsubscribe handling instead of reinventing them. Nothing sends without the platform's suppression gate.
  • A fetch service AdSpy doesn't own. AdFetch is a separately run service — its own repository, its own API, its own operator. AdSpy owns none of the browser fleet, the anti-bot handling or the proxy pool behind its fetches; it just calls the API. The same service independently backs the lead-discovery pipeline's page fetches, with no shared code between the two consumers.
  • One proxy budget across the business. Residential proxy transfer has a hard monthly ceiling, split across consumers with per-day byte budgets and hard stops, plus a request audit log — a mechanism AdFetch owns, not AdSpy. Ad intelligence, ad fetching and everything else draw from the same governed pool, so one enthusiastic crawler cannot starve the rest of the month.
  • The same model discipline as everywhere else. The auto-build's LLM calls go through an explicit provider allow-list — the same select-the-model-per-task approach as the delivery workflow — and its spend is bounded by the pipeline's own timeout and stage structure.
  • Into the agency's creative research. The boards, notes and analytics views are how proven angles and formats inform the creative production work — as research input, with a person deciding what any client actually receives.

Where AI is used, and where it is not

AI does

  • The four auto-build insight stages: read a proven ad and its landing page, extract the angle, draft the funnel copy and the email template.
  • Ad and landing-page analysis batches, when enabled — classification and angle extraction over the corpus.

Fixed rules do

  • Everything that counts: perceptual-hash dedup, tracker signatures, advertiser matching, search ranking, observation history.
  • The controls around the build: destination-URL validation, a risk gate between insight and build, saga-style rollback on failure, idempotent retries, one build per ad at a time.
  • The proxy byte budgets and their hard stops.

The pattern is the same one the rest of this portfolio uses: AI interprets, fixed rules enforce, and a person owns anything that could reach a customer. An LLM never chooses what gets sent — it drafts, inside a pipeline whose guardrails are ordinary software.

Evidence

  • The corpus at a glance

    Per-network counts, the filter bar and the facet row — including tracker-signature facets like the analytics and affiliate stacks detected on landing pages. Account identifier covered.

    Placeholder — evidence pending sanitization review before publication.
  • One ad, with its history and its actions

    97 days across 48 publishers and 8,441 observations is the longevity signal the manual process could never produce — and the Launch campaign and Generate assets buttons are the bridge into the sending platform. Account identifier covered.

    Placeholder — evidence pending sanitization review before publication.
  • Captured landing pages, classified

    Pages are snapshotted at capture time — campaigns die and links rot, but the evidence keeps. The classification chips (advertorial, sales, lead form, quiz, article) are what make funnel-type queries possible. Account identifier covered.

    Placeholder — evidence pending sanitization review before publication.
  • Advertisers, not just ads

    The entity layer: one operator running thousands of creatives reads as one advertiser with a history, not thousands of unrelated rows. Account identifier covered.

    Placeholder — evidence pending sanitization review before publication.
  • Analytics — creative reuse

    An ad recycled across 246 landing pages is a signal no snapshot could surface. Account identifier covered.

    Placeholder — evidence pending sanitization review before publication.
  • Watches — stated exactly as they are

    The page itself says the quiet part: criteria can be saved and pre-staged today, and the evaluator wiring is still rolling out. Honest status labels are a product feature on this system too. Account identifier covered.

    Placeholder — evidence pending sanitization review before publication.

What runs, and what does not

The same honesty rule as everywhere else in this portfolio: the state below is what this pipeline actually does, verified against its own records in July 2026.

ComponentStateThe evidence
Publisher crawl and ingestionRunning21,731 ads first seen in the 30 days to July 30
Landing capture and classificationRunning31,327 captures in the same window
Search, facets, boards, notesRunningDaily research use over the 66,870-ad corpus
Advertiser entity resolutionRunningOperator entities resolved across networks with first/last-seen history
Analytics dashboardsRunningCreative-reuse and cross-publisher views over live data
WatchesPartialCriteria saved and pre-staged; evaluator wiring still rolling out — the page says so on its face
Facebook Ad Library connectorStalled27 ads captured before the source began blocking unauthenticated capture; parked rather than fought
LLM ad analysisDormant40 analyses recorded, none since May; the batch layer is switched off while collection compounds
One-click auto-buildBuilt, gated, unusedFull pipeline with rollback, idempotency and compliance tests; zero production funnels committed

Collection is scheduled work rather than a 24/7 stream — the header in the first screenshot honestly reads "0 new / 24h" on a day between crawl runs.

Results

  • The corpus exists and compounds. 66,870 distinct ads, 114,098 landing pages and 1.29 million crawl jobs of provenance, growing at 21,000+ ads a month — a queryable asset where there used to be screenshot folders.
  • Longevity is now a number. "97 days, 48 publishers, 8,441 observations" replaces "I think I've seen this one before" as the basis for creative decisions.
  • Research became a query. Niche, network, geo, device, tracker stack, landing platform and days-alive are filters, not afternoons.
  • Intelligence sits one click from action — with the click still owned by a person, and everything downstream passing the same suppression gate as any other campaign.

What this has not yet produced, stated plainly: a production campaign built end-to-end by the auto-build path. That ledger is empty on purpose, and opening it is a deliberate decision that has not been taken.

Lessons

  • Depend on infrastructure you don't have to build. Every page AdSpy captures goes through a fetch service someone else owns and operates. The discipline that took was resisting the urge to reach past the HTTP boundary "just this once" when a fetch behaved unexpectedly — the fix always belonged on the other side of that boundary, not inside AdSpy.
  • Deduplicate at the door. Perceptual hashing at ingestion cost little; retrofitting it onto a corpus of recuts would have been a project. The same lesson as suppression on the sending side: enforce at the choke point.
  • Collection before analysis. The corpus compounds every week the crawler runs; analysis layers can stall — and one did — without devaluing the asset. Sequencing the durable part first made the stall survivable, and saying so beats pretending the analysis layer is live.
  • An intelligence tool is judged by its distance to action. The features that changed behavior were not the dashboards — they were the Launch campaign and Generate assets buttons that shortened the path from evidence to draft.

What's next

  • Wire the watch evaluator so saved criteria fire without a person opening the grid — the page already promises exactly this, and nothing more.
  • Revive the analysis batch layer against the now much larger corpus, with the same spend ceilings the auto-build path uses.
  • Take the first auto-build funnel to production behind the existing risk gate and review step — the deliberate opening of a deliberately empty ledger.

Want the detail behind this?

I am happy to walk through the architecture, the decisions and what I would change.