Ad Creative Intelligence — Transcript, Hook, On-Screen Text avatar

Ad Creative Intelligence — Transcript, Hook, On-Screen Text

Pricing

from $37.50 / 1,000 video_analyzeds

Go to Apify Store
Ad Creative Intelligence — Transcript, Hook, On-Screen Text

Ad Creative Intelligence — Transcript, Hook, On-Screen Text

Turns ad video URLs into transcripts with timestamps, on-screen text, the first-3-seconds hook and the detected CTA. Pay per analyzed video, no login, no API key.

Pricing

from $37.50 / 1,000 video_analyzeds

Rating

0.0

(0)

Developer

Andrey Kurilov

Andrey Kurilov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Ad Creative Intelligence — Transcript, On-Screen Text, Hook & CTA | $50/1k videos | No Login

Turn a list of ad video URLs into structured creative intelligence: a full transcript with timestamps, the text burned onto the screen, the first-3-seconds hook and the call to action — one JSON object per creative, $0.03 per analyzed video.

What it solves

Getting the ads themselves is a commodity — a dozen Ad Library scrapers do it for $0.15–1.00 per 1 000. The question your team actually asks is one level up: what is said in the creative, what is written on it, and what is the hook that stops the scroll?

This actor is the second step in that pipeline. It takes the media URLs you already have and gives back the analysis layer:

  • Hook — what the creative opens with in the first 3 seconds, the window performance buyers benchmark. Both channels are reported: what is spoken there and what is burned onto the opening frames, because a modern creative usually carries the hook in both at once. Cut on word timings, so a single long spoken segment does not spill the whole script into the hook. A creative that opens on music has no hook in the window — you get an empty hook.text with emptyReason and firstSpeechStartSec, the hook delay, rather than a line quoted from the middle of the ad.
  • Transcript — segments with timestamps, plus a flat transcriptPlain string to pipe into an LLM.
  • On-screen text — offers, prices and captions burned into the video, read off key frames.
  • CTA — the detected call to action and where it appears.
  • Pace and identity — scene-change count and a perceptual hash of the creative.

Typical recipe: Meta Ad Library Scraper ($0.15/1k) → this actor → your hook library.

Built for performance agencies and media buyers, UGC studios building hook libraries, brands monitoring competitors, and ad-intelligence tools that need a speech layer without running the infrastructure.

Input example

{
"videos": [
{
"url": "https://archive.org/download/OlayTotalEffectsAdvert/Olay%20Total%20Effects%20Advert.ia.mp4",
"meta": { "adId": "OlayTotalEffectsAdvert" }
},
{
"url": "https://archive.org/download/LOrealElviveDavidGinolaAdvert1998/L%27Oreal%20Elvive%20David%20Ginola%20Advert.ia.mp4",
"meta": { "adId": "LOrealElviveDavidGinolaAdvert1998" }
}
],
"language": "auto",
"asrModel": "fast",
"extractOnScreenText": true,
"maxFrames": 12,
"hookWindowSeconds": 3,
"skipIfNoSpeech": false,
"maxVideoDurationSeconds": 300,
"maxConcurrency": 6
}

Only videos is required. Send batches, not single URLs: every run has a fixed start-up cost that is billable, so 20 videos is the smallest sensible run and 100–500 is the sweet spot.

Input fields

FieldTypeDefaultDescription
videosarrayItems with a direct media url and optional meta passed through to the output. Required.
languagestringautoKeep auto. Forcing the wrong language is the most common source of garbage transcripts.
asrModelenumfastfast (4 GB) or accurate (8 GB, better on noisy or music-heavy ads, doubles the compute cost).
extractOnScreenTextbooleantrueRun OCR over key frames. Turn off for a cheaper audio-only pass.
maxFramesinteger12Cap on key frames per video, picked by scene-change detection.
hookWindowSecondsinteger3Length of the opening window reported as the hook.
skipIfNoSpeechbooleanfalseReport silent videos as no_content without running OCR.
maxVideoDurationSecondsinteger300Hard ceiling. Longer videos fail for $0. Can be lowered, never raised.
maxConcurrencyinteger6Upper bound on videos in flight. The run lowers it to what the memory you gave it can keep busy.

Output example

Real output for the first video of the input above — this is what the actor returned on the platform, not an illustration.

{
"sourceUrl": "https://archive.org/download/OlayTotalEffectsAdvert/Olay%20Total%20Effects%20Advert.ia.mp4",
"adId": "OlayTotalEffectsAdvert",
"status": "ok",
"failureReason": null,
"durationSec": 19.621,
"language": "en",
"hasSpeech": true,
"hook": {
"text": "You can either buy an anti-aging cream that works in lines and wrinkles",
"windowSec": 3,
"spokenWords": 13,
"source": "speech",
"spokenText": "You can either buy an anti-aging cream that works in lines and wrinkles",
"onScreenText": null,
"firstSpeechStartSec": 0.14,
"emptyReason": null
},
"transcript": [
{
"start": 0.14,
"end": 9.2,
"text": "You can either buy an anti-aging cream that works in lines and wrinkles or one designed to work on pores, blotches, tone, texture, radiance and lines and wrinkles.",
"confidence": 0.8313
},
{ "start": 9.48, "end": 14.4, "text": "Only one cream guarantees to reduce the appearance of all seven signs of aging or your money back.", "confidence": 0.8313 },
{ "start": 14.92, "end": 15.44, "text": "Total Effects.", "confidence": 0.8313 }
],
"transcriptPlain": "You can either buy an anti-aging cream that works in lines and wrinkles or one designed to work on pores, blotches, tone, texture, radiance and lines and wrinkles. Only one cream guarantees to reduce the appearance of all seven signs of aging or your money back. Total Effects. Not a difficult choice. Total Effects from Ole.",
"onScreenText": [
{ "atSec": 1.96, "text": "A", "confidence": 0.7936 }
],
"cta": null,
"sceneChanges": 6,
"perceptualHash": "01694949418a0400",
"meta": { "adId": "OlayTotalEffectsAdvert", "sourceDurationSec": 19.6, "bytes": 1918100 },
"processedAt": "2026-09-14T11:17:05.746Z"
}

This creative opens on the voiceover, so source is speech. On a creative that opens on a text card with the presenter a beat behind, source is both and the card is in onScreenText — 10 of the 40 creatives in the measured batch were that shape. On one that opens on music, text is null, emptyReason is speech_starts_later, and firstSpeechStartSec tells you how late: that was 8 of the 40.

Output fields

FieldTypeDescription
sourceUrlstringThe submitted media URL. Normalized, it is also the charging key.
adIdstring | nullCopied from meta.adId.
statusok | no_content | failedok — speech or on-screen text found; no_content — processed but empty; failed — unusable media.
failureReasonstring | nullunreachable, unsupported_media, too_long, timeout, internal_error.
durationSecnumber | nullVideo duration.
languagestring | nullISO 639-1 code detected from the audio.
hasSpeechbooleanWhether any speech was recognized.
hookobject | nullThe opening window: text, spokenText, onScreenText, windowSec, spokenWords, source (speech, on_screen, both or null), firstSpeechStartSec, emptyReason. Null only when the video failed. On a no_content video the object is present and emptyReason says why it is empty.
transcriptarray{ start, end, text, confidence } segments in chronological order.
transcriptPlainstring | nullThe whole transcript as one flat string, for LLM input.
onScreenTextarray{ atSec, text, confidence }, deduplicated across frames.
ctaobject | null{ text, atSec, source } where source is on_screen or speech.
sceneChangesinteger | nullDetected scene changes — a proxy for editing pace.
perceptualHashstring | nullFingerprint of the creative, for spotting the same ad under another advertiser.
metaobject | nullYour input meta, unchanged.
processedAtstringUTC ISO-8601 timestamp.

The full typed schema lives in .actor/dataset_schema.json, so MCP clients and LLM agents can pick the actor up without guessing.

Pricing

Pay per event. You are never charged for a failure.

Billed per started 30 seconds of video, because that is how the work scales. A 15-second creative costs less than it did under the old flat rate; a two-minute one finally pays for the two minutes of transcription it takes.

EventPriceWhen
actor-start$0.010Once per run.
video_analyzed$0.050Video processed, speech or on-screen text found. Covers the first 30 s.
video_extra_block$0.050Each started 30 s beyond the first.
video_no_content$0.010Video processed, nothing found. Covers the first 30 s.
video_failed$0.000Media unreachable, broken, longer than the duration limit — or a stage of ours failed and produced nothing. No event is reported at all, so it cannot appear on your invoice.

That is $50 per 1,000 creatives up to 30 seconds, which is how ad creatives are actually counted. Pricing per media-minute would be the wrong unit here and misleading: because a started block is billed whole, a 15-second creative works out at $100 per 1,000 real minutes and an 8-second one at $188. You buy analyses of creatives, not minutes of audio.

Calculator — a typical batch of 500 creatives, 470 with content, most of them short:

actor-start 1 × $0.010 = $0.01
video_analyzed 470 × $0.050 = $23.50
video_extra_block 90 over 30 s × $0.050 = $4.50
video_no_content 20 × $0.010 = $0.20
video_failed 10 × $0.000 = $0.00
───────
500 creatives $28.21 (≈ $0.056 per creative)

For comparison, the closest listing in the store returns a transcript and on-screen text — no hook, no CTA, no scene count, no perceptual hash — and charges $75 per 1,000.

Set ACTOR_MAX_TOTAL_CHARGE_USD on the run to cap the spend: when the cap is hit the run finishes cleanly and keeps everything already stored in the dataset — it does not crash, and it does not charge twice for a retried video.

What you are guaranteed

Nothing leaves the run. Everything is computed on the Apify machine you pay for — no third-party transcription service, no external AI provider, no key of yours or of ours. There is nothing to sign up for, nothing to rate-limit you, and your creatives are not handed to anyone.

A partial result is still a result. If one half of the analysis cannot be produced, you get the other half rather than an error — and you are charged the normal rate, because a transcript without on-screen text is still worth having.

Our breakage is never your bill. An empty result looks the same whether the creative carried nothing or something on our side failed to read it. The two are told apart explicitly: nothing found and everything worked → no_content from $0.010; nothing found because something broke → failed / internal_error at $0.000.

More memory is faster at the same price. Doubling the memory roughly halves the time and costs the same in total. Pick memory for how quickly you want the batch back, not to save money — and leave maxConcurrency alone unless the media host is slow.

FAQ

Do I need a Facebook/TikTok login, cookies or an API key? No. The actor takes media URLs you already have and downloads them over plain HTTP.

Does it scrape the Ad Library? No, by design. Ad Library scrapers are a commodity at $0.15/1k — use one of those and feed its output here. That also keeps this actor complementary to the tools you already run.

What if the same video appears twice in a batch? The charging key is the normalized URL, so you are billed once per creative even across retries of the same run.

Which languages? Transcription covers ~99 languages and the language is auto-detected from the audio — do not set it by hand unless you are certain. CTA detection covers English, Spanish, Portuguese and German.

How long may a video be? 300 seconds by default, and that is a hard cap. Anything longer is reported as failed / too_long and charged $0, so one stray long-form video cannot eat your budget.

Can I run it on a schedule? Yes. A failed result reports no billable event at all and an empty one starts at $0.010, so polling is cheap.

Limitations

  • Direct media URLs only; resolving an ad ID to a media URL is not implemented in v1.
  • The cta field is the call to action inside the creative — burned into a frame or spoken in the voiceover. It is not the Ad Library button ("Shop now", "Learn more"): that is rendered by Meta outside the video and cannot be recovered from the file. If you need it, it comes from the Ad Library scraper that fed you these URLs, in its ctaText. Measured against Meta's own labels on 5 live creatives, our field agreed 0 times — by construction, not by failure.
  • No face recognition, no biometric processing, no personal-data extraction — not now, not on request.
  • Transcripts are produced for analysis; the actor never republishes the source media.
  • Quality on heavily music-covered voiceovers is lower — check confidence rather than assuming.
  • Videos above 256 MB are reported as unsupported_media.
  • A caption that flashes on and off very briefly can be missed. Raise maxFrames for text-dense creatives.
  • The same caption seen more than once is reported once, near-identical misreadings included. A caption whose wording genuinely changes later stays a separate entry.

Roadmap

  • v1 — this scope: transcript, on-screen text, hook, CTA, scene changes, perceptual hash.
  • v2 — hook typology (question / shock-stat / problem / demo / testimonial), sentiment, offer and price extraction, creative deduplication by perceptual hash.
  • v3 — Standby mode for agents, MCP tool, cross-platform comparison of one creative.

Disclaimer

You are responsible for complying with the terms of service of the platforms your media comes from and with applicable data-protection law. This actor analyzes advertising creatives; do not use it on private, personal or paywalled content.