Meta Ad Transcript Scraper - Video Ads to Text
Pricing
from $19.00 / 1,000 transcripts
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
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_speechrow, 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
- 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. - Set Transcripts per search and Transcripts per run (3 and 3 in the form) to the size you want.
- Click Start. Each video ad comes back as one row with its transcript; open the Transcripts view or export JSON, CSV or Excel.
- 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):
| Field | What it holds | Filled |
|---|---|---|
transcript | the speech of the video as text | 54 of 54 |
segments | the transcript in timed segments (start, end, text) | 54 of 54 |
words | every word with its start, end and probability (with wordTimestamps) | when asked |
language, languageName, languageProbability | the spoken language the model detected | 54 of 54 |
hook, hookSeconds, hookStartSeconds | the words spoken in the first seconds after speech begins, and the second it begins | 54 of 54 |
confidence | the model's own mean token probability, 0 to 1 | 54 of 54 |
speechSeconds, wordCount, wordsPerMinute | seconds of voice found, words, pace | 54 of 54 |
videoDurationSeconds, transcriptSeconds, transcriptComplete | the video's length, the audio transcribed, and whether all of it was | 54 of 54 |
adArchiveId, adLibraryUrl, pageName, adText | the ad and its advertiser (empty only for a bare video link given without its ad) | 50 of 54 |
pageId, ctaText, ctaType | the advertiser's page id and the call to action | 40 to 46 of 54 |
startDate, isActive, daysRunning | the ad's dates | 40 to 46 of 54 |
publisherPlatforms, landingUrl, landingDomain | where it runs and where it sends people | 38 to 40 of 54 |
targetedOrReachedCountries | as 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, videoUrlExpiresAt | the 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, rawAd | the options and add-ons below | when asked |
imageUrl, imageText, mediaFileUrl | on image_text and image_file rows: the image ad's file, its text, the saved file | when asked |
status, paidEvents, message | why a row is what it is, and the events it is charged for | every 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.
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| 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
| Field | What it does |
|---|---|
searchTerms | words to search the Ad Library for |
advertisers | exact page names, page ids, Facebook page URLs or an advertiser's Ad Library page link |
adUrls | Ad Library links with ?id=, bare ad ids, or Ad Library search links (their filters apply) |
videoUrls | direct video files on Meta's video CDN |
dataset, rows | the 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, targetedCountryOnly | the Ad Library's own filters (countries as two or three letter codes or names) |
launchedAfter, adTextContains, onePerAdvertiser, pageCategories, minDurationSeconds, maxDurationSeconds, spokenLanguages | filters applied before any download (spoken languages: after detection), free |
maxAdsPerSearch, maxAds, videosPerAd, transcribeSeconds | sizes and caps |
spokenLanguage, hookSeconds, wordTimestamps, subtitles, sceneCuts | transcription options, free |
translateToEnglish, onScreenText, maxTextFrames, imageAdText, adDetails, saveMediaFiles, saveImageFiles | add-ons, priced above |
advertiserActiveAds, includeRawData | the 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, advertiserSummary | monitoring 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_speechrows (their on-screen text can be read withonScreenText). - 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_expiredrows. - It does not keep transcripts in its memory: a video an earlier run delivered comes back as a free
already_deliveredrow 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 ApifyClientclient = 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
- Meta Ads Library Scraper - Ad Library, All Filters
- Facebook Ads Library Scraper - Ad Library & Spy
- Instagram Ads Library Scraper - Creatives, Video
- Meta Ad Spend Scraper: Advertiser Spend by Country
- TikTok Creative Center Scraper: Top Ads, No Login
- Google Ads Transparency Scraper - Decoded Creatives
- TikTok Video Scraper: Post Stats, Transcripts
- Facebook Posts Scraper - Page Posts, No Login