Ad Creative Intelligence Scraper avatar

Ad Creative Intelligence Scraper

Pricing

from $1.60 / 1,000 results

Go to Apify Store
Ad Creative Intelligence Scraper

Ad Creative Intelligence Scraper

Search the Meta, Google, TikTok, and LinkedIn ad libraries for a competitor's ads, then take the videos apart: a word-timed transcript, the cut list, and a teardown of the hook, offer, CTA, and claims. Run the search on its own for a fast ad export, or analyse video URLs you already have.

Pricing

from $1.60 / 1,000 results

Rating

0.0

(0)

Developer

The Netaji

The Netaji

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

The Actor searches the Meta, Google, TikTok, and LinkedIn public ad libraries for one advertiser's ads and, on request, analyses each video rather than only cataloguing it: a transcript with word-level timings, a scene list with per-shot motion, and a structured teardown of the hook, the script's stages, the offer, the call to action, and the claims made.

Searching by advertiser name is the one operation every library supports, so query is the only input most runs need.

Three modes

scraperType chooses what a run does. The two are separate because they fail separately: a search answers in seconds and has nothing in it that can time out, while an analysis downloads files and reads them. Welding them together made every run only as reliable as the slowest, least certain part of it.

The batch summary is not a third mode. It is a footer on the analysis run that produced it, appended automatically as the last row.

Find a competitor's ads (search) — the ad libraries and nothing else. Returns each ad's creative, copy, landing URL, media files, and dates. No downloads, no analysis. This is the mode to start with, and the one that produces the video URLs the next mode takes.

Take video ads apart (analyze) — the transcript, the cuts, and the teardown. Give it a brand name and it searches the libraries first, or paste video URLs into videoUrls and it analyses exactly those and touches no ad library at all. The second shape is the dependable one: the videos are already in hand, so no library can slow it down, refuse a country, or list an ad it publishes no file for.

Accepted input

  • scraperTypesearch or analyze. Defaults to search.
  • query — brand, company, or advertiser name. Required by search, and by analyze unless videoUrls is supplied.
  • platforms — which libraries to search. Defaults to Meta only, which is the library that serves this reliably worldwide. Add the others deliberately: Google covers one country per run, TikTok covers only Europe (below), and LinkedIn publishes a media file for only some of its ads.
  • countries — comma-separated two-letter codes, default US. Meta and Google read the first entry; LinkedIn reads the whole list. UK is corrected to GB and EL to GR.
  • mediaTypeall, video, or image, for search. The analysis modes always narrow to video, because an image ad has no transcript and no cuts.
  • date_min and date_max — optional activity-date bounds. The TikTok Ads Library requires a window and searches the last 90 days when both are blank.
  • active_statusall, active, or inactive. Only the Meta Ad Library filters on delivery status upstream.
  • videoUrls — for analyze: analyse exactly these videos and search no library. Paste the video_url column straight from a search run. When this is set, query and the library settings are ignored, and the run log says so.
  • maxAds — how many ads to return or analyse; default 10, maximum 50.
  • transcribeCreatives — default true.
  • detectScenes — default true.
  • teardownCreatives — default true.
  • batchReport — default true. Appends the summary row to the end of an analyze run. Billed once, and only when the row is actually produced.
  • includeTranscriptText — default true. Disabling it drops the full text, segments, and word timings from each row and retains the teardown and the scene list.

Response fields

Two record shapes are saved, distinguished by record_type.

A search run saves record_type: "ad" rows carrying the ad-library fields only: platform, ad_id, ad_url, advertiser_name, advertiser_id, first_seen, last_seen, is_active, and creative, plus video_url — the one file worth analysing, already picked out of the creative's mixed media list so it can be pasted straight into the analysis mode. The analysis fields are absent rather than present and empty.

From an analyze run, a record with record_type: "ad" is one analysed ad. It carries the same ad-library fields platform, ad_id, ad_url, advertiser_name, advertiser_id, first_seen, last_seen, is_active, and creative, followed by the analysis:

  • media — duration, dimensions, and whether the file carried an audio track.
  • hook — the words spoken in the first three seconds, taken from the transcript's word timings rather than from the first sentence, so a sentence crossing the boundary is cut where the viewer heard it cut. It is read from the transcript rather than from the teardown, so it is populated on a run with teardownCreatives disabled.
  • transcriptlanguage, has_speech, word_count, and, unless includeTranscriptText is disabled, text, segments, and words.
  • scenescount, cuts_per_minute, and each scene's start, end, and motion, classified as static, moderate, or dynamic.
  • teardownhook, script_structure, offer, cta, claims, language, and confidence. Each claim records the evidence it was drawn from.
  • analysis — the outcome of each step, as ok, skipped, or failed, with a reason.

A record with record_type: "batch_report" is written once, last. Its report field counts what recurs across the ads analysed in the run: recurring_hooks, hook_types, recurring_offers, discounts, cta_actions, cta_wording, recurring_claims, claim_types, languages, and pacing, the last holding the median duration, median scene count, and median cuts per minute. stages_failed counts the ads on which each step did not complete, so a thin report is explainable without repeating the run. This row is the reason to analyse twenty ads rather than one: a pattern across an advertiser's slate is not visible one ad at a time.

Fields absent from the upstream response are returned as null rather than omitted.

Example input

A plain search:

{
"scraperType": "search",
"query": "athletic greens",
"countries": "US",
"maxAds": 20
}

Analysing what that search found, with no library in the path:

{
"scraperType": "analyze",
"videoUrls": ["https://video.xx.fbcdn.net/v/t42.1790-2/example.mp4"]
}

Example record

{
"record_type": "ad",
"platform": "meta",
"ad_id": "527778036512305",
"ad_url": "https://www.facebook.com/ads/library/?id=527778036512305",
"advertiser_name": "Nike",
"media": { "duration_seconds": 31.4, "width": 1080, "height": 1920, "has_audio": true },
"hook": "Three seconds is all anyone gives an ad, so this one starts here.",
"transcript": { "language": "en", "has_speech": true, "word_count": 96 },
"scenes": { "count": 14, "cuts_per_minute": 26.8 },
"teardown": {
"hook": { "text": "Three seconds is all anyone gives an ad, so this one starts here.", "type": "pattern_interrupt" },
"offer": { "present": true, "description": "20% off first order", "discount": "20%" },
"cta": { "present": true, "action": "shop", "text": "Shop the new collection" },
"claims": [{ "text": "Lasts twice as long", "type": "comparative", "source": "transcript" }]
},
"analysis": {
"transcribe": { "status": "ok" },
"scenes": { "status": "ok" },
"teardown": { "status": "ok" }
}
}

What each library actually covers

The four libraries are not interchangeable, and the default input does not reach all of them.

The TikTok Ads Library is TikTok's EU Commercial Content Library. It carries only ads delivered in the EEA, Switzerland, the United Kingdom and Turkey. Selecting it alongside countries it does not cover leaves it out of the search before the run starts, with a line in the log saying why — the coverage is set by the regulation the library exists to satisfy, not by the advertiser being searched for, so asking it anyway can only waste the call. A run that selects TikTok and nothing else for a country outside its coverage is refused outright, because an empty result there would read as "this advertiser has no ads" when the truth is that the library was never able to answer.

The Meta Ad Library publishes an ad's format from the ad's own metadata and its media files separately, so an ad marked video does not always carry a downloadable file. Ads listed as video with no file are passed over before any analysis and are not charged for; the run log counts them. A search that returns twenty listings can therefore analyse fewer than twenty ads, and the Actor over-fetches to absorb this.

Only the Meta Ad Library filters on delivery status, which is why active_status changes Meta results and leaves the others unaffected.

Video length limit

Creatives longer than two minutes are refused, and the ad is saved with its remaining fields and the reason recorded on analysis. The limit is measured rather than chosen: transcription of a spoken-word creative costs approximately half a second of processing per second of video, so a five-minute creative would take longer to transcribe than a single request is permitted to run. Ad creatives are rarely that long; one that is returns a record with a reason attached rather than failing the run.

Charged events

Each step is charged only when it produces a result.

  • Transcription is charged per minute of video, rounded up, and only once a transcript has been returned. A creative that could not be downloaded, was refused as too long, or proved not to be a video is not charged.
  • The teardown is charged once per teardown returned.
  • The batch report is charged once per run, and only when the summary row is produced.

Disabling a step in the input removes its charge entirely. A step that fails is not charged, and the record is retained with the fields the other steps produced.

Behaviour on partial results

A single ad that fails is retained in the dataset with its remaining fields and a reason on analysis. An expired media link on one ad among forty is ordinary and does not interrupt the run.

A step that fails for a reason which will hold for every remaining ad is switched off for the rest of the run after the first occurrence, recorded once in the log, and marked skipped with that reason on every later record. Repeating it per ad costs a request each and cannot succeed.

A library that is unavailable does not fail the run. The run completes with results from the libraries that answered, and the run log names the one that did not. The run fails only when every selected library is unavailable.

An interrupted run resumes at the exact ad it stopped on and neither re-analyses nor re-charges the ads already saved. Because a resumed run cannot read the records its earlier attempt pushed, its summary row is marked covers_this_attempt_only rather than under-counting silently.

Creatives without speech

A creative carrying a backing track and no voice-over returns an empty transcript with has_speech set to false, and analysis.transcribe reads ok. Silence is a finding rather than a failure; a fast-cut creative with no narration is a deliberate format, and the scene list still describes it. The teardown then runs on the published ad copy where the library publishes any. Where there is neither speech nor copy, the teardown is skipped and not charged rather than produced from nothing.

Scope

Only what the ad libraries publish to logged-out visitors is read. The Actor holds no account on any platform and reaches no signed-in surface, so material a library shows only to authenticated users is outside its scope.

Spend and impression brackets are not analysed here. Where the ad's metadata is sufficient and the creative itself is not required, the All-in-One Ad Library Scraper covers the same four libraries at a lower cost per ad.