Charged only when a transcript is delivered — expired links and music-only ads are free rows. TikTok Creative Center Top Ads → transcript, first-3s hook, CTR and brand metadata. Paste ad links or material IDs (a fresh link is fetched for you) or chain any scraper. No start fee.
Clearer wording on uncharged no-speech rows: an ad whose audio turns out to be music-only or silent now says exactly that in statusReason, in plain language. The same ads are recognised as before, and they are still never charged.
1.0.15 — 2026-08-29
Silent ads can now be read instead of skipped — and every run says how many it saw.
New option: Read on-screen text on silent video ads (includeOnScreenText, off by default). A music-only or voice-less Top Ad has its message on the screen, not in the audio. With the option on, the ad's own keyframes are read and delivered as onScreenText (headline, body, CTA, and the full visible text), charged like a transcript — same event, same price, never the extra-minute surcharge. With it off, nothing changes: silent ads ship free exactly as before.
An ad with no readable on-screen copy is still never charged. Silent b-roll whose only visible text is a logo or a placard comes back as an uncharged no_onscreen_text row rather than a charged row of noise, and the brand name always comes from TikTok's own metadata, never from reading a video frame.
Every run now reports the silent ads it found, so you can see what the option would turn into results before you turn it on.
When the speech service refuses this actor's access mid-run, the ads left over now each get their own row saying the problem is on our side and that a re-run should work — instead of vanishing into a single line in the run summary. Nothing is charged for them.
Extra-minute surcharge accounting is now belt-and-braces: if that event is ever missing from the price list, a long ad delivers its transcript and reports zero surcharge minutes, instead of listing minutes that were never billed.
1.0.14 — 2026-08-29
A busy CDN is no longer reported as an expired link.
A busy or briefly failing video CDN is now a temporary, uncharged miss that asks you to re-run — instead of telling you your whole batch of links was stale and sending you back to re-scrape them. Links that really did expire read exactly as before.
The run summary's "your links have expired" note now appears only for links that really did expire, so a short upstream hiccup can no longer make a fresh batch look old.
When Creative Center answers a fresh-link lookup with a block page instead of the ad, the row now says so and invites a re-run, and the lookup retries on a new connection. It used to be reported as an unreadable page with nothing you could do about it.
An ad page that redirects to a sign-in, consent or region page is now an uncharged, retryable miss. Only a redirect back to the Top Ads listing still means the ad has been delisted.
1.0.13 — 2026-08-29
A typo in an input field name now gets a helpful pointer instead of sample rows. A field the actor does not recognise is ignored by the platform, so an input like adIds used to look exactly like a blank run and came back with the free demo row — as if the typo had worked. Such a run now returns one free row that names the field it could not recognise, names the fields to use instead (materialIds / videoUrls, with the shape to paste) and the chaining fields. Nothing is charged, and a genuinely blank run still returns the demo row exactly as before.
1.0.12 — 2026-08-29
Rate-limit retries now reuse the video already in hand. When the speech service asks the actor to wait, the retry transcribes the bytes it already downloaded instead of fetching the file (or re-opening the ad's detail page) again — retries are faster and cheaper, and a link that expired mid-run can no longer be misreported as permanently dead when the real cause was a brief wait.
A speech-service access problem now stops the run honestly. If the speech service refuses this actor's access, the remaining ads are no longer processed one by one toward calls that cannot succeed: the run stops cleanly, the status line says how many ads were left and that the problem is on our side, and none of them are charged.
1.0.11 — 2026-08-28
Interrupted runs now resume without double-charging. If the platform moves a run to another server mid-batch (or you resurrect a finished run), the actor now recognises every ad it already delivered: nothing is fetched, delivered, or charged a second time, and any charge the interruption cut short is settled honestly. Before, a moved or resurrected run could deliver duplicate rows and charge again for ads you already had.
A run's time ceiling now counts from when the run started, not from the latest restart, so an interrupted run can no longer live (and cost) longer than the ceiling promises.
Long-video surcharge budgeting now also reserves for ads still being processed by parallel workers, so a batch of long videos near your maximum cost stops honestly instead of being cut off by the platform.
Chaining from a mistyped or unreadable Dataset ID now returns one free row naming the ID and what to fix, instead of finishing quietly with an empty result.
1.0.10 — 2026-08-27
Billing accuracy: a row now reports charged: true only when a charge was actually made on your run — before, a delivered transcript always said it had been charged, even on runs where nothing could be.
A video file that arrives cut short is now spotted before transcription. The actor retries it, and if it still will not download in full you get an uncharged row saying so — instead of a transcript of part of the ad that you were charged for.
A maximum cost per run that covers exactly one transcript now delivers that transcript, instead of stopping with nothing and asking you to raise the cap.
Runs close to their maximum cost now reserve extra-minute headroom against the current prices, so long videos stop honestly instead of being cut off part-way.
1.0.9 — 2026-08-27
Price cut. A delivered transcript now costs $0.020 down to $0.008 depending on your Apify plan tier — the volume price was $0.015. The free-plan price and the $0.005 extra-minute surcharge are unchanged, and you are still charged only when a transcript lands in your dataset.
The pricing block in this page now shows the new figures.
1.0.8 — 2026-08-27
Added a plain note that this is an independent actor — unofficial, and not affiliated with or endorsed by TikTok.
The directory of other steadyfetch actors now covers every family (ad creatives, trends and keywords, YouTube, Instagram, jobs, Amazon, and general media) and names each one exactly as it appears on the Store, so a link always lands where the name says. It now sits at the end of the page, just above support.
1.0.7 — 2026-08-27
The README now opens with an Output section — a sample results table, a screenshot of a real run's output, and the full JSON row — so you can see exactly what you get back before spending anything.
Added a copy-and-paste block for AI agents and LLM clients: actor id, a complete input example, every output field, and the exact event prices.
Added a directory of the other steadyfetch ad-intelligence actors (Facebook & Instagram, Google Ads, LinkedIn, Instagram Reels, Google Trends) with their free n8n templates.
The example dataset linked from the README is now permanent, so it will not expire.
1.0.6 — 2026-08-25
You can now paste Creative Center ad page links directly — the URL you get browsing Top Ads (ads.tiktok.com/business/creativecenter/topads/<id>, with or without tracking parameters) works in both the video-URLs and material-IDs fields; a fresh video link is fetched for each. Pasting a listing page (Top Ads or Spotlight) now returns clearer uncharged guidance.
1.0.5 — 2026-08-21
Added a ready-made n8n workflow and a live example dataset to the README.
1.0.4 — 2026-08-21
Billing accuracy: the same ad supplied more than once (URL, id, or chained row) is delivered and charged once; long-video surcharge charges always match the per-row ledger, and runs near the spend cap stop honestly; improved music-only detection (still never charged).
Fixes: maxAds now counts only transcribable ads, so free informational rows always ship; corrupted numeric ad ids are refused with a clear reason instead of fetching the wrong ad; stricter media-URL and download-size safeguards; sturdier transcription timeouts.
1.0.3 — 2026-08-21
Initial release: transcripts + first-3-seconds hooks for TikTok Creative Center Top Ads — from ad video URLs, Top Ads material IDs or detail-page URLs, or chained after any Creative Center scraper run (dataset ID or pasted rows). Brand, title, CTR, cost, likes, industry and objective ride along on every row.
Built for TikTok's ~6-hour video links: expired links are detected before any download and come back as uncharged rows with the exact expiry time (urlExpiresAt); rows that carry a material ID get a fresh link fetched automatically — and that fresh link (with its expiry) is reported on the row whatever the outcome.
Charged only on delivery: expired links, music-only or voice-less creatives, ads that dropped out of Top Ads, and input mistakes arrive as uncharged rows with the reason stated. The first 3 minutes of each video are included; longer videos add a small per-started-minute surcharge. No start fee.