- Clearer wording on uncharged no-speech rows: an item whose audio turns out to be music-only or silent now says exactly that in its row note, in plain language. The same items are recognised as before, and they are still never charged.
Chain it after any scraper, and hear about a setting the run could not use.
- New: chain a scraper run straight into this actor. Put a finished run's Dataset ID into the new field — with Apify's Connect actor integration it fills itself — and every row is deep-scanned for one audio or video link, whatever the scraper calls it (
videoUrl, audioUrl, mediaUrl, playAddr, downloadAddr, a bare file link, nested or top-level). Prefer to paste? The new Dataset items field takes the rows directly.
- One media link per row, and never a double charge. A row's video and its own audio track are the same item, so they bill once; a link you also listed in Media URLs is transcribed once; thumbnails, covers and profile pictures are never mistaken for media. Rows carrying no media link are counted on the run's status line and cost nothing.
- A dataset this actor cannot read is answered, not swallowed. A wrong ID — or one whose read access was never granted — comes back as a single uncharged row telling you which ID failed and what to do, and the good links in the same run still run.
- A setting the run could not use is now said out loud. An output format that is not one of
text, segments, srt, vtt, or a language hint that is not a two-letter ISO 639-1 code, used to be dropped in silence. The run's status line now names it and says what happened instead — and a run with nothing to report stays exactly as quiet as before.
- Nothing about pricing changed: chained items are charged per audio minute transcribed, exactly like a pasted link.
A host that blocked us is no longer reported as a file that is gone.
- A host that answers 401, 403 or 451 — a hotlink-protected, geo-gated or bot-walled CDN — is now reported as a temporary block you can re-run, not as a file that is unavailable at that address. 404 and 410 still come back as a permanent answer.
- When a host serves a web page or a short message where the audio file should be, that is now reported as a block on the link you gave us rather than as "you pasted a page". A link that really is a page still gets the old, plain answer.
- Page links on supported sites no longer come back as "this page exposes no audio or video" when the site simply refused us or changed its markup. Those now say so and ask for a re-run; a page that genuinely has nothing to transcribe is unchanged.
- A bot check worded "sign in to continue" is no longer mistaken for a paywall. Pages that really do need an account, a subscription or an age confirmation still say exactly that.
- Every row now carries a
retryable column: true means the host blocked or throttled us and running the same input again is worth it, false means the answer will not change. Nothing about pricing changed — none of these rows is ever charged.
- A typo in an input field name now gets a helpful pointer instead of the demo row. If you send a field this actor does not have —
url instead of urls, say — the run now returns one free row that names the field it did not recognise, names the one you meant, and shows the shape to send. Before, that run looked exactly like a run with no input at all and answered with the demo row, which made a typo look like it had worked. Nothing is fetched and nothing is charged either way.
A speech-recognition outage on our side now stops the run cleanly instead of failing every item one by one.
- If the transcription service refuses this actor's access mid-run, the run stops paying for work it cannot deliver. The item that hit the refusal comes back as an uncharged
asr_unavailable row saying plainly the problem is ours, and every remaining item is answered instantly with the same uncharged status — no more downloading and decoding each file first only to fail at the last step. The run status names the outage and says to try again later. Ordinary rate-limit blips keep their usual retries and are unaffected.
A blank line in your list now gets a straight answer instead of being called a duplicate.
- An empty or whitespace-only entry in
urls now returns the uncharged input_error row
this listing promises, with a note saying what to pass. It used to return no row at all,
and the run status reported it as an item "already in this run's results" — a duplicate of
something that was never there.
- The already-delivered count in the run status now counts only genuine duplicates.
Blank entries, and any other entry that is not a usable link, are answered once each and
never inflate it.
- The run status now says "1 entry was not a usable link" where it used to mismatch its own
count.
Review-fix build: a row's charged column now always matches what the run could actually bill.
- Fixed: a run that could not bill — an unmonetized copy of the actor, or a price that had not
taken effect yet — still marked delivered transcripts as charged and counted those charges in the
run summary, even though nothing reached your invoice. Such a run now delivers the transcripts
free, marks every row
charged: false, and says so in the run log. The dataset reconciles against
your invoice in every case, not just the normal one.
- Fixed: the same run also budgeted itself as though it had unlimited billable room, so the
"max total minutes" and cost caps you set were not applied to it. The caps now hold on every run.
- If this actor's billing is ever mis-set in a way that would charge you for the rows this listing
promises carry no result fee — misses, refusals, the free sample — the run now fetches nothing,
delivers nothing and charges nothing, and tells you plainly that the fault is ours. A pricing
mistake on our side can no longer put a charge on a free row.
Interrupted runs now pick up exactly where they left off, and long or awkward files cost less time.
- Fixed: a run that was interrupted and restarted — moved to another server by the platform, or
resurrected by you from the Runs tab — could deliver the same item a second time and charge for it
again. A restarted run now recognises everything it had already delivered, skips it, and never
charges twice for it. Anything that was delivered but not yet billed when the interruption hit is
settled once, so no row is charged twice and no delivered row goes unbilled.
- Fixed: on a restarted run, "Max total minutes" started counting again from zero, so a run could
transcribe up to twice the limit you set. The limit now covers the whole run.
- Fixed: the actor's own run-length ceiling also restarted on an interruption. It now runs from when
the run started.
- Items that were never started when a run is interrupted carry no key, so a resumed run picks them
up normally — you never lose the tail of a list to a restart.
- Faster on hosts that ignore range requests (large archives and some podcast CDNs): those files were
being downloaded twice, once to identify them and once to transcribe them. They are now fetched
once.
- Faster on long recordings: the decoded audio is written once and each window is cut from it, rather
than rewriting the whole decoded file for every window. A multi-hour recording spends noticeably
less time before its first transcript.
- How many items run at once is now sized from the run's memory, so a batch of very large files can
no longer exhaust it mid-run.
Review-fix build: charge settlement, live-stream refusal, transcript stitching and subtitle timestamps.
- Fixed: on a run with a total-minute or charge cap, an item trimmed to fit what was left could
silently shrink the budget for everything after it. Later items were transcribed and delivered but
came back marked as uncharged while real chargeable room remained. The remaining budget is now
exact, so every item that gets a transcript gets billed for it.
- Live radio streams are now refused the moment the server's reply headers arrive, rather than after
waiting for a body that never ends. The modern kind of stream — which answers like a normal file
and simply never stops — used to burn the full 30-second timeout and come back as "please re-run".
It now returns the same uncharged live-stream row as the classic kind, immediately.
- A slow host that does state its file size keeps the honest "temporary, try again" row, and neither
case switches the rest of the run onto a proxy: the server answered, so nothing is wrong with the
connection.
- Fixed: in a very long recording, a final window that the previous window had already covered
entirely could repeat its last few words in the plain-text transcript. The timestamped segments
were always correct; the plain text now matches them.
- Fixed: a subtitle time landing a hair under a whole second (59.9996s) could render the malformed
stamp
00:00:59,1000. It now rolls over correctly to 00:01:00,000, including across minutes
and hours.
- Live radio streams are now caught in both of the forms servers use: the newer kind that answers
normally, and the classic kind whose reply an HTTP client cannot parse at all. Either way you get
one uncharged row saying it is a live stream, instead of a message asking you to try again.
- Fixed: a run whose charge cap covered exactly one audio minute returned no transcript at all —
every item came back as a "budget stop" row. A one-minute cap now delivers that minute.
- Fixed: on a run with no pricing attached, rows said they had been charged when nothing had been.
Rows now report
charged: false and chargedMinutes: 0 unless a charge was really made.
- Live radio streams (ICY / SHOUTcast / Icecast URLs) are now refused on the first few kilobytes
with a row that says so, instead of downloading up to the size limit and reporting "too large".
- A web address whose domain does not exist is now reported as a permanent problem with the
hostname named, instead of asking you to re-run something that can never succeed.
- Very long recordings no longer spend an extra transcription pass on a final sliver of audio the
previous window had already covered.
- Transcribe any direct audio or video file link, from any host — signed CDN links and links with no file extension included.
- Page links supported on 11 tested sites: Libsyn, Megaphone, Buzzsprout, Acast, Spotify for Podcasters (Anchor), S3/CloudFront, Archive.org, SoundCloud, Loom, Twitch VODs and Wistia.
- Output formats: plain text, timestamped segments, SRT and VTT subtitle files.
- Automatic language detection across about 90 languages.
- No length limit: long recordings are transcribed in overlapping windows and stitched back together with continuous timestamps.
- Charged per audio minute actually transcribed. Unreachable links, music-only audio, oversized files, live streams and unsupported pages carry no result fee, and every one of them comes back as a row explaining why.
- Two run limits, both optional: max minutes per item and max total minutes.