Meta Ad Transcript Scraper - Video Ads to Text avatar

Meta Ad Transcript Scraper - Video Ads to Text

Pricing

from $19.00 / 1,000 transcripts

Go to Apify Store
Meta Ad Transcript Scraper - Video Ads to Text

Meta Ad Transcript Scraper - Video Ads to Text

Meta ad transcript scraper, no login: Facebook and Instagram video ads from the Meta Ad Library turned into text in bulk, inside the Actor. Rows carry the transcript, timed segments, language, hook and confidence beside the ad copy and call to action. CSV, API, schedules; pay per transcript.

Pricing

from $19.00 / 1,000 transcripts

Rating

0.0

(0)

Developer

Automation Craft

Automation Craft

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Meta Ad Transcript Scraper - Video Ads to Text

Turn Facebook and Instagram video ads from the Meta Ad Library into text in bulk: search by keyword or advertiser, paste Ad Library links, video links or the dataset of any Ad Library run, and get every ad's spoken script as a transcript with timed segments, word timestamps, the language, the opening line and the second speech begins, next to the ad's copy, call to action, dates and platforms. The speech model (Whisper) runs inside the Actor: no outside AI service, no API key, no login. Videos without speech, repeats and failed reads are free rows that say why.

Why marketers use it

  • Competitor scripts as data. Hooks, offers and calls to action of the video ads a brand runs right now, ready for a spreadsheet or your own AI model.
  • Every input you already have. Search terms, advertiser names or page ids, single Ad Library links or ad ids, Ad Library search links with their filters, direct video URLs, the dataset of another Ad Library run, or pasted rows.
  • Honest billing. A transcript is charged once per video: the same creative running under several ad ids is transcribed and charged once, a video with no speech is a free no_speech row, an expired link is read again from the Ad Library when the ad id is known.
  • Deeper rows. Language with its probability, a confidence figure, speech seconds, words per minute, subtitles (SRT and WebVTT), optional English translation, on-screen text, scene cuts and the Ad Library's EU reach details.

How to transcribe Meta video ads

  1. Type one or more Search terms (for example meal kit) and pick the Countries (US by default), or paste Advertisers, Ad Library links or ad ids, Meta video URLs, or pick a Dataset of an Ad Library run.
  2. Set Transcripts per search and Transcripts per run (3 and 3 in the form) to the size you want.
  3. Click Start. Each video ad comes back as one row with its transcript; open the Transcripts view or export JSON, CSV or Excel.
  4. To follow a competitor, save the input as a task with a Memory name and New ads only, and schedule it: each run transcribes and charges only the videos it has not delivered before.

Clicking Start with nothing set runs a sample: 3 video ads running in the US for "fitness app".

What you get

One transcript row per video ad, plus free status rows (one per ad or video not transcribed, with the reason), one free coverage row per search, and a run summary. Fill rates measured on 54 transcript rows of 40 platform runs on 2026-10-13 (searches in the US and Spain, advertisers, ad links, video links, pasted rows, a chained dataset):

FieldWhat it holdsFilled
transcriptthe speech of the video as text54 of 54
segmentsthe transcript in timed segments (start, end, text)54 of 54
wordsevery word with its start, end and probability (with wordTimestamps)when asked
language, languageName, languageProbabilitythe spoken language the model detected54 of 54
hook, hookSeconds, hookStartSecondsthe words spoken in the first seconds after speech begins, and the second it begins54 of 54
confidencethe model's own mean token probability, 0 to 154 of 54
speechSeconds, wordCount, wordsPerMinuteseconds of voice found, words, pace54 of 54
videoDurationSeconds, transcriptSeconds, transcriptCompletethe video's length, the audio transcribed, and whether all of it was54 of 54
adArchiveId, adLibraryUrl, pageName, adTextthe ad and its advertiser (empty only for a bare video link given without its ad)50 of 54
pageId, ctaText, ctaTypethe advertiser's page id and the call to action40 to 46 of 54
startDate, isActive, daysRunningthe ad's dates40 to 46 of 54
publisherPlatforms, landingUrl, landingDomainwhere it runs and where it sends people38 to 40 of 54
targetedOrReachedCountriesas the Ad Library's search answer gives it: an empty list on every row read (the reach per country of an ad shown in the EU comes with adDetails)0 of 54
videoId, videoUrl, videoUrlExpiresAtthe creative's asset id and the file read (links expire after 1 to 4 days)52 to 54 of 54
subtitlesSrt, subtitlesVtt, translationEnglish, onScreenText, sceneCuts, cutsPerMinute, adDetails, mediaFileUrl, pageActiveAdCount, rawAdthe options and add-ons belowwhen asked
imageUrl, imageText, mediaFileUrlon image_text and image_file rows: the image ad's file, its text, the saved filewhen asked
status, paidEvents, messagewhy a row is what it is, and the events it is charged forevery row

Real row (shortened), from a search for "meal kit" in the US:

{
"type": "transcript",
"status": "transcribed",
"adArchiveId": "4309638865973296",
"pageName": "Hungryroot",
"ctaText": "See details",
"language": "en",
"languageProbability": 1,
"hook": "It is 5.30 and I just got my very first",
"hookStartSeconds": 9.81,
"transcript": "It is 5.30 and I just got my very first delivery from Hungary route. It is perfect because guess what? ...",
"transcriptSeconds": 102.22,
"videoDurationSeconds": 102.33,
"speechSeconds": 81.66,
"wordCount": 315,
"confidence": 0.81,
"paidEvents": { "transcript": 1, "transcript-minute": 1 }
}

The example shows what a speech model does with a brand name it does not know ("Hungary route" for Hungryroot): names, prices and codes are worth a glance before you quote them. The video runs 102 seconds, so the row is one transcript and one transcript minute.

Row statuses

Paid rows (type transcript): transcribed, transcribed_partial (the compute cap stopped the read; the row says where), screen_text (a silent video's on-screen text), image_text (an image ad's text), image_file (an image ad's saved file).

Free status rows: no_speech (music, silence or text on screen), no_audio_track, no_video (an image or text ad), same_video (the same creative as another ad of the run, with its transcript in full), already_delivered (your memory holds it), language_filtered, duration_filtered, ad_text_filtered, launch_filtered, advertiser_filtered, category_filtered, video_expired, video_gone, video_too_large, video_failed, ad_not_found, lookup_failed, advertiser_not_found, advertiser_ambiguous (the candidates are listed), image_text_empty, failed, skipped (the run stopped first), not_charged (a correction: the row it names was delivered without part of its charge), duplicate_input (a value given twice), memory_free (the named memory could not be used, so every row the run delivers from then on is free), memory_full (the memory holds its maximum of keys, no new row is delivered under it), invalid.

How much does it cost to transcribe Meta video ads?

Pay per event. A transcript includes the first 60 seconds of audio; a longer video adds one transcript minute per started minute after that. The add-ons are charged only when you switch them on, and only for what they deliver.

EventFree planBronzeSilverGold
Transcript (one video, first 60 seconds included)$0.024$0.024$0.022$0.019
Transcript minute (each started minute after 60 seconds)$0.015$0.015$0.014$0.012
Translation minute (optional, each started minute translated)$0.015$0.015$0.014$0.012
Text frame (optional, one frame or image with new on-screen text)$0.0064$0.0064$0.0058$0.005
Ad details (optional, per ad)$0.00128$0.00128$0.00116$0.001
Media file (optional, per file saved)$0.00256$0.00256$0.00232$0.002
Actor start (per run, per GB of memory; 1 GB by default)$0.024$0.024$0.024$0.024

Platinum and Diamond plans pay the Gold price. The Actor start has no plan discount.

The Store pricing card shows these prices per 1,000 events: "$19.00 / 1,000" on the Transcript row means one transcript costs 1.9 cents on the Gold plan, and "$12.00 / 1,000" on the Transcript minute row means one extra minute costs 1.2 cents.

Example on the Gold plan: 20 video ads of 35 seconds each cost 20 x $0.019 + $0.024 = $0.404; the same run with two 90 second ads among them adds 2 x $0.012. Videos without speech, the same creative under another ad id, videos your memory holds and failed reads cost nothing.

Input

FieldWhat it does
searchTermswords to search the Ad Library for
advertisersexact page names, page ids, Facebook page URLs or an advertiser's Ad Library page link
adUrlsAd Library links with ?id=, bare ad ids, or Ad Library search links (their filters apply)
videoUrlsdirect video files on Meta's video CDN
dataset, rowsthe dataset of an Ad Library run (picked in the form), or rows pasted as JSON
countries, activeStatus, mediaType, adType, platforms, adLanguages, searchType, sort, dateFrom, dateTo, targetedCountryOnlythe Ad Library's own filters (countries as two or three letter codes or names)
launchedAfter, adTextContains, onePerAdvertiser, pageCategories, minDurationSeconds, maxDurationSeconds, spokenLanguagesfilters applied before any download (spoken languages: after detection), free
maxAdsPerSearch, maxAds, videosPerAd, transcribeSecondssizes and caps
spokenLanguage, hookSeconds, wordTimestamps, subtitles, sceneCutstranscription options, free
translateToEnglish, onScreenText, maxTextFrames, imageAdText, adDetails, saveMediaFiles, saveImageFilesadd-ons, priced above
advertiserActiveAds, includeRawDatathe advertiser's number of active ads, the Ad Library's own record of the ad, on each paid row and its free same_video copies (not on the other free status rows); free
memoryName, newAdsOnly, resetMemory, runTag, advertiserSummarymonitoring and labels

A key sent as null or an empty text counts as left out, on every field except the seven pick lists (activeStatus, mediaType, adType, searchType, sort, onScreenText, saveMediaFiles): the platform checks those against their values before the run starts, so send one of the values or leave the key out. A value that cannot be used is listed by its position in a free row; a field whose values are all unusable stops the run before anything is read.

Each dataset or pasted row is read on its own: the filters check that row's own ad copy and start date. A row whose video link has expired is read again from the Ad Library by its ad id, and a row with only an ad id takes the ad's facts from there. Failed rows of an earlier run of this Actor (video_expired, video_failed, lookup_failed, failed, skipped) can be pasted back to try them again.

What this Actor does not do

  • It does not log in, and it reads only what the Meta Ad Library shows logged out.
  • It does not call any outside AI service: no summaries, creative critiques or ad scores written by a language model. The transcript, the hook, the calls to action and the advertiser summary rows are yours to feed to the model you choose.
  • It does not read other ad libraries (Google, TikTok, LinkedIn) or the advertiser's landing page; it delivers the landing link and domain.
  • It does not transcribe videos without speech: they are free no_speech rows (their on-screen text can be read with onScreenText).
  • Its speech model is Whisper base: on a test set of real ads the median word error was 8.6 percent in English and about 25 percent in other languages, and unknown brand names can be misheard. A video with only a few spoken words (under one second of voice) counts as no speech; a sung line can count as speech.
  • It reads the SD file of each video (same audio as HD). Video links signed by Meta expire after 1 to 4 days; an expired link of an ad with a known id is read again, others are free video_expired rows.
  • It does not keep transcripts in its memory: a video an earlier run delivered comes back as a free already_delivered row that names that run's dataset, not as a second transcript.

FAQ

How do I bulk pull transcripts from Meta video ads?

Give the Actor search terms, advertisers or Ad Library links and set the number of transcripts per search; every video ad it finds comes back as one row with its transcript, segments and hook. A dataset of another Ad Library run can be picked as the input too.

Can I download the videos from the Facebook Ad Library?

Every row carries the video file link it read (videoUrl, valid for 1 to 4 days). With saveMediaFiles set to video or audio (and saveImageFiles for image ads), the Actor also stores the file in the run's key-value store and puts its link on the row (a Media file event per file).

Does it work for Instagram ads?

Yes. The Meta Ad Library holds the ads that run on Facebook, Instagram, Messenger, Audience Network, WhatsApp and Threads; filter them with platforms.

Which languages does it transcribe?

Every language the Whisper model reads (100 language codes); each row gives the detected language and its probability. Set spokenLanguage when you know it, spokenLanguages to keep only some, and translateToEnglish for an English version of the rest.

How do I get the transcript of one Facebook ad video?

Paste the ad's Ad Library link (with ?id=) or its ad id into Ad Library links or ad ids, or the video file link into Meta video URLs, and click Start. The row carries the transcript, timed segments, the language and the opening line; a video without speech, a video your memory holds and a failed read are free rows with the reason.

Why does this Actor run with limited permissions?

It needs nothing else: it reads public pages and files, writes to its own run storage, and keeps an optional memory in a named key-value store it creates itself. It can read a dataset you pick in the dataset field, and no other storage of your account.

Use it from code

curl -X POST "https://api.apify.com/v2/acts/automation_craft~meta-ad-transcript-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms": ["meal kit"], "countries": ["US"], "maxAdsPerSearch": 5, "maxAds": 5}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('automation_craft/meta-ad-transcript-scraper').call({ adUrls: ['https://www.facebook.com/ads/library/?id=4309638865973296'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((x) => x.type === 'transcript').map((x) => x.transcript));
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation_craft/meta-ad-transcript-scraper").call(run_input={"advertisers": ["HelloFresh"], "maxAds": 10})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item["type"] == "transcript":
print(item["pageName"], item["hook"])

Changelog

  • 0.1 (2026-10-13): first release. Search, advertisers, ad links, video URLs, datasets and pasted rows; Whisper base inside the Actor; segments, words, hook, confidence, subtitles; translation, on-screen text, image text, scene cuts, ad details and media files as options; memory with new ads only and the "no longer shown" report.

More data tools by Automation Craft