- Two sentences on the run page are shorter, so a crowded run now shows you more, not less. The status line is cut at 500 characters by the platform, and on the busiest run it can compose — a bare-Start sample stopped at your product limit whose delivery record could not be read — it was 25 characters too long and had to drop the whole breakdown of what was NOT charged, together with the "open an issue" line. "N categories listed nothing or were blocked" now reads "N categories empty or blocked", and "N not a deliverable listing (see rows)" reads "N not deliverable (see rows)". Same facts, same counts, same units. That run now shows the full breakdown AND the support line where it used to show neither. No price, input field, output column or charged event changes.
- The whole "Maximum cost per run" you set is now spent on bestsellers. Before this build the run held back about a tenth of your cost cap before it started — a cushion for platform running costs which, on this actor's pricing, your cap does not pay for at all: your cap buys bestsellers, and the running costs are ours. So the cushion was simply cap you had asked to spend and could not get. On a run capped at $0.10 with bestsellers at $0.0015 the plan asked for 60 bestsellers where the cap paid for 66 — 6 bestsellers of your own cap, unspendable by construction. From this build the plan uses your cap in full, so a run asks for as many bestsellers as your cap can really pay for. 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, and a run that reaches your cap still stops cleanly, ships what it had already fetched, and tells you what is left. No price, input field or output column changes.
- The per-bestseller price and a line on how often the data moves now sit in the opening list, three screens earlier than before. A buyer landing here had to read about 6,884 characters before the price appeared at all. It is now a bullet under the input line: both ends of the tier ladder, the one priced event, and the reminder that a row we could not deliver is never charged — with the full ladder, the event name and the honesty contract unchanged below. Beside it is the cadence line that was not on the first screen at all: what actually moves between one run and the next, so a buyer can tell whether this is a one-off or a schedule. No input field, output column, charged event or price changed; only where the page says them.
- This actor's title and store description now say what it actually returns: the top 60 ranks, not every rank. Amazon puts 60 of its top 100 in the page itself (ranks 1-30 and 51-80); the rest are drawn by the browser and are not in the HTML at all, which the page has explained in its own section for a while. The listing said "every bestseller rank" anyway, so a buyer asking for a top 100 was promised something no run could keep. The title is now Amazon Best Sellers Scraper — Top 60 Ranks, Full Product Row and the description says the same. Same actor, same id, same URL, same input, same output, same price.
- The store description now says that New Releases and Most Wished For are included. They always were — the
list field has carried all three ranked lists since the first build, and they cost the same flat fee — but the listing only sold Best Sellers.
- The dataset's default table now shows
images, variants and specs. All three have always been in every charged row and in the Full detail view, but the table that opens first left them out, so the three fields the listing sells were invisible until you switched views. Nothing about the data changed: no input field, output field, event or price moved.
- The input form now opens on a first run of 20 ranks, not 120. The form arrives with two example categories, and
Max products per category used to sit empty and fall back to 60 — so pressing Start on the example delivered up to 120 bestseller rows and about $0.72 on the Apify free plan. The form now opens with that limit set to 10, so the example run returns the top 10 of each category, 20 rows for about $0.12, and comes back quickly. This is a starting value in the form only: the limit still falls back to 60 whenever it is left out by an API call, a scheduled task or an integration, so nothing you have already wired up changes. Nothing else moved: no input field, output column, event or price changed.
- The input form now opens with the call that works, what one bestseller costs and what is never charged — the screen an AI agent reads. An AI agent shopping the store never reads this page: it reads the input form's own description, and that description used to open by telling a human to click Start. It now opens with a ready-to-send input showing both a department name and a pasted ranked-list link, says which field is required and that every other one can be left out, gives the per-bestseller price on the Apify free plan and on paid plans with the per-1,000 arithmetic, lists what is never charged, names the run option that caps the bill and the two limits that bound the work, and points a keyword, an ASIN or a seller id at the right sibling actor. Categories leads with the value shape and its example instead of the console instruction, which now comes last. Nothing else moved: no input field, output column, event or price changed, and the console form behaves exactly as before.
- 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. Nothing else moved: no input field, output column, event or price changed, and a run that reaches its work behaves exactly as before.
- The links to our other scrapers on this page name them correctly again. Several of those actors were retitled on the store, and this page still used their old names. The links always pointed at the right actors; only the words were out of date.
- Asking for a bigger limit than this actor can do no longer stops the run before it starts.
Max products per category, Max products (whole run) and Max run seconds used to be range-checked by the platform itself, so a run asking for 600 ranks a category, 50,000 products or 30 seconds was refused outright: no run, no rows, no message, nothing on the run page to explain it. The ceilings are unchanged (60 ranks a category, 5,000 products, 60 to 21,600 seconds) but they are now ours to apply: the run starts, continues at the nearest value it can do, and adds one uncharged input_note row naming what you asked for and what bound. Anything you already send inside those ranges behaves exactly as before.
- Nothing else moved: no input field, output column, event or price changed.
- The listing is now called Amazon Best Sellers Scraper — Every Bestseller Rank, Full Row. It is the same actor, at the same web address, with the same input and the same rows. The address did not change, so saved tasks, schedules, API calls and integrations carry on exactly as they were — only the name shown on the store is different.
- An AI agent can now pin this actor straight from the top of the store page. The one-click MCP link, the actor's id, the single input field it needs with a real example, and the run setting that caps what a run may spend now sit in the opening lines of the page instead of far down it. An agent that reads only the start of a listing could not see any of that before, so it could not work out how to call this actor without being told.
- The page also names our other scrapers correctly again. A few links and mentions still used titles those actors no longer have. The links always pointed at the right actors; only the words were out of date.
- One maintenance detail you will not see: the private run-report this actor writes for our own support — numbers only, never anything you typed — now also records the price each charged item carried on that run, so a question about a bill can be answered from the run itself.
- Nothing else moved: no price, event, output column or charge changed, and only delivered products 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, output column or charge changed, and only delivered products are charged.
- A run on a short time limit now gets a real second attempt on a blocked bestseller. Patience is sized to the clock a run actually has instead of being refused whenever the full pause would not fit, so a short run — including the eight-minute sample and Apify's own five-minute health check — gets a retry where before it got none. The first pause is a third as long, so a block that lifts quickly is caught far sooner, and a block that answers the same way twice ends the waiting instead of paying for pauses that were never going to help.
- Nothing else moved: no price, event, output column or charge changed, and only delivered products are charged.
- A department that honestly ranked nothing no longer asks you whether something went wrong. A department Amazon answered with an empty list, and a rank we could confirm is not a deliverable listing, are real answers and nothing is charged for them — but the run page still ended with "Something off? Open an issue", which reads as a fault on a run that worked. It now asks for an issue only when something a re-run could fix went wrong: a department Amazon blocked or we could not read, a listing we could not fetch, a setting we could not accept, a run cut short by your cost cap or the clock, an unreadable delivery record, or a run that delivered nothing and could not say why. Every count still appears on the line exactly as before.
- Nothing else moved: no price, event, output column or charge changed, and only delivered products are charged.
- A block of links pasted into one row is now read as the list you meant, whatever separates them. "Categories" takes one category or link per row. A whole block pasted into a single row was read as one very long address, so a list of category links ranked one at best and lost the rest in silence. 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.
- The run's own record now counts the products your limits left uncollected. When your Max products cap filled, your maximum cost per run was reached, or the run's clock ended the walk, the departments still ahead of it — and the ranks inside a department it had already listed — were simply absent from the report this run writes back to us: a run that asked for five products and delivered two closed its books with three named by nothing at all. Each is now counted under the limit that stopped it, so a run that stops short of what you asked for is visible to us without you having to report it.
- A run that stopped at your product cap now also records whether that cap really filled. It is one true-or-false fact about the run, never the number you typed, and it lets us see a run that claimed your cap stopped it while it had in fact delivered fewer products than you allowed.
- Nothing you can see changed. Your rows, your columns, your receipt row and your bill are exactly as they were — only delivered products are charged, and a product that was not delivered is not charged.
- A run you capped now records the products it asked each department for, not the products that department might have held. Set "Max products" to 2 and this actor reads only the first two ranks of the first department — but its own record of the job still counted the whole department as asked for, so a run that answered honestly could look to us like a run that had lost products. The departments the run never reached are still counted in full, and your limit is still named as the thing that stopped the run.
- Nothing about your rows, your status line or your bill changed.
- A department that holds fewer products than your per-department limit is no longer recorded as if it had held the limit. Ask for up to 60 products from a department that ranks 12, and this run's own record of the job said you had asked for 60 and been given 12 — 48 products that were never there, and nothing in the record to say so. The record now follows what each department really listed. Your rows, your status line and your bill are unchanged: the same 12 products are delivered and charged.
- A department that was never read is now counted one by one, not as a single problem. When a setting such as "Marketplace" cannot be read, every department you sent still gets its own uncharged row saying so — that part is unchanged — but our own record of the run counted that as one problem rather than as the twenty departments it cost, so a run of yours that delivered nothing could look far smaller to us than it was. The same is now true of a department Amazon walled: the run records the products that wall cost, not just the wall.
- A department line this actor could not read now stays in the count of what you asked for. If your list held five departments and one of them was neither a department name nor a Best Sellers link, the run's own record quietly dropped it from what you had asked for. It is still answered with its own uncharged row, and nothing is charged for it.
- Your "Max products" limit is now recorded as what stopped the run, never as what you asked for. A run that filled your limit reads as a run that filled your limit, with the rest of the departments you sent still on the record as asked for and unfinished.
- A product ranked in two of your departments is counted once, the way it has always been delivered once and charged once.
- A run now pauses only when it can finish a whole second round of attempts afterwards and still have time to write its rows. When Amazon refuses every route, this actor waits a minute and a half to three minutes and asks again. The check that decided whether that pause was affordable set aside half a minute for the round of attempts that follows it, while a real round here takes between two and a half and just over four minutes, depending on how many routes the run is allowed to use. So on a short run — the automatic five-minute check, or a low Max run seconds — the run could take the full pause and then run out of clock part-way through the round it had just waited for. The pause is now measured against a real round on this actor's own connection ladder, so a first run that waits now always keeps room to finish and report: a short run either waits and finishes cleanly or answers straight away, and a run with the time to wait behaves exactly as it did.
- Nothing about your dataset or your bill changed: a pause is never charged, and only delivered products are charged.
- A sentence in the entry below called this actor's sample connection routes "free". A run always spends platform time you pay for, so nothing on this page is described that way: the sentence now says the no-input sample uses only the unpaid connection routes. Nothing about what this actor does, delivers or charges changed.
- 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 reads one real bestseller list, charged like any run. Amazon sometimes turns every connection away for a few minutes at a time, and one full round of attempts could use up most of the sample's own three-minute limit — so the pause-and-try-again this actor gained in the last build 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 eight minutes, sized to hold one full round of attempts, one pause, another full round, and enough time left over to stop cleanly and report. A sample Amazon answers still finishes in seconds; only a blocked one uses the extra time; the no-input sample still uses only the unpaid connection routes, so a wait never buys a paid one; and nothing is charged unless product rows are delivered.
- How much of its remaining time a blocked run may spend waiting now follows the size of what you asked for. A run with more lists still to read keeps exactly the limit it had — no more than half the time left — so a wide block still leaves the later lists their share of the run. A run with a single list may spend what is left on its one pause, because nothing else is waiting for that time.
- A category or a product Amazon walls now gets another try later in the same run, when the run has the time for it. Every route to a ranked list, and to each product on it, can be refused for a few minutes at a stretch, and this actor used to report that as "please re-run" within about a minute — with most of a long run still unused. Now, when a list or a rank is left walled after the first pass and the run still holds real time, it waits one to three minutes, comes back on fresh connections and asks again — more than once on a long run, never on a short one, and never past the point where the summary row and the run's own report must still be written. A department that genuinely does not exist on that store, a list the store served and confirmed empty, a page in a layout we could not read, and a product that is not in that country's catalogue are still reported at once and never waited on.
- The rows for whatever stayed walled land after the delivered ones, in the order you listed your categories and in rank order within each one, and each now says how long the run waited and how many passes it made before giving up. They are still uncharged and still safe to re-run.
- A walled list is now counted apart from a department that simply has nothing ranked. Both still ship the same honest uncharged row; the difference is in what this actor reports back to us, so a spell of walls reaches us as a wall rather than as categories you got wrong.
- The summary row records the wait: how many lists and ranks were walled, how many passes were made, how many seconds were spent waiting, and how many of them the wait recovered.
- A wait is taken only when it pays for itself. An idle minute costs this actor's own compute, so the run waits only while the lists and ranks still to deliver would cover it at your price — a walled category is priced at every rank it can still yield — except that a run which has delivered nothing at all always gets one wait. What is charged does not change: only delivered products are charged, exactly as before.
- A run near its time limit now stops cleanly instead of being cut off mid-fetch. The page-fetch ladder now checks the run's own clock before every attempt and every pause between attempts, so it never starts a fetch it cannot finish in time. A run that reaches its limit ends with its summary row intact rather than being stopped part-way through a request.
- Every run now reports what you asked for in the same unit it reports what it delivered. The run's own record counted your ask in categories while it counted the result in product rows, so a run that named two categories and came back with sixty products recorded an ask of two — an ask smaller than its own delivery. Your ask is now the row cap you set in "Max products (whole run)", or, when you set no cap, the categories you sent times "Max products per category". The summary row is unchanged: it still counts the categories you asked for, and says so. Nothing about what is collected, delivered or charged changed.
- Settings with no categories now run the sample list under your settings, instead of returning one guidance row. Picking a different Marketplace or List, or setting a limit, and clicking Start with Categories empty used to end the run with a single uncharged "no categories were provided" row — so changing one dropdown was answered worse than changing nothing at all. That run now ranks a real department with your settings applied, charged like any run.
- The sample now uses a real department on each store. Amazon's department names are per-store, so the sample on
amazon.de now reads its own Electronics department instead of a name that only exists on amazon.com — which used to come back as an empty list.
- A limit is a ceiling, never a request. On one of these runs "Max products per category", "Max products (whole run)" and "Max run seconds" are honoured as at most — the sample's own five ranks and three-minute window are used when they are smaller, so narrowing a setting can never widen the bill.
- One uncharged row explains it, naming every setting you did set, that everything else used the sample's own values, and the field to fill in for your own run. It is never counted as a miss.
- A field this actor does not recognise, or a category list you actually filled in, still gets the guidance row — answering a typo with sample rows would read as if it had worked. A store or a list this actor does not offer is still refused by name.
- A mistyped "Marketplace" or "List" no longer swallows your category list. One unreadable value in either field used to end the run with a single guidance row, whatever you had typed in "Categories" — twenty categories came back as one row. Every category you sent now gets its own uncharged row saying it was not read and which field stopped it, and the run still succeeds. Nothing is read and nothing is charged, exactly as before.
- "Marketplace" now says which of three things went wrong. A real Amazon store this actor does not cover (amazon.ca, amazon.fr, amazon.co.jp and the rest, plus the country names people type for them) names the nearest store that does work, instead of sending you back to re-check a spelling that was already right. A value naming more than one store — "worldwide", "Europe", or just "amazon" — says this actor reads one store at a time. Only a value nothing can read is now reported as unreadable.
- Every uncharged input row now carries the field it is about, so a run with several settings set says which one to fix without reading the sentence.
- The run status line and the summary row count what you asked for, not what survived the settings. A run stopped by a refused setting said "across 0 categories" when you had asked for twenty; both now say 20 and name how many were not read, so the run page and the dataset never give you two different numbers for the same fact.
- The run's own report to us carries that same number — the categories you typed, counted before any limit applies. It used to report whichever list in your input happened to be longest, so a run that turned every category away could look like it had nothing to do.
- A store written the ordinary way now works in "Marketplace". The field used to take the exact domain and nothing else, so
US, USA, United States, Amazon.com, www.amazon.com and a pasted store link each stopped the run before a single category was read — one guidance row, and nothing for anything you sent. The domain, the host, a pasted link, the country code and the country name all resolve now. A store this actor does not cover is still refused rather than answered with a different one.
- "List" reads the value you actually sent.
Best Sellers, best-sellers, New Releases and Most Wished For now land on the list they name, instead of stopping the run as an unrecognised value.
- A run stopped by an input mistake now tells us which field was wrong — the field's name only, never the value you typed. A check that is too strict now reaches us as one thing to fix instead of looking like many unrelated typos.
- A best-seller page that comes back unreadable is now retried before it is reported as a miss. A page that arrives complete but with none of the list on it used to end the attempt right there. The run now takes another look — a different page layout, a different network route — and reports a miss only if those come back empty too. Same price either way.
- A run that stops before it starts now reports its outcome too — a run refused for its memory setting now reaches 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.
- Run status lines fit the run page again; sample-run wording shortened.
- 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 stopped by a pricing fault on our side now asks you to open an issue once, not twice, and names the reply time.
- A run that filled the row cap you set is no longer treated as a run that went wrong. The Issues-tab line now appears only when something actually did.
- The run page points at the Issues tab on every ending that went wrong, including a run refused before it started.
- One support promise on this page — the older three-hours line is gone.
- 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 fully delivered run is left alone.
- One support promise across this page — issues are answered in a couple of hours, always within a day.
Documentation build: nothing about what runs, what is delivered or what is charged changed.
- The screenshots on this page now load from Apify storage. The same two images of a real run, served from the platform itself instead of an outside host.
- Every link on this page now stays inside Apify.
Documentation build: nothing about what runs, what is delivered or what is charged changed.
- Real console screenshots on this page — the input form exactly as it arrives, and the dataset table a real run delivers.
- One-click MCP link — pin this actor in Claude, Cursor or any MCP client straight from this page.
- Suite links refreshed to the current names of the other steadyfetch actors.
- Input-form copy corrected. The Categories field still said a bare Start returns uncharged sample rows. It ranks a real Best Sellers top five, charged like any run — the field now says so, as this page already did.
Start with the default form and get real ranked products instead of placeholder rows.
- A bare Start now runs a 5-rank sample. Click Start with nothing set (or send an empty input from the API) and the run ranks the top five of the
amazon.com electronics Best Sellers and returns their full rows, charged like any other products. The placeholder "sample rows" are gone; what you see is what a real run returns.
- The sample stays small and quick by design: one category, five ranks, the no-cost connection lanes only, and a three-minute window. On a bad Amazon minute you get one uncharged row saying the list was not served (re-run in a minute), never an empty dataset.
- The status line says when a run was the sample and how to run your own categories.
- Nothing else changed: any input with categories in it behaves exactly as before, and a mistyped field still gets a row naming the field instead of a sample.
The Marketplace and List dropdowns accept null as well, so an all-fields-null template runs.
- An input that fills every optional field with
null now starts. That is the shape n8n, Make and most agent frameworks actually send, and two fields were still refusing it: the Marketplace and List dropdowns. {"categories": ["electronics"], "marketplace": null, "list": null, "maxItems": null} used to be rejected before the run began, with an error about allowed values. It now runs on the defaults — amazon.com, Best Sellers — exactly as if those fields had been left out.
- A value the dropdown does not list is answered by name, and nothing is read.
"list": "movers-and-shakers" is the one a buyer actually types, and Best Sellers rows delivered under that heading would read exactly like the answer they asked for. It now returns one uncharged row naming the three lists this actor reads, and reads nothing. Same for a store we do not cover. Nothing is charged, and the run still succeeds.
- Every value the dropdowns list behaves exactly as before, and the console pickers are unchanged.
- The run's own status line now says "1 input error" instead of "1 category line could not be read". A mistyped
list was being reported as a category problem, which sent you looking at the wrong box; the dataset row has always named the right one.
- Nothing about what is delivered or charged changed. One flat fee per delivered rank, misses never charged.
Optional settings now accept null, and null means "use the default".
- An explicit
null on an optional setting starts the run instead of refusing it. Agents and integrations routinely fill in the fields they are not using with null; until now {"categories": ["electronics"], "maxItems": null} was rejected before the run began, with an error saying the field had to be an integer. It now runs exactly as if the field had been left out.
null never changes what a run does. Max products per category, Max products (whole run), Max run seconds, Include variants and Include specifications each fall back to the same default they would have used anyway. This is a second way to say "leave it alone", not new behaviour.
Categories still cannot be null, and neither can the Marketplace and List dropdowns — a dropdown only accepts one of the values it lists. Send a real value or leave the field out entirely. Categories staying strict is deliberate: it is what catches a mistyped field name before the run starts rather than after.
- Nothing about what is delivered or charged changed. One flat fee per delivered rank, misses never charged.
Rows now arrive in rank order, the way this page has always described them.
- The dataset is written in rank order — 1, 2, 3 — and stays that way. Two products are fetched at a time, and until this release each one was written the moment its own page came back, so a fast rank #4 could land above a slow rank #2. The ranks were always correct on the rows themselves; only the order they were written in was not. Rows are now written in rank order while the fetching still runs side by side, so the run is no slower.
- An uncharged miss sits in its own rank slot too, in line with the products around it, instead of at the end. Nothing about what is delivered or charged changed: misses are still never charged, and each delivered product is still one flat fee.
The linked example dataset is re-shot from the code this release ships, and it now has a permanent address.
- The example-dataset link points at a fresh run of exactly this code — the Electronics best sellers, two delivered product rows with the Sold-by cluster populated, the honest uncharged
not_a_product row where Amazon's own subscription plan sits at rank #1, and the summary row last.
- That sample now lives at a permanent address. It used to be one run's own output, which is cleared when that run ages out — the link would eventually have gone dead on its own. It cannot now.
- The page says "one real run of the current code", not "of the current build", because a release that changes only this page must not make that sentence false. Nothing about what this actor delivers or charges changed in this release.
The linked example dataset is re-shot from a verified run of the current build, and one status-line wording is corrected.
- The example-dataset link now points at a run of this build — the Electronics best sellers with the Sold-by cluster populated on delivered rows, the honest uncharged
not_a_product row at rank #1, and the summary row last.
- Status-line grammar: a single permanent miss now reads "1 product was not a deliverable product listing" instead of the plural form. Nothing about what this actor delivers or charges changed in this release.
Ranked rows carry their Sold-by seller and their specs again — the two gaps that hit device-heavy categories hardest.
buyBoxSeller, buyBoxSellerId, fulfilledByAmazon and soldByAmazon are filled in again. Amazon serves the Sold-by block in several layouts and ranked rows had been shipping the cluster as null; the parser now reads all of them, verified against freshly captured pages.
- Amazon's own device pages now deliver their specs. Best-seller lists are full of Amazon devices, whose pages keep the spec sheet in a different layout — those rows previously shipped
specs: {}. categoryPath and bestSellersRank stay empty on those pages because Amazon renders neither there; the README now discloses that.
- The
‎Apple brand garbage is gone. Invisible direction marks some pages prefix onto brand and spec values are stripped from every text field.
- New column:
buyBoxNote. When a served page genuinely names no seller, the Sold-by fields stay null and this column says so on that exact row.
- The run's status line now separates permanent misses from temporary ones. A rank held by something that is not a product listing (Amazon's own subscription plans, for one) no longer reads "could not be fetched" as if a re-run would fix it.
- amazon.co.uk lists deliver again — the fetch ladder gained a final mobile-fingerprint step on the same residential exits after .co.uk began refusing every desktop fingerprint. Nothing about what is charged changed: misses are never charged.
Clearer release notes — this page's notes now read more plainly. Nothing about what this actor delivers or charges changed.
Every actor named in the README is now a live link.
- The steadyfetch shelf links point at the published actors. The Amazon Seller Scraper entry and every other name in the suite tables now link to their live store pages. Nothing about what this actor delivers or charges changed.
Restarts, resurrections and billing bookkeeping hardened end to end.
- A restarted run no longer trusts a stale answer about what it already delivered. Right after a restart, the platform's view of the run's own output can lag a few seconds behind. A run that believed that lagging answer could have delivered — and charged — products a second time, or lost count of rows past the lagging total. It now double-checks an "empty" answer and reads its own output through to the true end before doing anything, so nothing already delivered is ever fetched, delivered or billed again.
- Finishing an interrupted charge can never bill twice — and can never sink the run. When a restart finds a charge from the previous attempt half-finished, the amount still owed is reckoned against the highest count of what already landed, so a lagging counter cannot cause a repeat charge. And if that settlement cannot be completed at that moment, the run carries on and settles it on a later resume instead of failing — nothing extra is charged either way.
- A run being moved to another server hands over cleanly. The departing side no longer declares the run finished on its way out — the run continues where it left off.
- A resurrected run gets a real working window. "Max run seconds" counts the run's life, not each restart's — but a run resurrected after that window had already passed used to stop on its first step, blaming your own limits, with nothing new delivered. It now gets a fresh, bounded window to finish the remaining work.
- If this actor's own price configuration is ever broken, a run stops before spending anything. Both broken shapes — one that would bill for rows we promise carry no result fee, and one that could not bill at all — halt immediately, fetch nothing, charge nothing, and say plainly that the fault is ours.
- A charge is counted only when it actually landed. The
charged flag and the run's own charge totals now reflect the platform's answer, never an assumption.
Numbers printed in the "wrong" language now always read as the numbers they are.
- Counts survive a product page served in another language's number format. Amazon renders a page in the formatting of the route that fetched it, not the store's own, so amazon.de sometimes arrives with English-style numbers — a review count of "4,305". Read with German number rules that used to collapse into a decimal: a charged
reviewCount of 4, a thousand times under. Grouped whole numbers now read as grouped whole numbers in every language — on review counts, list ranks and prices alike.
- "Bought in past month" badges phrased without a "+" right after the digits parse correctly, and the localized German thousand/million marks ("Tsd.", "Mio.") are understood — "Mehr als 1.000 Mal … gekauft" is 1,000, never 1,000,000.
- A Nordic "kr" price mark never takes another marketplace's currency label. When the currency of a price cannot be resolved from the page, the
currency column ships honestly empty instead of guessed.
- The Amazon suite links in the README now point at the published actors.
"Nothing ranked here" now means Amazon really said so.
- A category is never reported as empty on the word of a request Amazon distrusts. Amazon sometimes serves a full "no results" page to a request it does not trust, for a list that in fact has plenty of products. Such a page is now re-checked before any verdict is given, and if that re-check never succeeds the row says the list could not be read this run and asks you to re-run — uncharged. This matters twice over, because an empty-category answer used to be remembered for the rest of the run: a resumed run would not ask again.
- A ranked page we cannot read is reported as our problem, not yours. If Amazon serves a real list page in a layout this actor cannot parse, the row now says so and is flagged for us to look at, rather than claiming the category has nothing ranked on it.
- A list page that redirected to a robot check is read as a robot check even when the destination answers "page not found" — it no longer comes back as "that category page does not exist".
A typo in an input field name now gets a helpful pointer instead of sample rows.
- A run that sets a field this actor does not have is answered, not demoed. Sending something like
depts instead of categories used to look exactly like an empty run, so it came back with the uncharged sample rows — and nothing said the field had been ignored. Such a run now returns one uncharged row that names the field it did not recognise, names Categories (input key categories) and shows the shape to send. A run that really is empty still returns the sample rows, and a run with real categories is unchanged.
Price parsing is hardened, ported from the family's shared parser.
- Promotional wording printed next to a price ("avec 18 % d'économies", "con il 18 % di risparmio") can no longer bleed its digits into the parsed amount — a percentage is never read as part of a price, in any language.
- The Nordic "kr" and Polish "zł" currency marks are now recognised wherever Amazon prints them, instead of being dropped.
- Review counts on European listings are read correctly. Some storefront layouts print the total with a space between the digit groups ("4 298"); earlier builds could not read that formatting and shipped an honest empty
reviewCount. The count now arrives as a number, in the store's own formatting.
- The uncharged sample run survives a restart. Starting the actor with no input returns a small, uncharged, offline sample. If that run was moved to another server or resurrected, it wrote the whole sample into your dataset a second time. It now recognises the rows it has already delivered and adds nothing.
- "Bought in past month" is correct on decimal counts. Amazon writes some of these as
1.5K+, and as 1,5K+ on amazon.de. Both were read as 15,000 instead of 1,500 — ten times the real figure. Whole-number forms such as 2K+ and the German 1.000+ were always right and are unchanged.
One safety rule tightened on the restart path shipped in 1.0.4.
- When a restarted run needs to finish an interrupted charge, it first confirms against the run's own billing record what has already been billed. If that record cannot be read, the run now settles nothing rather than trusting a second source that could be stale. An unbilled row costs us; billing you twice costs you, and only one of those is acceptable.
- The example dataset linked from this page is now a real, unedited run: two departments, three delivered rows, and one uncharged row where Amazon's own subscription plan sits at rank #1.
A run that gets moved between servers no longer repeats or re-charges anything.
- Apify moves long runs to another server and restarts them when it does. Before this build, the restarted run knew nothing about what the first half had already done: it fetched the same ranked products again, wrote them into your dataset a second time, and charged for them a second time. It now re-reads its own results first and picks up at the next rank — no duplicate rows, no second charge, and a resurrected run does the same.
- Your product limit now counts the rows you already have. A run capped at 100 that moves mid-way delivers 100, not 200.
- Your
Max run seconds and our own internal run ceiling are measured from when the run started, not from when it was restarted — so a moved run does not quietly hand itself a second full time budget.
- If a charge was interrupted between a row landing in your dataset and being billed, that single charge is completed on restart, and it can never be made twice. If the run cannot read its own results back at all after a restart, it delivers your rows but bills nothing, and says so.
- A category or a ranked product with a permanent answer — "that department does not exist here", "that page is gone" — is now reported once, not once per restart. Temporary problems are still retried, because a re-run is exactly what they ask for.
- Amazon sells some of its own subscription plans through ordinary product ids, and one of them is rank #1 in the US Electronics chart. Those pages carry no product listing at all, so they used to come back as
parse_failed — "a layout we could not read, that one is on us". They now come back as not_a_product, which is what they are. Still uncharged, either way.
- Amazon's sign-in wall is now detected on every route in one place, including when Amazon redirects to the sign-in page instead of showing the wall. A missed wall used to read as "this category is empty", which is a permanent verdict about your input rather than the temporary block it really is.
- A category page that quietly falls back to Amazon's Best Sellers front page is now recognised from the address it landed on, not only from the page's own navigation — so "that department does not exist in this store" stays accurate when Amazon changes the page.
Review-fix build: billing accuracy, honest statuses, and correct ranks.
- Billing accuracy: when two ranked entries turn out to be the same product — a variant that redirects to one canonical listing — it is delivered and charged exactly once, even when both are fetched at the same moment. A row that fails to be written is no longer counted as delivered, and its charge slot goes back.
- A category link Amazon answers with "page not found" is now a permanent, uncharged answer that tells you to check the slug or paste the link from Amazon's own list. It is no longer retried through every route, and it no longer reads as "temporary — please re-run".
- Rank numbers are read with the store's own number format, so a German list's
1.234 is rank 1,234, and a badge we cannot read comes back empty instead of a wrong-looking number.
- When your spend cap is what stops the run, the summary says so even if the cap runs out on the last category.
Initial release.
- Name an Amazon category and get one complete product row for every rank: the rank, the list, the category and its path, plus price, currency, list price, stock, buy-box seller, rating, review count, bought-in-past-month, variants, bestseller ranks, images, bullet points and the specifications table.
- Best Sellers, New Releases and Most Wished For. Movers & Shakers is not offered because Amazon builds that grid in the browser and the page carries no rows to read.
- 60 ranks per category — ranks 1-30 and 51-80, which is what Amazon puts in the page. Ranks 31-50 and 81-100 are loaded by the browser and are not there to read. Subcategories work as input, and each one is its own list of 60.
- Takes a short department name (electronics, kitchen) or a link copied from the page — both of Amazon's URL shapes, subcategory links included. A pasted link decides its own store and list, so one run can mix stores.
- Marketplaces: amazon.com, amazon.co.uk and amazon.de.
- One priced event per delivered product and nothing else — no start fee, no per-category fee, no per-field fee.
- Full product detail on every rank — there is no cheaper "list only" mode, because that would need a second event and this family charges one.
- Categories that list nothing or are blocked, and individual ranks that cannot be fetched, are returned with an honest status and are never charged, and every run ends with a summary row that reconciles against the invoice.
- Your limits are exact: the run stops cleanly, names the setting that stopped it, and hands back the categories still to do.