- The results receipt at the end of your dataset now reports the same "left at your cap" counts as the rest of the run. Every run closes with one uncharged
_summary row carrying the run's own tallies. A capped run leaves reels behind in two places — reels the run had already found and could not pay for, and reels it never got as far as asking for because the cap had already bounded how many it could plan — and while your results record and the run page both count the two together, that receipt row counted only the first. On one real run it published 18 reels left where the record beside it said 231, and on another, whose cap bound only the planning, it published a flat zero while one reel had in fact been left. From this build the receipt's skippedBudget and skippedMaxItems are the same numbers the record and the run page publish, so the three surfaces agree. Nothing about what you are charged changes, and no price, input field or delivered column moves.
-
More of the "Maximum cost per run" you set is now spent on reels. Before this build the run held back about a tenth of your cost cap before it started looking — a cushion for platform running costs which, on this actor's pricing, your cap does not pay for at all: your cap buys transcripts, and the running costs are ours. So the cushion was simply cap you had asked to spend and could not get. Measured on a run capped at $0.10 with transcripts at $0.01: the run planned nine reels where the cap paid for ten, delivered nine, and counted the tenth as left at your maximum cost — a whole reel of your own cap unspendable. From this build the plan uses the cap in full, so a run asks for as many reels as your cap can really pay for: one more reel on that $0.10 run, and about nineteen more on a $3.00 one. Nothing you are charged changes, and nothing can be charged above the cap you typed — every charge is still checked against what is left of your cap at the moment it is posted, a long video's extra minutes are still held to what the cap can cover, and a run that reaches your cap still stops honestly, ships what it had already fetched without charging for it, and tells you what is left. No price, input field or output column changes.
-
When a run stops at your "Maximum cost per run", the run page now tells you how many reels are really left — and it says so on runs that used to say nothing at all. A capped run leaves reels behind in two places: reels it had already found and could not pay for, and reels it never got as far as asking for, because the cap had already bounded how many it could plan. Your results record has always counted both together; the line on the run page counted only the first. On one real run that meant the page said 18 reels were left where 231 were, and on another — a run whose cap bound only the planning — the page said just "Delivered 9 transcripts." with no mention of the cap, no count of what it left, and none of the advice about re-running. From this build the count on the run page is the same number your results record publishes, and the cap clause appears on every run a cap actually stopped, together with the reminder that re-running with "New reels only" on skips what you have already paid for so nothing is charged twice. The same correction applies to the "beyond maxItems" count. Nothing about what you are charged changes — only what the run page tells you.
-
Your reels now start arriving while the rest of your creator list is still being read. Until this build a run with more than one creator read every creator first and only then began transcribing, so one creator Instagram would not answer held back reels the run had already found — on a long list that could be several minutes of an empty dataset with nothing wrong. From this build each creator's reels go straight into transcription as that creator is read, so the first rows land on the first creator's time rather than on the whole list's. Measured on an eleven-creator run where the second creator was unreachable for five minutes: the first row used to land after the last creator was read, and now lands within seconds of the first one. Nothing about the order of your dataset changes — reels still read newest first by date per creator, and pasted links and chained rows still read in the order you supplied them (on a run that mixes creators with links, the creators' reels now come first and the links follow). No price, input, output column or charge changes.
-
The run page now says which creator it is reading and how many reels are already queued. Reading a creator that is not answering is the longest quiet stretch this actor has, and the page could not tell you whether anything had been found yet — so a working run and a stuck one looked the same. It now reports "Reading creator 3 of 11 — 7 reels queued and already being transcribed" as it goes, beside the progress line it already posts every thirty seconds.
-
One unreachable creator no longer spends the run that the creators behind it were owed. When a run has already listed reels for other creators in your list, it now stops waiting on an unresponsive creator after one full set of attempts instead of continuing for as long as your run time allows. The first creator of a run is never cut this way — while nothing has been found, the creator being read may be the only one there is, so it still gets every attempt. When this does end a creator's listing, that creator's row says so plainly and names what to do about it (re-run it on its own, or with fewer creators), rather than pointing at a "Reels per handle" depth you never reached. Nothing is charged for reels a listing never reached.
-
A creator's list is no longer reported as an account that does not exist. When Instagram will not serve a creator's reel feed, the run collects the list from another source. That source answers "this account has no reels" and "this account does not exist" with the same response, and the run was reading both as the second — a permanent verdict about an account whose own profile the same run had just read successfully, and one no re-run could clear. Since nothing in the run can tell those two answers apart, it now says only what it knows: the read was refused outright rather than answered, it is not a verdict about the account, and there is nothing to be gained from running it again. Reels the run had already listed for that creator are kept, and nothing is charged for the ones it never reached.
- The monthly allowance behind this actor's data reads is now $60, up from $25 — a busy month no longer stops delivery part-way through. Nothing you are charged changes: the allowance is ours, not yours, and a run that ever meets it still stops honestly and charges nothing for what it did not deliver.
- The profile-lookup fee this page mentions is live now, so the page states it plainly instead of announcing it. The Instagram-suite section told you that profile posts would begin adding a $0.003 profile lookup on a coming date. That fee took effect, so the sentence is now in the present tense: profile posts adds one profile lookup of $0.003 per profile that delivers posts, and a profile that delivers nothing pays nothing. The shelf line naming the three actors that carry a small delivery-conditional fee reads the same way. This build changes nothing about this actor: no input field, output column, charged event or price of its own moved.
-
A short run gave up on a creator's list with most of your run time still unspent, then asked you to raise it. Before asking for one more page, the run charged that page the most a read can possibly take — twenty seconds — on top of the thirty seconds it holds back for writing your rows. On a short window that bar was most of the window: a run with forty-seven seconds still in hand read nothing further, on pages that were costing about a second each, and a run set to the shortest time this actor accepts was over the bar before it started. From this build the run asks the honest question instead — is there room, above what writing your rows needs, for a read worth having — and what it holds back for the rows is sized to the run time you actually bought rather than a flat thirty seconds. Runs of a few minutes or longer behave exactly as before, and a creator's list Instagram really does cut short still reads as that. Nothing is charged for reels a list never reached, and no price, input or delivered column changes.
-
A list stopped so a creator's own profile page could still be read was reported as this run's depth limit — a setting you had not touched. When Instagram will not serve a creator's post feed, the reels shown on their profile page are the last place left to look, and the run keeps back a little time so that step is still reachable. When that hold-back ended the list, nothing upstream had refused us and the "Reels per handle" depth was never reached — yet the reels that were never listed were counted against that depth, and the run page told you to raise it. From this build they are counted against your Max run time, where they belong, and the row says which hold-back took them, with both levers named: a longer run, or a smaller ask. It is the same correction 1.0.111 made for the time held back for transcription. A list Instagram really cuts short is unchanged, nothing was charged for those reels either way, and no price, input or delivered column changes.
- When your own "Max run time" is what ends a run, the extra data source is no longer blamed for it. That source is asked when Instagram will not serve a reel or a creator's list. Its reads were timed from their own start rather than against your run, so a read begun near your limit could run past it — and when your limit was what stopped it, the run treated that as the source being slow: it waited, asked again, waited again, spending the very seconds it needed to write your rows, and then told you the source was unavailable and to re-run. Those reads are now given only the time your run actually has, a read your limit cut is not waited out or re-asked, and the row already says plainly that this run's own time limit stopped it and names the setting to raise. A real outage or rate limit on that source is still waited out and still reads exactly as before, and nothing about what is delivered or charged changes.
-
Price copy only. The README's pricing block now names the paid-plan price in effect since 15 September 2026 20:15 UTC — $0.0075 per delivered transcript on Silver and above (Bronze $0.010 and the Apify free plan's $0.015 are unchanged, as is the $0.005 long-video minute). The rise was notified on 1 September; this build changes no delivery, charge or input.
-
A run that filled your "Maximum cost per run" said how many reels were left, and not how to get them. When the cap you set runs out, the reels behind it are not attempted and nothing is charged for them — the run page has always said so and named the setting to raise. What it never said is the cheaper answer: press Start again. Reels this run already delivered and charged for are on your account's memory, so with New reels only switched on a second run skips every one of them and goes straight at the ones the cap left out — nothing is charged twice. From this build the run page says exactly that, with both numbers in it: how many reels are left, and how many of the ones already paid for a re-run will skip. Measured on a real run: 394 reels asked, 154 delivered and charged, 231 left at the cap and no route to them on the page. Nothing about pricing, the form, the charging or the columns you receive changes.
-
A listing this run stopped early so it would still have time to transcribe was reported as this run's own depth limit — a setting you had not reached. The run holds back part of your Max run time for transcription, so the reels it has already found actually get transcribed rather than the whole window going into looking for more. When that reserve ends a creator's list, nothing upstream refused us and the "Reels per handle" depth was never reached — yet the run page said "hit this run's own depth limit — raise Reels per handle" and the reels it never listed were counted against that depth. From this build they are counted against your run window, where they belong, and the page says what actually happened: the listing stopped to leave time to transcribe what was found within your Max run time, with both levers named — a longer run, or a smaller ask. A creator's list Instagram really does cut short is unchanged, and so is a run that genuinely ran out of time. Nothing was charged for those reels either way, and no price, input or delivered column changes.
- A run could keep working for minutes after the Max run time you set had already passed. Every time check in this actor decided whether there was room to start one more piece of work; nothing bounded how long that piece of work was then allowed to take. A reel picked up with a minute of your limit left could spend up to twenty-five seconds looking the reel up, three tries of forty-five seconds each downloading it and three minutes in the transcription service — all of it after your limit had gone by, with four reels doing it at once. Measured on this build's own test: a run with sixty-one seconds left finished seventy-four seconds past its limit, and it ended saying the reels ran out rather than that the clock did. From this build every network read is given the smaller of its own timeout and what your run actually has left, so the same run now finishes inside the limit, and a reel your clock cut is counted against Max run time (seconds) — the run page names that setting as the one to raise, exactly as it already did for reels that were never started. Runs with time to spare are untouched: every read gets its full allowance, every reel is downloaded and transcribed as before, and a genuine Instagram or download failure is still reported as one. Nothing is charged for a reel the clock cut, no price, input or delivered column changes, and the licensed data feed we fall back to is no longer paid for a page your run has no time left to use.
- A run that ran out of time could tell you Instagram had cut a creator's list short, when it was this run's own time limit. Reading a creator's reels stops paying for new connections a little before the run's clock is out, so the last refusal that comes back inside that window says only one thing: there was no time left to ask again. Until now it was written down as Instagram cutting the list — the run page said "cut short by Instagram — re-run for the rest", the uncharged row said the post feed had stayed walled, and a re-run met the identical time limit. From this build a run in that position says what actually happened: "stopped before the run timeout — N reels left, raise it", with the row naming Max run time (seconds) as the setting that moves it, and the reels it never listed are counted against that limit instead of against Instagram. A list Instagram really does cut short is unchanged — it still says so, still asks you to re-run, and is still carried on through the licensed data feed where that can answer. No price, no input and no delivered column changes, and nothing was charged for those reels either way.
- A run that named a watchlist could stop dead in the middle of a delivery, and a refused list update said nothing. A watchlist is a key-value store in your own Apify account, and this actor writes to it right after each reel is delivered and before that reel is charged. If the API token the run was started with could read that store but not write it — which is what a token restricted with "Restrict what Actors can access using the scope of this Actor" does without key-value store Write and Create — the refused write ended the run there and then, with reels already in your results and no explanation on the run page. The run now finishes normally: every reel is delivered and charged exactly once, and the refusal is reported the way a refused account-memory update already is — on the run page, in one uncharged note row carrying the whole explanation, and in the run log beside Apify's own message — so you know those reels are not on your list and would be charged again next run unless the token is given key-value store Write and Create permission (or Actor runs is set to Full access). Runs started from the console or with a full-access token are unchanged, as is every price, input and delivered column.
-
A run started with a scoped API token could be charged twice for the same reel, and nothing told you why — it now says so, and says exactly what to grant. The check that hands back a reel your account already has lives in a key-value store in your own Apify account. An API token limited with "Restrict what Actors can access using the scope of this Actor" cannot open that store unless it carries key-value store Read, Write and Create permission, so runs started from the API with such a token silently lost the check and charged again for reels an earlier run had already delivered — while the run page said only that the check was "unavailable this run". From this build the run names the cause and the fix in three places: on the run page, in one uncharged note row placed first in your results (so an agent reading rows never misses it), and in the run log beside Apify's own message. A watchlist the same token cannot open now says the same thing instead of asking you to re-run, which on that token would fail identically, and New reels only refuses with the permissions to grant rather than "re-run in a minute". Nothing changes for a run started from the console or with a full-access token, no price, input or delivered column changes, and every other reason the check can be unavailable keeps the wording it had.
-
The other half of that token: a run could read your memory of past reels and be refused every UPDATE to it — so the reels it delivered were not on the record and your next run paid for all of them again. A scoped API token can carry key-value store Read without Write, or Write without Create on a store your account does not have yet. Such a run opened your memory, handed back every reel you already had correctly, and then quietly failed to write down the new ones: nothing looked wrong anywhere, and the bill arrived on the following run. From this build the first refused write is named the moment it happens — on the run page, in one uncharged note row, and in the run log beside Apify's own message — and it says plainly that the reels delivered now will be charged again next run unless the token is given key-value store Write (and Create) permission, or Actor runs are set to Full access. Alongside it, the run page's one line was being cut off by the platform at 500 characters on the busiest runs, which could remove the very sentence about your money: the line now gives up the "open an issue" ask first, then the watchlist detail (which is in OUTPUT in full), and never a count, a cap or a charge statement. Nothing about pricing, the form, or the columns you receive changes.
- Write the singular of a field name —
reelUrl, videoUrl, url, handle, username, profile — and the run now reads it instead of coming back with an error row. The form's fields are lists, so they are named in the plural (reelUrls, videoUrls, handles); a call written by hand, or by an AI agent, very often sends the singular instead. Until now that input was not recognised at all: the run came back having transcribed nothing, and the uncharged row it left behind did not even name the field you had used. Anything you send under one of those names is now sorted exactly as if you had pasted it into "Instagram links or creators" — a reel or post link is transcribed, a creator has their latest reels transcribed, an Instagram media link is transcribed directly — and one uncharged note row names the field you wrote and the field this actor reads, so the next run needs no guess. Send the same reel in both the singular and the real field and it is still delivered and charged once. A value this actor cannot place still comes back as its own uncharged row, which now names your field too, and a run that read nothing from your input says so on the run page with both field names on it. Nothing about pricing, the form, or the columns you receive changes.
-
The hand-over announced two builds ago was never actually switched on for your runs — from this build it is. When Instagram stops serving a creator's reels part-way through, the run is meant to finish the list through a licensed data feed rather than hand you a short one. That was built and tested, but the run itself never turned it on, so every run since has kept getting the short list and the "please re-run" row that goes with it. It is on now, and it behaves exactly as 1.0.101 described: the walk is carried on to the end, same reels, same columns, same price, and nothing extra is charged for them. What buys nothing is unchanged — a creator who genuinely has no video posts, your own maximum already reached, a run started with the form untouched, and any run where Instagram answers normally. No price, no input and no delivered column changes.
-
A creator the backup feed refuses, or answers in a way this actor cannot read, is no longer reported to you as a passing outage. When Instagram walls a creator's post feed, the run finishes the listing on a licensed data feed. If that feed refused the request outright, or answered in a shape this build does not read yet, the uncharged row you got called the source "temporarily" unavailable and asked you to re-run — a run that would have come back with the identical answer. The row now names what actually happened and says plainly that another run cannot change it: a refusal is refused the same way every time, and an answer we cannot read is ours to fix rather than yours to retry. Nothing is charged for either row, exactly as before, and no price, no input and no delivered column changes.
- An answer from the licensed data feed that this actor cannot read is now reported as exactly that, instead of being filed as a passing outage. On both feed doors — the one that resolves a single reel and the one that lists a creator's reels when Instagram walls the feed — an answer that came back in a shape this build does not recognise used to be treated like a temporary outage, waited on and re-asked as if it might clear. It cannot: the same answer comes back every time. The run now says so in its log, naming only the field names of the shape it saw, counts it on the run's own upstream figures, and does not spend the wait on it. What you receive is unchanged: a reel the native page could not resolve keeps the row and the reason it already had, and a walled listing still hands over exactly as before. No price, no input and no delivered column changes.
- A run that stops before it starts now reports what you asked it for. There are four reasons a
run can refuse before it fetches anything: the listing's billing setup would have charged you for
rows that carry no result, a restarted run could not read back what it had already delivered, a
restarted run's processing window had already ended, or "New reels only" was switched on with no
list to compare against. In each case the run said what had happened and charged nothing, but its
own record showed the size of your request as zero — so the runs that served you least were the
ones hardest for us to find and fix. The record now carries the number of reels you asked for and
the one reason the run stopped. Your rows, your charges and the message on the run page are
unchanged.
- A small ask no longer spends twenty minutes looking for reels. Finding a creator's reels goes
through Instagram's own surfaces, and when one of them is refusing us the run keeps trying on new
connections. Until now the only thing that stopped it was the run's own clock, so a request for
three reels could spend most of an hour on it — one did, and returned three reels after twenty
minutes. The time a run spends finding reels is now sized to how many reels it was asked for, and
a run that has found nothing yet always gets one full attempt whatever the size of the ask. When
that limit is what ended the search, the row says so in those words — so you can tell "we stopped
because the ask was small" from "that is all the account has", and it names the two things that
move it: ask for more reels in one run, or re-run. Nothing is charged for a search that ends this
way, and a run started with the form untouched is unaffected.
- When the licensed data feed slows a run down, the run now waits it out for as long as your ask
is worth, instead of giving up after a few seconds. When Instagram refuses a creator's reel
feed, this actor finishes the list through a licensed data feed. That feed occasionally answers
"slow down", and until now the run waited it out for a fixed fourteen seconds and then stopped —
you got the reels already in hand, the rest was reported as a walk Instagram had cut short, and
the row asked you to re-run, on runs that still had minutes of their time limit left. The waiting
is now sized by how many reels you are still owed, the memory you picked and your own run clock,
each wait longer than the last, so a busy few minutes on that feed costs you a pause rather than
the rest of your reels. A small ask waits exactly as long as it did before, no run ever waits
less than it used to, and no run waits past your run-time limit, your reel limit or your cost cap
— each of those still ends the waiting on the spot. An answer that came back in a shape we cannot
read is still never bought twice. Nothing about money moved: no price, charged event, input field
or output column changed, only delivered transcripts are charged, and a listing cut short is
still uncharged.
- The limit on what a run spends reading frames that come back with nothing chargeable is now counted and checked per read, not per reel. A reel with a lot of on-screen text can take up to three reads of its frames, and each one asks for more room than the last — but that limit was both counted and checked once per reel, so a run could pass its own ceiling several times over without noticing. Both halves are fixed: every read is now counted at what it really costs, and each one is checked before it goes out. A reel whose deeper read the limit stopped now comes back with a row saying exactly that, instead of the plain no-speech line — re-run it with fewer reels ahead of it to get its text. Nothing about your bill changes: this limit has never charged you for anything, on-screen text is charged only where it is actually delivered, and a music-only reel with no readable text is never charged.
- A reel your account already paid for is now recognised even when you pass its page link instead of its file. If you had transcribed a reel by passing its direct video link, and later passed the same reel as an instagram.com/reel/… link, it was fetched and transcribed all over again and charged a second time — the run only worked out which file the page link pointed at after it had already decided to buy it. It now checks again at the moment it finds out, before anything is fetched, so the reel comes back from the run that delivered it, not charged. With "New reels only" it is left out and counted, as it always was for reels recognised earlier. A reel your account has not had is fetched and charged exactly as before.
- A reel is recognised by its audio link as well as its video link, so passing either one never costs you twice. When a reel arrives from another actor's dataset it usually carries two links — the video and the audio — and only the video one was remembered. If you later passed that reel's audio link instead, it was fetched, transcribed and charged again even though your account already had it. Both links now count as the same reel, whichever of the two you pass.
- When Instagram stops serving a creator's reels part-way through, the run now collects the rest
somewhere else instead of handing you a short list. Reading a creator's reels goes through
Instagram's own feed, and that feed can refuse a run's connection after it has served a page or
two — or refuse from the very first page — which left the reels it never listed uncollected and
the row saying the walk had been cut short. When that happens the run now continues through a
licensed data feed and keeps listing: same reels, same columns, same price, and nothing extra is
charged for them. You are told once per creator, on the run, which of the two happened. Nothing
is bought where Instagram answers normally, where a creator genuinely has no video posts, where
your own maximum was already reached, or on a run started with the form untouched.
- A creator whose reels could not be listed is never described as posting photos. Where the run
reads the rest of a creator's reels through the licensed feed and that feed shows nothing either,
the row now says the listing was cut short and can be re-run — instead of reporting, as a
finished answer, that the account has no video posts.
- Less waiting on a door that is already shut. While the licensed feed can answer a walled
creator, the run still tries Instagram's own connections to the measured limit that recovers them
— and then moves on, rather than spending minutes more opening fresh connections to a feed it has
a working alternative for. A run with no alternative available waits exactly as patiently as it
always has.
- A reel found for you whose video link has gone dead is now fetched again from the same second
source, instead of coming back as "expired, please re-scrape". Instagram's video links are
signed and go stale, and a reel that arrives from a creator listing or from another actor's
dataset can reach us after its link has died. This actor already goes back to the reel's own page
for a fresh copy in that case — but where that page would not serve it either, the second source
behind it was only ever offered to reels you pasted in yourself. It is now offered to any reel
the run can fetch again, so a row that used to come back uncharged and empty is delivered and
transcribed at the normal price. Reels whose link still works never go near it, and nothing about
what you pay changes.
- An aborted or migrated run now leaves its receipt from the first moment of the run, instead of
only after start-up finishes. The record that says how a run ended was only put in place once
the run had finished starting up — reading your input, opening its stores, working out what a
previous attempt had already delivered and charged. A run stopped inside that window ended with
nothing written about it at all, which mattered most on a re-started run, where the thing not
written about was the earlier attempt's work. It is now in place from the run's first moment, and
a run that reaches its work behaves exactly as it did before.
- Nothing else moved: no price, event, input field or output column changed, and only delivered
transcripts are charged.
- A link in your rows can never carry a network address, whatever form it arrives in. Every link
this actor delivers already went through our own URL hygiene before reaching your dataset, and that
pass had a gap: where an upstream body writes its links with HTML-escaped separators (
& in
place of &), the address parameter was not recognised by name and could survive into a row. It is
now removed however the link is written — escaped, plain or legacy separators, upper or lower case,
and inside a link that wraps another link. Nothing else in a link moves: the expiry, the signature
and every routing parameter are delivered exactly as they were served, so the links keep working
exactly as before. No column, no input, no price and no charge changes.
- A run that has reached your maximum cost per run no longer fetches a reel it will not deliver. When the cost cap binds, the run works out there is no room left for another reel before it goes and fetches that reel's video, instead of fetching it first and finding out afterwards. With four reels being worked on at once that could mean a handful of fetches for reels that were never going to be delivered. Nothing about what you receive or pay changes: the same reels are delivered, the same reels are charged, and the ones your cap cut are counted on the run exactly as before.
- An over-ask on a cap no longer refuses the run.
maxReelsPerHandle, maxItems and maxRunSeconds carried a maximum in the input schema, which the platform checks before a container starts — so a caller asking for 20,000 reels, or a 5-second run clock, got an error and no run at all rather than the 10,000 this actor can serve. The ceilings now live only in the code: the run starts, continues at the nearest end of the range, and ships one uncharged row saying what you asked for and what bound it. Nothing about the form, the defaults, the output or the price changed.
- A silent reel with a lot of writing on it now delivers that text instead of coming back empty. With Read on-screen text on silent reels switched on, a reel carrying a lot of on-screen copy — a long caption card, a recipe, a list, a dense international reel — could carry more text than our reader returned in one read, and the reel then shipped as an uncharged row with no text at all, as though nothing could be read on it. Such a reel now gets a second, larger read asking only for the visible text, and it delivers. Where a reel carries more copy even than that, the text ships cut short at about 3,500 characters with
truncated: true on onScreenText and a note on the row saying so, rather than being dropped. truncated is a new column inside onScreenText and is false on every ordinary reel. A reel whose frames are too big to send to the reader at all is now read once more at a smaller size, and only says so plainly — uncharged — if that is refused too.
- The second-chance lookup for a reel Instagram will not resolve now asks once, never three times. When that lookup answered with something this actor could not read, it was tried again twice over — and each of those tries used up part of the allowance the lookup runs on, so a handful of unreadable answers could close the lookup for everyone earlier in the month than it needed to. An answer that has already been paid for is now never asked for a second time; an answer that genuinely costs nothing is still retried exactly as before. Nothing you receive or pay changes: the same rows, the same verdicts, the same price, and a reel the lookup cannot serve still comes back on the same uncharged row saying so.
- A silent reel whose frames were too big to read now delivers its on-screen text instead of coming back empty. With Read on-screen text on silent reels switched on, the frames sampled from a tall, long or high-detail reel could add up to more than our text reader accepts in one request — and because that is a property of the reel itself rather than a passing glitch, re-running produced exactly the same empty row every time. Such a reel is now read once more at half the frame size, and delivers its text like any other. If the smaller read is refused as well, the row still says so plainly and is still not charged, exactly as before. The same limits on what counts as readable text apply to the second read, so a reel with nothing real on it is still never charged.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- The top of the input form now says what to send and what it costs. It reads as one short brief: the single call that works (
startUrls with a handle and a reel link mixed in one list), the empty-input 2-reel sample, what one charged unit is and what it costs on the Apify free plan — a creator's latest 10 reels is about $0.15, 500 reels about $7.50 — the list of what is never charged, the run option that caps what a run can spend, and where a YouTube link or any other audio or video file goes instead. Paid plans cost less per reel, and every tier is in this actor's own pricing table on the store page. Copy only: no price, event, input field or output column changed.
- Two field descriptions now lead with the thing you need first. "Instagram links or creators" says in its second sentence that plain links and the
{"url": "…"} shape are both read, and "Reel video/audio URLs" says in its second sentence that a direct audio or video file on any other host is transcribed by our media transcriber (apify.com/steadyfetch/media-transcriber), field urls. Both sentences were already written, further down. An AI agent calling this actor only ever sees the first 500 characters of a field description, so it could not see either of them.
- A run that delivered nothing now names the most likely reason on its own status line, with what to do about it — a post that is private, removed or mistyped, a photo post with no video in it, a music-only reel and the on-screen-text option that reads it, a sign-in page from Instagram that a re-run usually clears, a chained row with no video or audio URL in it. The per-row answers are unchanged and still carry the full detail: the status line simply stops making you open the rows to find out what happened. Those rows cost nothing before and cost nothing now.
- Nothing else moved: no price, event, input field, output column or charge changed, and only delivered transcripts are charged.
- Paste your links anywhere and the actor sorts them. There is a new input field, Instagram links or creators (
startUrls), and you can put anything Instagram in it: reel links, post links, profile links, bare handles, Instagram CDN media links — mixed in one list if you like. Each entry is read by its own shape and sent to the right place, so a reel link is transcribed, a creator has their latest reels listed and transcribed, and a media link is transcribed directly. Entries can be plain links or the {"url": "…"} shape other actors use; both are read. The fields you already use — Instagram creators, Instagram reel links, Reel video/audio URLs, Dataset ID, Dataset items — are untouched and all still work exactly as before, and the same reel supplied through two of them is still delivered and charged once.
- A list sent under another actor's field name is read instead of refused.
urls — the name our media transcriber uses — now goes through the same sorting, so a profile link sent that way reaches the creator surface rather than coming back as guidance. One uncharged note row still says which field the form actually carries.
- An entry the actor cannot place still comes back as an uncharged row saying what it looked like, and it costs that entry only — every other link in the same list is served.
- There is no language setting, and there never was one. The spoken language is detected automatically and reported in the
language column on every row; a language field sent from another actor's form is accepted and ignored rather than stopping the run.
- Nothing else moved: no price, event, output column or charge changed, and only delivered transcripts are charged.
- A maintenance build: nothing about your runs changes. The credential this actor uses for its licensed data feed was rotated, and a new build is the only way the platform takes the new one. Same price, same charged event, same input fields, same output columns, and only delivered transcripts are charged. There is no reason to re-run anything.
- A reel link Instagram will not resolve for us is now retried through a licensed data feed, at the same price. Paste a reel or post link and this actor fetches the reel's video straight from Instagram's own public page. On a large share of those links Instagram answers with a sign-in screen, a page it will not explain, or nothing at all — and the row came back uncharged saying "temporary, please re-run", which is honest and still leaves you without the transcript. From this build, a link that ends that way is looked up once more through a licensed data feed, and if the feed can serve the reel it is downloaded, transcribed and delivered exactly like any other reel: one row, one charge, the same price, no extra fee and no new option to switch on. A reel the feed cannot serve either comes back with the same uncharged row it does today, saying the same thing — you are never worse off than before, and nothing extra is ever charged. Reels the actor can already resolve by itself are untouched and are never looked up anywhere else.
- A link that really is gone is still answered from Instagram itself, with no second lookup. A post that is private, removed, or whose short code is wrong is a verdict this actor confirms with two readings of Instagram's own page, and it stays that way — nothing is looked up elsewhere for it. The same goes for a photo post or an all-photo carousel (there is no video on it to transcribe) and for a lookup your run's own time limit skipped. All three still cost nothing.
- A rescued reel arrives with more filled in. Where the lookup carries them, the creator, the caption, the post's date and its play, like and comment counts now land in the columns they have always had on this actor and which a pasted link used to leave empty. No column was added, renamed or removed, and no column changed meaning.
- Nothing else moved: no price, event, input field, output column or charge changed, and only delivered transcripts are charged.
- A maintenance build: nothing about your runs changes. The store listing now leads with what buyers actually type — the actor is called Instagram Reels Transcript Scraper — Reels to Text, No Login — and the top of the page carries the one-click MCP pin, this actor's id, the input field to fill with a real example, and the field that caps what a run can spend. An AI agent reads only the first part of a listing, and until this build every one of those sat below the cut. The actor itself, its input, its output and its wording on price are untouched.
- The private run-report this actor writes for our own support — counts only, never anything you typed — now also records whether a run that stopped at the row limit you set had actually filled it, and the per-event prices the run was billed at. Both were blank before, so a run stopped by your own limit looked the same to us as one that simply ran out of reels.
- Nothing else moved: no price, event, input field, output column or charge changed, and only delivered transcripts are charged.
- Paste a video file that is not Instagram's and you are now told which of our actors does read it. This actor transcribes Instagram reels and posts off Instagram's own CDN, so a link to a media file you host somewhere else — your own storage, your own CDN, a file an agent already downloaded — comes back as an uncharged row, in either link field. It always did. What it did not do was say where that file CAN be transcribed, so the answer was a dead end: correct, and useless. From this build that row names our media transcriber, which reads an audio or video file from any host, and the exact field to paste the link into. Instagram links are unchanged — a reel or post link is still resolved, a share link still gets its own answer, a profile link still gets its own, and a non-media Instagram CDN link still gets the CDN guidance it needs. Nothing was charged for these rows before and nothing is now.
- Nothing else moved: no price, event, input field, output column or charge changed, and only delivered transcripts are charged.
- Two Instagram links this actor used to refuse now work. A profile link on
instagr.am — Instagram's own short domain — was answered "this actor takes Instagram profiles" and collected nothing, and so was a handle pasted out of a spreadsheet or a JSON file with the quotation marks still around it ("nasa"). Both are accepted from this build, under exactly the same rules as before: a reel link is still a reel link, a "Copy link" share URL is still a share URL, and an app page is still an app page.
- Nothing else moved: no price, event, input field, output column or charge changed, and only delivered transcripts are charged.
- A made-up closing line after the end of the audio no longer hides a real transcript — and is never delivered. Speech recognition sometimes invents a sign-off, most often "Thank you.", and stamps it with a time that falls past the end of the reel. When that stamp landed far enough out, the whole transcript was judged unreliable and the reel came back marked as having no speech: nothing delivered and nothing charged, even when there were 25 seconds of clear speech on it. It was found on a real customer run of our Facebook ads transcriber — a 30-second property ad with 25 seconds of clear voiceover that came back with nothing at all — and the same speech step runs here. From this build the invented line is removed before anything else is decided, so the real speech is delivered and charged exactly as usual — and the invented line is taken out of the transcript, the timed cues and the opening-line field too, so you are never handed, or billed for, a sentence the audio does not contain. The same invention was also slipping through quietly at the end of transcripts that DID deliver; it is gone from those as well. The length we measure for billing is unchanged.
- A reel that came back empty because of that fault is tried again, instead of being handed back with the same empty answer. Once a reel has been delivered to your account we never charge you for it twice, and to do that we remember what every reel answered. The trouble was that the memory also remembered the EMPTY answer above — so re-running the same handle handed the same nothing straight back from your own record, without fetching or listening to the reel at all. It was found on a real customer run of our Facebook ads transcriber, five runs in a row against the same ad, and the same memory works here. From this build, a reel whose remembered answer was an empty one — no speech found, no audio track, no on-screen text found — is tried again the first time you run it on a newer build, and charged once if it then delivers something. It could never have been charged before, because an empty answer is never billed. A reel ALREADY DELIVERED to you is untouched: it still comes back uncharged and is never charged a second time. Two remedies our own rows offer you now actually get tried instead of being answered from memory: switching on the on-screen-text option, and passing the
audioUrl field for a reel whose video stream carried no audio.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A reel reported private or removed is now confirmed with a second look before we say so. "The post is private, removed, or the link/shortcode is wrong" is the harshest thing this actor says about a link you paste, and it was decided from a single reading of Instagram's page. That same page sometimes answers with a sign-in screen or a stripped stub instead of the post, so one reading is not enough to close the question. The lookup now takes one more read a couple of seconds later, and writes that verdict only when both readings agree; if the second read serves the reel, you get the transcript instead. A reel that really is gone is answered a couple of seconds later than before, still with no result fee, and the extra read costs you nothing.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A maintenance build: nothing about your runs changes. The private run-report this actor writes for our own support — counts only, never anything you typed — gained room for four figures it does not fill in yet: how many targets a run was given, how long it waited on a blocked source, how many of those waits recovered, and a reason code for an item our own size limit refused. The build carries the shared contract so a later one can report them; on this actor every one of them is left blank, and nothing a run does or costs is different.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- Two runs of the same watchlist started at the same time no longer erase each other's sightings. Watchlists and the account memory are now merged on every write, so an item one run delivered stays remembered, and a later re-run hands it back instead of charging it again.
- A walled-profile row that has stopped promising a re-run now says so, in a field as well as in its sentence, and prices the remedy: a profile still unreadable after that long would cost the same minutes again, so the row says whether re-running is still the fix instead of leaving the invitation implicit.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A chained row that IS a reel but carries no video link is now transcribed, instead of being turned away. Some Instagram scrapers hand you a row that says plainly it is a video —
"type": "video", "productType": "clips", the post's own short code — and simply do not include a media link, because the surface they read it from does not publish one. Chaining that run in here got you nothing: every one of those rows came back "no reel video/audio URL found in this row", uncharged and unhelpful, even though this actor has always been able to fetch a reel's media from the reel's own page given nothing but its short code. It now does exactly that for those rows, so a chained dataset that was returning empty for you should start returning transcripts. Rows that genuinely never held a reel — a photo post, a carousel of photos, a comment — are unchanged: they are still answered instantly, locally, and with no result fee, and no lookup is ever spent on them. The rescue also runs inside every limit you already set: it counts against "Max reels to process", it stops when your maximum cost is reached, and it stops when the run is near its time limit.
- The field name
urls now works here. If you came from another transcript actor in this family, the list of things to read is called urls there and reelUrls / videoUrls here — and pasting your input across returned nothing at all. This actor now reads urls too: reel and post links go to "Instagram reel links", Instagram CDN media links go to "Reel video/audio URLs", and anything it cannot place is answered on its own row exactly as before. One extra row, charged nothing, names the fields this form actually uses so your next run needs no guessing. The input fields themselves are unchanged — nothing was renamed, and every saved task keeps working.
- One creator no longer reads as three on the run page. When the creator a run was reading could not be listed at all, the run-page summary counted the same creator more than once — it reported the number of reels it had been asked for as if that were a number of creators ("2 creators temporarily unavailable" when there was one), and then named that same creator a second time as having hit a depth limit. Nothing was ever miscounted in what you were charged or in the rows themselves — this was the summary sentence only — but it made a one-creator run look like a three-creator failure. The line now counts reels as reels, and names a creator once.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A photo post now says it is a photo post, instead of "private, removed, or the link is wrong". If you pasted an
instagram.com/p/… link to an ordinary photo, this actor told you the post was private, removed, or that your link was wrong. It was none of those things — the post was public and perfectly fine, it just has no video on it. The row now says exactly that, under its own no_video_in_post status, and still costs nothing.
- A carousel of photos no longer claims Instagram restricts it. The same paste, but of a carousel post whose items are all photos, came back saying Instagram would not expose the reel's video because of "a licensing/embed restriction on the reel itself". There was no restriction. That sentence was a guess, made because nothing else had matched — and it was told with complete confidence to people paying for the answer. An all-photo carousel now comes back as
no_video_in_post too, saying there is no video on it. A carousel that DOES contain a video is transcribed as it always was: its first video item, one row, one charge.
resolve_blocked now means only what Instagram itself says. That status is now raised on Instagram's own copyright-blocked flag for the post, and on nothing else. Its wording says so.
- A page we cannot explain now says we cannot explain it. When Instagram serves the post's page and it carries no video and none of the reasons above, the row says exactly that and asks you to re-run, under the new
resolve_unexplained status. Nothing is charged. Previously that case was swept into the "restricted reel" verdict above and closed for good, so a change at Instagram's end would have looked like a permanent fact about your reel.
- The
/p/ links the input field promises now behave as promised, and the field says what happens to each shape.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A running job now tells you it is alive. Until now this actor went quiet between its first few setup lines and its first finished reel. Finding a creator's reels can take several minutes on its own, and longer when Instagram is refusing connections and the run is patiently retrying on fresh ones — and none of that reached you. Nothing was wrong during that silence and reels were still being collected, but there was no way for you to tell, and a run you cannot distinguish from a stuck one is a run you end up cancelling. From this build the log carries a line at least every thirty seconds while the run is working: how long it has been going, what it is doing right now ("finding the reels to transcribe", "transcribing the reels"), and how many reels have been delivered so far. The same line now also appears on the run page beside the run itself, so you can see the run is progressing without opening the log at all. The opening line states that cadence up front, so a gap longer than thirty seconds is something you can act on rather than guess about.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A reel you re-run keeps the answer it actually got. When a reel comes back to you from the account memory — one this account already asked about — the row used to say "Already delivered to your account", whatever the first run had found. On a reel that was never transcribed at all (no speech, no audio track, nothing readable on screen) that was simply wrong, and it also wiped out the sentence that told you what to do about it: a video-only link, for instance, used to say "if your scraper exports an audioUrl field, pass it — the audio lives there", and on the second run that sentence disappeared. Those rows now keep their own reason word for word and add one honest line saying it is the same answer as before and nothing was charged again. A reel that really was transcribed still says it was already delivered. Re-running now shows you at least as much as running once.
- A reel whose frames could not be read now says so. With "Read on-screen text" switched on, a reel whose video we could not open for frames came back as an ordinary silent row — the same row you would have got with the toggle off, so there was no way to tell that the pass you asked for never actually ran. The row now says the on-screen text was not checked and that re-running may succeed, and the run's own record counts it separately. Nothing was charged for those rows before and nothing is now.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A reel page Instagram answered with a sign-in screen now says exactly that. Two different things were being reported with one word. Sometimes Instagram does not answer a reel lookup at all — a dropped connection, a server error, nothing on the wire. Sometimes it answers perfectly well and serves a sign-in page where the reel should have been, which is about the connection the run went out on and not about the reel. Both came back as
resolve_unavailable, so neither we nor you could tell which had happened. The second one now comes back as resolve_signin_wall, in its own words. Nothing else about those rows moved: both are still temporary, still say nothing about the reel itself, still ask you to re-run, and still cost nothing.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A reel lookup your run had no time left for now says so as a time limit, not as an Instagram problem. When a run came close to its own time limit, the remaining reel lookups were skipped — correctly, and uncharged — but the row read as if Instagram had refused to serve the page. It now says plainly that the run was near its time limit, and the run-page message counts it with the other reels the timeout left, so the number you need to raise is the one named next to it. The wording of the row and the fact that nothing is charged are unchanged.
- Everything else is bookkeeping you cannot see. Five kinds of uncharged outcome — a reel Instagram will not expose to embeds, a private or removed post, a video-only stream with no audio track, a music-only reel, and a silent reel with nothing readable on screen — used to be summed into one number in this actor's own run record, together with links that had expired. They are now counted separately, so a run where every reel was music-only is no longer filed the same way as a run where every link had gone stale. Every row, its status, its wording, its
charged flag, the closing _summary receipt and the totals on the run page are exactly what 1.0.82 shipped.
- Nothing else moved: no price, event, input field or output column changed, and only delivered transcripts are charged.
- A music-only or silent reel is no longer charged as a transcript. When a reel carried no speech, the transcriber sometimes invented a short caption for it — "Outro Music", "Música", "The End" — and that invented caption was delivered and billed as if it were the reel's own words. Short reels were where it happened: below fifteen seconds the only thing standing between an invented caption and your bill was a list of exact phrases, and anything not on the list went straight through. A reel whose transcript is nothing but a sound or a card is now recognised as such at any length and ships as an uncharged no-speech row — no result fee, exactly as the store page says.
- A short reel that really does speak is still delivered. Speech is now weighed against the part of the reel the words actually cover rather than the whole of its length, so a six-second reel carrying a three-word line reads as speech and not as silence. Short spoken reels that used to come back as "no speech" are delivered.
- Nothing else moved: no price, event, input field or output column changed.
- A chained row that never held a reel is now recorded as exactly that, and not as a reel we failed to fetch. When you chain a scraper run, some of its rows are photo or carousel posts, and some come from a scraper that exports no video or audio address at all. Those rows have always come back to you uncharged, in one row each, saying which field was missing — and that has not changed. What changed is how the run itself is filed: they used to be counted together with reels that were fetched and could not be delivered, so a run over a mixed dataset was summed up as hundreds of failures when nothing had failed. The same split now separates a reel page Instagram would not serve on the day, a creator it answered about definitively, and a run where our own on-screen-text reader was unavailable — three different facts that were being counted as one.
- Nothing you can see moved. Every row, its status, its wording and its
charged flag, the closing _summary row and the run-page message are exactly what 1.0.80 shipped. No price, event or output column changed, and only delivered transcripts are charged.
- The profile and reel lookups no longer report a host they cannot reach as a host that does not exist. Some servers publish only one kind of internet address, and it is a kind our machines cannot dial straight out. The page lookups used to demand the other kind and get "no such address" back, which is a claim about the host rather than about our own connection — and it cost the run one attempt of its own retry ladder on a false answer. The whole run now prefers the address it can dial rather than demanding it, which is what the video download already did. Nothing was ever charged for either row.
- Nothing else moved: no price, event, output column or charge changed, and only delivered transcripts are charged.
- A block of links pasted into one row is now read as the list you meant, whatever separates them. "Instagram creators", "Instagram reel links" and "Reel video/audio URLs" each take one entry per row. A whole block pasted into a single row was read as one very long address: fifty CDN links became one item, and because Instagram signs its media addresses that item came back as a single row saying the link could not be read — for a list that was perfectly good. A pasted block is now split back into its individual links whether they are separated by spaces, line breaks, tabs, commas, semicolons, pipes or nothing at all, so a column copied straight out of a spreadsheet works. Each one is then read, deduplicated and charged on its own, exactly as if you had pasted them one per row.
- A link that carries another link inside it is still one link. An address holding a second address in its query or its path is left whole, not broken in two, and a single link pasted on its own is never rewritten.
- Text pasted around a link no longer breaks it. A number, a bullet or a note sitting beside a link is ignored and the link itself is used. A row holding no link at all is still answered as one row, not one row per word.
- Nothing else moved: no price, event, output column or charge changed, and only delivered results are charged.
- A reel that was already transcribed when your run reached its maximum cost now comes back to you, uncharged. Your cost limit is checked at the last possible moment, immediately before a row is written and billed — and by then this actor has already fetched the reel and had it transcribed. Until now that row was replaced by a "stopped at your maximum cost" row and the transcript itself was thrown away, so the limit cost you the result as well as stopping the run. The transcript — or, for a silent reel, the on-screen text read from it — now ships in full, the row says the run reached its maximum cost and that nothing was charged for it, and your limit is still never exceeded. Reels after it are stopped before anything is fetched, exactly as before.
- Nothing else about charging changed. Your maximum cost per run is never exceeded, only delivered transcripts are charged, a reel that could not be delivered is not charged, and a run started with nothing set behaves exactly as before.
- A reel whose media server this run cannot reach is now retried in a way that can actually work. Instagram hands out media links that point at whichever of its servers is nearest to whoever asked, and some of those servers simply cannot be reached from where a run of this actor goes out. Until now every retry dialled that same unreachable server, so three attempts were really one attempt: the reel waited about three quarters of a minute per try, delivered nothing, and asked you to re-run — which would have failed exactly the same way. The run now asks Instagram's main media server for the same file, and, if that is refused too, fetches it over a different connection. Both are tried before the reel is given up on, and a reel that downloads first time behaves exactly as it always did.
- A reel that really cannot be fetched now says so in one plain sentence. These rows used to carry a raw network error and an internal address, which read as a fault in your input. They now say Instagram's media servers could not be reached from this run, that nothing was charged, and to re-run.
- Nothing about charging changed. Only delivered transcripts are charged, a reel that could not be delivered is not charged, and a run started with nothing set behaves exactly as before.
- A blocked post feed no longer uses up the time the profile-page reels need. When Instagram will not serve its profile route, this actor reads the creator from their public profile page, and the reels shown on that page are the one surface left when the deeper feed is blocked too. Since the walk became patient about a blocked feed it could spend the whole listing part of your run taking fresh connections, and those reels were then never collected at all — the run ended asking you to re-run with the reels sitting in hand. The walk now stops in time for them, so a creator whose feed stays blocked comes back with the reels their profile page shows instead of nothing.
- A feed that answers costs nothing extra. The profile page's reels are still collected only when the deeper feed did not give the run what you asked for, so a run whose feed serves does exactly what it did before, with no extra requests and no change to your rows.
- Nothing about charging changed. Only delivered transcripts are charged, a reel that could not be delivered is not charged, and a run started with nothing set behaves exactly as before.
- A creator whose POST FEED is blocked is now retried on fresh connections, for as long as your run's time limit allows. Instagram blocks its post feed per connection, and a fresh one usually serves the very same creator seconds later. Until now this actor had exactly one connection for that route: when it was refused, the walk stopped there and the row said "this run stopped before it finished reading" with the whole of your run's time still unspent — even though the reels were readable on the next connection. The walk now continues from the exact same position on fresh connections while the run still has room for one more and for writing your rows at the end, and while the reels you asked for can still pay for it. A feed that answers straight away is exactly as fast as it always was, and a connection that was refused is never charged.
- A run that already listed reels from the profile page keeps going for the rest. Asking for more reels than the profile page shows sends the run onto the deeper feed route; one refusal there used to end the list where it was. It now spends its connections on the rest of what you asked for.
- A blocked walk now says WHICH part was blocked. The creator's profile was read; it was the post feed that Instagram would not serve. The row says so, with how many connections were tried and over how many minutes, so a blocked feed is never read as a verdict about the creator. A blocked walk is still never reported as "this account posts photos".
- The retry ladder always keeps back enough time to write your rows and the summary. A retry could previously start with twenty seconds left — a whole request inside the half-minute the run holds back for reporting — and the feed's own retries did not look at your run's time limit at all. Every retry, and every cooldown before one, now leaves that half-minute plus a full request behind it.
- Nothing about charging changed. Only delivered transcripts are charged, a reel that could not be delivered is not charged, and a run started with nothing set behaves exactly as before.
- Every reel this run could not deliver is now named. The run's own record of what was asked for and what came back is kept in REELS, the same unit as your rows: a creator whose listing Instagram cut part-way reports the exact reels it never listed, a creator it would not open at all reports that creator's whole share of your ask, and a creator that answered definitively — no video posts, private, gone — reports one. Until now those shortfalls were recorded per CREATOR against a reel-count ask, so the two numbers could not be read together at all.
- A creator with fewer reels than your per-creator limit now asks for what it has. Ask for 10 reels each from a creator who has posted 3, and the run records an ask of 3 answered by 3 — not 10 with 7 missing. Your limit is still a ceiling and the dataset is unchanged.
- The reels your own caps trimmed are counted, not silently dropped. When the whole-run limit or the maximum cost per run cannot pay to list a creator at all, those reels are recorded against the setting that stopped them, and the run says which one it was.
- A run Apify moves to another server now says so as its stopping reason — and no longer asks you to open an issue about it. The hand-over already appeared on the run page; it is now the reason the run records, so a run that continues elsewhere is never recorded as one that ran out of work. Nothing is delivered or charged twice across that seam.
- An expired link is counted once. A reel whose signed link had already expired was recorded both as an uncharged miss and as an expired one; the run's record now counts it a single time. It was always uncharged, and still is.
- Nothing about charging changed. Only delivered transcripts are charged, a reel that could not be delivered is not charged, and your limits still stop the run exactly where they always did.
- A run that waits now always keeps room to finish and report. When Instagram walls every connection to a creator, the run can pause and walk the ladder again on fresh connections — but the check that decided whether a pause was affordable kept back only half a minute for what came after it, while one fresh connection lane is three requests and their cooldowns, up to two minutes. On a run whose time limit fell in the band just under eight minutes, the pause was allowed and the walk after it then ran into the time the run keeps back for writing your rows and the summary. The check now keeps back a whole fresh lane, measured from this ladder's own request timeout and cooldowns, so a pause is only taken when the run can actually use it. The run limit you start with is unchanged.
- Charges are unchanged. Waiting is uncharged, a walled creator is uncharged, and only delivered reels are charged.
- A run started with no input at all now has room to wait out a block. Press Start on the untouched form and this actor transcribes two reels from one real creator, charged like any run. Instagram sometimes turns every connection away for a few minutes at a time, and one round of attempts across both connection pools and both surfaces was measured at just under three minutes — the whole of the sample's own three-minute limit, with six seconds left. So the pause-and-try-again this actor gained two builds ago could never happen on the most common first run of all: it reported "blocked, please re-run" while the block was still lifting. The sample's time limit is now nine minutes, sized to hold one full round of attempts, one pause, one more round, and enough time left over to stop cleanly and report. A sample Instagram answers still finishes in seconds; only a blocked one uses the extra time, and nothing is charged unless a transcript is delivered.
- How much of its remaining time one blocked creator may spend waiting now follows the size of what you asked for. A run with more creators still to read keeps exactly the limit it had — no single creator may spend more than half the time left, so a wide block still leaves the later creators their share of the run. A run with a single creator may spend what is left on its one pause, because nothing else is waiting for that time.
- The no-input sample now always reads Instagram for real. It used to be answered from this account's own history of past runs, so a second Start handed the first one's reels back uncharged, without a download or a transcription. The sample now ignores that history in both directions: it fetches and transcribes every time, and it does not add its own reels to the history. Two things are unchanged — a run with your own creators or reels in it still hands back what this account already has, uncharged, and so does a no-input run where you asked for the history by name ("New reels only" or a watchlist name).
- A reel link from the app's "Copy link" button now points you to the address that works. That button sometimes hands back a share link with no reel code in it — the run already answered such a link with an uncharged guidance row, but the "Instagram reel links" hint and the example now tell you to open that link once and paste the plain reel address it lands on, so a handful of share links no longer come back as guidance rows and nothing else. Nothing about what is delivered or charged changed.
- A creator Instagram blocks on every connection is now given more of your run's time before it gives up. When Instagram refuses a creator on every connection — both its data service and its public profile page — the run used to try for about three minutes and then return "please re-run", advice that would only repeat the same three minutes. It now waits a short spell and tries again on fresh connections, for as long as the run's time and your ask allow. These blocks usually clear within a few minutes, so a creator whose reels were listable all along is delivered instead of coming back empty. Uncharged either way.
- A creator that stays blocked no longer reads as a quick "please re-run". After several minutes of fresh connections that were all refused — on both surfaces — the row says the creator could not be read and may be one Instagram shows only to logged-in visitors, rather than pointing you back into the same block. A creator that was only briefly unavailable still says a re-run may clear it, and now says how many connections it tried and over how long.
- A temporarily-blocked creator is counted apart from a private or empty one, so a passing block and a permanent verdict read differently on the run and in the run's record. A private, deleted or empty creator still gets its definitive answer at once, and a short run still returns its honest row inside the time limit you set. Nothing about what is charged changed.
- A creator that Instagram walls on every connection is now retried on fresh connections before the run gives up. When Instagram refuses both the profile data route and the profile page, that page can be walled for one connection while a fresh one serves it seconds later. The run used to try the page exactly once, so a single walled attempt returned nothing while most of your run time sat unused. It now retries the same page on fresh connections, up to a small bound and only while the run still has time and budget, so a creator whose reels were listable all along is delivered instead of coming back empty. Uncharged either way.
- The retry ladder stops at your run's time limit. On a short run the connection retries used to run past the limit you set; every retry now checks the time left and stops cleanly inside it.
- A creator that still could not be read says how hard the run tried. A temporarily-unavailable row now names how many connections were tried before it gave up, so "please re-run" is never a verdict after a single attempt.
- A creator with no posts at all is no longer told they post photos. A public profile that has never posted got the one sentence this actor reserves for photo accounts, wording it as "no video posts were found in the 0 most recent posts we read" and pointing you at the photo scraper. It now gets the plain, definitive answer: a real public profile with nothing on it. Uncharged, as before.
- A list this run's own depth cut short is no longer a verdict about the creator either. On a photo-heavy account the walk stops at the depth your ask pays for. That stop used to be reported as "the account posts photos", which is permanent-sounding and was not something the run had established. The row now says the run stopped at its own depth, that this is a limit on the run and not a verdict about the account, and names Reels per handle as the setting that reads further.
- The run only tells you to re-run when a re-run can help. A list Instagram cut short still says so and still asks for a re-run, because a fresh run often clears it. A list one of our own limits ended now names the setting to raise instead, rather than sending you into a re-run that would stop in exactly the same place.
- Change only an option, name nothing, and the run now goes ahead. Turning on-screen-text reading on, setting a cap or a run-time limit, "New reels only" or a watchlist name and pressing Start without naming a creator, reel link or chained run used to turn the run away with a single uncharged guidance row — so the buyer who flipped one toggle got less than the buyer who touched nothing. Those settings are now applied to the default 2-reel sample and the run delivers, charged like any run. A cap smaller than the sample is honoured exactly; a bigger one never grows it.
- One uncharged
sample_note row says which settings were yours, what the sample supplied for the rest, and how to run your own reels. It is never counted as a miss, and the run status line says the sample ran under your settings.
- Guidance is unchanged where it is the honest answer: a field name this actor does not recognise, or a list you sent empty (
handles: [], reelUrls: [], datasetId: "") still gets its uncharged row naming the fix — a mistake is never answered with sample reels.
- Pressing Start with nothing set at all is unchanged: the same 2-reel sample of one public creator.
- Every input problem now names the field it was about in the run's own record — the creators list, a reel link, a media URL, pasted rows, a watchlist name — instead of one undifferentiated "input error". The field NAME only; nothing you typed is stored. One unusable entry still costs that entry and nothing else: every other creator, link and row you sent runs exactly as before.
- The run's record now reports what you ASKED for alongside what was delivered, so a run that turned everything away can be seen as one. It previously reported the number of reels the run got as far as attempting, which is 0 on exactly the runs worth looking at.
- The Changelog tab no longer describes any row as "free" — the word is "uncharged"; running any actor still uses platform time you pay for. No prices, counts or behaviour changed.
- A reel already delivered to your account is never charged a second time. Re-running the same creators, reel links, chained rows or media URLs used to download, transcribe and charge for every reel again. The run now recognises a reel your account already has — under its short code or its media file, however it arrived last time — and hands it back from the run that delivered it:
repeat: true, firstSeenAt, firstSeenRunId, charged: false, not downloaded or transcribed again. The status line counts them and OUTPUT.repeats holds the number. Your account keeps this memory in the key-value store ig-reels-watch-account; delete it to forget everything.
- New reels only works without a watchlist name. It compares against your account's memory; a named watchlist still keeps a separate list per creator set. Only when neither can be read does the run stop, uncharged, instead of charging you for reels you may already have.
- If the memory cannot be read, the run still runs. It delivers and charges as usual and says on the status line and the charged rows that the repeat check was unavailable.
- Every row now carries
isNew and firstSeenAt, not only rows of a watchlist run.
- A watchlist written before this build kept no copies of its rows: the reels on it are transcribed again once, not charged, and kept from then on.
- A reel you already have comes back even when the speech service is down or your cost cap is spent — it was paid for once already, so nothing stands between you and the row.
- The status line can no longer be cut. The run page truncates it at 500 characters; on a heavy run the watchlist totals and the link-freshness note now step aside with a pointer to the run's OUTPUT record, which carries them in full, so the counts, the named caps and the support line always survive. Two clauses that carried the line's own separator were reworded.
- A few row and page outcomes this listing called "free" are named "uncharged" or "at no extra charge", which is what they are.
- Rows pasted into the "Dataset ID" field are read as your rows. A paying buyer pasted a dataset's exported rows into that field; the run sent them to the platform as if they were an ID and stopped on the answer. The run now recognises pasted rows there, works them exactly like rows pasted into "Dataset items", and adds one uncharged note saying where they belong next time. Anything else that is not a dataset ID or dataset name — a link, a value with spaces, a very long value — is answered with one uncharged row naming what it looked like, before anything is sent anywhere. Nothing was charged for the runs that stopped, and nothing is charged for these notes.
- A Dataset ID the platform itself cannot answer for is settled in seconds, not minutes. When the platform's own dataset lookup fails on its side, the run used to wait through the platform client's long retry schedule — close to seven minutes on one lookup — and could then run out of its own time. The lookup now gets two quick tries plus one short pause, and the run moves on to its honest uncharged row. Nothing about what is charged changed.
- A guidance row is never dropped by the run's time limit. A row that only explains an input problem costs nothing and takes no time, so it now ships even when the run has reached its safety margin; only real work is skipped there.
- A chained Dataset ID the run cannot read now ends as one uncharged row, whatever the reason. Until now a refusal the run did not recognise — anything other than "no such dataset" or "no access" — stopped the run within seconds with nothing delivered. Every answer now becomes an honest
input_error row naming what the platform said, a momentary refusal gets one more try, a read that stops part-way keeps the rows already read and says where it stopped, and the run carries on with the rest of the input. A value that is not a dataset ID at all says so instead of reading as a temporary problem. Rows chained in an unexpected shape were already harmless and now have a test that keeps them so. Nothing was charged in any of these cases before, and nothing is now.
- A problem inside the speech-to-text service is no longer reported as a problem with the reel's audio. Every refusal from that service used to read the same way — a permanent, uncharged miss saying the reel held nothing we could transcribe — so "the service changed something on its side" and "this reel has no usable audio in it" looked identical in your dataset. A fault on the service's side now ships as an uncharged row marked
retryable that asks for a re-run, and a reel we genuinely cannot transcribe keeps the honest, uncharged miss it always had. Nothing about what is charged changed.
- A run that stops on a fault of ours now tells us what kind of fault it was, so it is looked at without anyone needing to share the run. Nothing about what is delivered or charged changed.
- Small asks reach the profile-page read when Instagram's profile service errors or walls — a run that has delivered nothing yet may now buy the one read that answers (the profile page) even when the ask is a handful of reels, so a single-handle run or the default sample no longer comes back empty while Instagram's own profile service answers an error. A profile that still cannot be read stays uncharged and says why.
- A walled connection no longer eats the whole run — the retry ladder stops at the run's own time limit instead of sleeping past it, so the fresh connections and the profile-page read still get their turn inside a short run.
- The default sample's three minutes now start when the run actually boots, not when it was queued, and the time kept back for transcripts never exceeds half the run's own window — a sample queued for a minute used to open with most of its window already gone and stop its own creator read at once.
- A run that stops before it starts now reports its outcome too — a run refused for its memory setting, and a run stopped because this build was missing a credential of ours, now reach us the same way every other run does: counts and reason codes only, never your input or your rows.
- Every run now reports its own outcome to us — counts and reason codes only, never your input or your rows — so a run that goes wrong reaches us even when nobody shares it.
- Vendor calls on media that yields nothing chargeable are bounded per run — a small allowance that every charged delivery widens, so a paid run is never cut short; past it, items ship as uncharged
vendor_budget rows.
- A chained Dataset ID is looked up read-only. A mistyped ID creates nothing and returns one uncharged input-error row that names the ID as the problem; a real dataset is read page by page with an honest notice past 10,000 rows.
- The watchlist clause of the status line no longer splits itself with a semicolon.
- Row notes state what happened and what was charged; the support ask lives on the run page.
- Console field descriptions no longer call a row "free" — running any actor still uses platform time.
- The end-of-run summary now fits on the run page. It was long enough to be cut off part-way through; the wording is tighter and every count, cap and charge statement survives.
- A run that ends with a problem now says where to reach us. A miss, an input error, an early stop or a failed run closes by pointing at the Issues tab and naming the reply time; a run that delivered everything, including one that filled the row cap you set, is left alone.
- One support promise across this page — issues are answered in a couple of hours, always within a day.
A run that resumes after a platform restart now recognises every row it already delivered, so nothing is delivered or charged twice.
Apify occasionally moves a running actor to another server. When that happens, the run re-reads its own dataset to remember what it already delivered. Until now it trusted the dataset's row count, which can lag for a moment after a restart; a lagging count could make the run start over and charge again for rows you already had, or stop reading before the end. The run now checks for real rows instead of trusting the count, and reads to the end whatever the count says. Rows, prices, charges and the status line on a normal run are exactly as before.
This build also carries the cost-record bookkeeping update shipped on the other transcript actors: if the record this actor keeps of its own running costs cannot be saved, the run log says so plainly, and every run's OUTPUT record carries whether it was saved.
A creator whose post feed Instagram refuses now still comes back with transcripts.
- When Instagram walls a creator's post feed on every connection the run tries, the run reads the reels shown on that creator's profile page and transcribes those instead — the newest of the 12 posts that page shows. Runs that used to end with "nothing was listed, please re-run" now deliver rows, charged exactly like any other transcript.
- The profile page publishes less than the feed does, so reels read from it carry the caption, thumbnail and the posted date to the day, while
plays, likes and comments come back empty.
- Every handle-mode row now carries a
postSource column saying which Instagram surface listed the reel: "profile-page" for the creator's profile (its listing, or the page itself) and "feed" for the deeper post feed a bigger ask walks. Pasted links and chained dataset rows leave it empty.
- "Newest first by date" still holds on every surface, and if no reel can be read at all the creator's row is uncharged and asks for a re-run, as before. Prices, events and every other column are unchanged.
Listing text only — nothing changes in your rows, prices, charges or status line.
- The input-form and dataset screenshots now load from Apify storage instead of an outside host, so they render on the listing itself.
- Every link that pointed outside Apify has been removed from the listing text.
- The free n8n workflow templates still exist; the listing now says where to find them (our Apify profile) instead of linking out.
Internal: long-video budget sizing now follows the live price sheet automatically — nothing changes in your rows, prices, charges or status line.
How much of a run's maximum cost is set aside for a long video's extra minutes used to be a fixed number inside the actor. It now follows the actor's own published price sheet as it stands on the day you run, so a future price change on the store applies to that reserve the moment it takes effect. Prices, events and what you are charged are unchanged.
Completes the internal cost-accounting change from the previous build — nothing changes in your rows, prices, charges or status line.
A storage fix on our side: runs started from any account now contribute to our internal cost accounting the same way our own runs do. Your dataset, your charges and the status line are unchanged.
A small ask is never asked to overpay for a hard creator lookup.
- When Instagram walls a creator's profile, the run tries further connections only while what you asked for can cover them. If it cannot — a one-reel ask at a plan's lowest per-reel price — the creator's row says so and names the fix (ask for more reels per creator). Nothing is charged for a creator that stops there.
- Prices, events and charging are unchanged; the listing's suite blocks name a sibling actor's change.
Internal cost accounting only — nothing changes in your rows, prices, charges or status line.
Runs started from our own account now record the processing they used, so our cost reports are measured instead of estimated. Nothing is added to your run or its storage, and your dataset, your charges and the status line are unchanged.
A creator lookup that fails on every connection now reads the public profile page as a last resort, and the retries alternate between two kinds of connection.
- When Instagram walls the first read of a creator's profile on every connection the run tries, or answers it with its own error for a class of large accounts, the run now reads the creator's public profile page before it would ever report the wall, and continues from there when the page answers.
- The retries after a failed first read now alternate between two kinds of connection instead of one, so a bad minute on one kind no longer decides the run.
- Reels transcribed afterwards are charged exactly as always; a wall that survives every surface still ships the honest uncharged row. Nothing about prices, events or charging changed.
A rate-limited creator lookup now retries on a stronger connection before giving up.
- When Instagram walls the first read of a creator's profile, or answers it with an unreadable page, the run no longer stops there with a "please re-run" row: it retries the same profile on a fresh connection, twice at most, before it would ever report the wall. Reels transcribed afterwards are charged exactly as always — a wall that survives every retry still ships the honest uncharged row.
- Nothing about prices, events or charging changed.
See what you are buying before you run it: real console screenshots in the listing.
- The listing now shows the input form exactly as it appears in the console, and the dataset table of a real run — two transcribed reels with their opening hook, full transcript, duration, short code and post URL. You can see the fields you fill in and the columns you get back before starting anything.
- Every link to another steadyfetch actor now carries that actor's current store name.
An empty input — from the API or an agent — now runs a real 2-reel sample instead of a placeholder row.
Clicking Start with nothing set already listed a creator's reels because the form comes prefilled; sending an empty input from the API, n8n or an MCP agent used to return one frozen sample row and no live transcript. Both now run the same small real sample — the 2 latest reels of one public creator — transcribed and charged like any run, so the first thing you see is the actual output. The status line says it was the sample and how to run your own creators. If Instagram does not serve that profile at that moment, you still get one uncharged row explaining it, never an empty result.
Text-heavy creatives are now read in full.
A reel carrying a lot of on-screen copy used to come back as an uncharged "service problem, please re-run" row, and a re-run gave the same answer. The text reader now gives such a creative a second, larger pass, so it delivers like any other. A creative that still cannot be read reliably ships as an uncharged row that says so, never as a charge.
Watchlists: re-run the same creators on a schedule and pay only for the reels that are new.
Until now every run was a one-off. Ask for the same creator tomorrow and you got — and paid for — the same reels again. Two new fields change that:
- Watchlist name (
watchlistId) — give the run a name such as acme-creators and the actor remembers every reel it has answered under that name, in a key-value store in your own Apify account (ig-reels-watch-<name>, yours to inspect or clear). Every row now says whether the reel is new to that list (isNew) and when it was first seen (firstSeenAt).
- New reels only (
newReelsOnly) — with a watchlist set, reels already on the list are skipped before anything is downloaded: not fetched, not transcribed, not charged. The run's status line, its OUTPUT summary and the closing _summary receipt say how many were new, how many were skipped, and how many the list holds now.
Only a reel the actor actually answered goes on the list — a delivered transcript or on-screen text, or a final uncharged verdict such as no speech. A reel it could not answer (an expired URL, a failed download, a reel your cost cap left out) is not remembered, so the next run tries it again. The list is written the moment a row lands in your dataset and before its charge posts, so an interrupted run can never forget a reel you paid for.
Two safety rules: New reels only without a watchlist name does not run at all (the actor cannot tell a new reel from one you already paid for), and a watchlist the run cannot open stops the run before any spend. Both ship as one uncharged, clearly-labelled row.
Without a watchlist name nothing changes: the two new columns read null, and every input mode, price and charging rule is exactly as before. The page also gained a scheduling recipe, the one-click MCP link, and the suite links now carry the current names.
The step that reads on-screen text off a silent reel moves to our provider's current engine.
If you have on-screen text extraction turned on, the engine reading those frames is being retired by the provider this month, with runs quietly redirected to its replacement two weeks from now. This build makes that move explicitly instead: charged output should never ride a silent switch.
Both engines were run side by side on the same real silent reels before this shipped. The same text comes back, and the rule that matters most is unchanged: a reel whose frames carry no real copy — a bare title plate, b-roll, a logo — is still the uncharged silent row it always was, and is never charged. Nothing about what this actor charges changed.
Long reels no longer come back as failed_processing.
This actor gave itself a fixed two minutes to pull the audio out of a reel, no matter how long that reel was. It was set once, for short clips, and never grew with the video — so a long reel was stopped partway and reported as a broken file. A sibling actor on Facebook ad inventory measured the damage on a real run: every creative past roughly twelve minutes was lost, and nothing under five minutes ever was.
- The time budget is now earned by the reel's own length, up to a generous ceiling, and it is also held inside what is left of your run.
- A video-only stream is recognised before any extraction work starts — th