# Changelog of Google Trends Scraper — Google Trends Data, Interest Over Time (`steadyfetch/google-trends-scraper`) Actor

- **URL**: https://apify.com/steadyfetch/google-trends-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/steadyfetch/google-trends-scraper.md

## Changelog

### 1.1.70 — 2026-09-24

- **A time range written as shorthand now runs instead of being turned away.** "12m", "12-m", "12 months", "past 12 months", "Today 12-m" and Google's own menu wording such as "Past 7 days" are read as the one Google window they name (here `today 12-m` and `now 7-d`), and the run adds one uncharged row saying what you sent and what it read, plus a line in the run log. The same goes for the hour, day, week, month and five-year windows. A value that could mean more than one window is still never guessed: a bare "1" is refused, and so is a span Google has no window for, such as "6m" — and the refusal now names the nearest windows, for example `did you mean "now 1-H", "now 1-d" or "today 1-m"?`. The exact presets and custom date ranges work exactly as before.
- **A run refused over its input now leaves one uncharged row in the dataset.** Before, a refused run's dataset was empty and the guidance was only on the status line and in the `INPUT_GUIDANCE` record, so anything reading the dataset got nothing back. The run now also writes one row with `surface: "notice"`, `data.status: "input_error"`, the field to fix and the same guidance, marked `charged: false`. Nothing is charged for it. No price, input field, output column or charged event changed.

### 1.1.69 — 2026-09-24

- **Settings sent wrapped in an extra "input" object are now read.** A run whose input arrives as `{"input": {…}}` — for example from `run_input={"input": {...}}` in the Python client — now reads those settings as if they were sent directly and adds one uncharged note row naming them. Before, the run stopped with a guidance row and fetched nothing. Nothing changes about the price, the input fields or the output columns.

### 1.1.68 — 2026-09-24

- **A run that Apify restarts after it has already delivered keeps its own record of that delivery.** If the restarted part of a run delivers nothing new, the run's internal record now keeps what the earlier part delivered and charged, with a note of the restart, instead of being rewritten as if nothing had been delivered; one line in the run log says so. Nothing changes about what is delivered, which rows are charged, the price, the input fields or the output columns.

### 1.1.67 — 2026-09-23

- **The top of this page now says how often Google Trends data changes and how to put a run on a schedule.** A 12-month timeline refreshes about weekly, the daily windows about daily, and the hourly windows and trending-now through the day; the page now shows how to save your input as a Task and add it to an Apify Schedule at the cadence that fits your time range. Every rerun is a fresh read, charged like any run, so a schedule matched to your window avoids buying the same report twice.
- **The Search terms field now opens with what to pass and one example, `["bitcoin", "ethereum"]`, followed by what is never charged.** An AI agent reading this actor through Apify's MCP server sees roughly the first 500 characters of each field, and those now carry the value shape and the never-charged rule. No price, input field, output column or charged event changed.

### 1.1.66 — 2026-09-22

- **A failed internal bookkeeping write no longer prints its storage address in the run log.** Nothing changes about what is delivered, which rows are charged, the price, the input fields or the output columns.

### 1.1.65 — 2026-09-22

- **Type a country's own name in its own language and the run now finds that market — fifty-nine spellings across forty-four markets, "Deutschland", "日本", "مصر", "España" and "भारत" among them.** The location fields already read a two-letter code, a three-letter code and a country's English name, so "India" worked and "भारत" did not: the name went to Google exactly as typed, charted nothing, and you paid platform time for a market you never reached. From this build the native spelling lands on the same market its English name does, on both `geo` and the trending-now country, and the run still shows you the reading on the same uncharged note row it always used — which market it used, and the code to set if you want to say it exactly. A spelling that names no country is still never swapped for a guess: it is passed to Google as you typed it, on an uncharged row that says so and now names the native name as a form that works. The names are a reviewed list, and every one of them resolves only to a market this actor already carries — it will never answer you with a country you did not ask for. No price, no charged event, no input field and no output column changed.

### 1.1.64 — 2026-09-22

- **Set a category, leave the search terms empty, and the run now explores that category instead of reading our example keyword under it.** Until this build a run carrying a category and no search terms fell through to the sample: it read `bitcoin` under your category, charged one trend report for it, and if you had selected Related topics it charged the separate topics fee for bitcoin's topics too. Nobody sets a category in order to be told about bitcoin. `{"category": 7}` with no search terms now returns Google's own category view over the location and time range you set: the category's interest-over-time series, and its ranked top 25 and rising 25 queries — what people in that category are searching for, each with its own rise beside it. Common IDs are 7 Finance, 45 Health, 12 Business, 16 News, and 0 still means all categories. It costs **one trend report** for the whole category, exactly as one keyword does, on the same ladder — there is no new charge and no new event. Two surfaces are not on this route and the run says so rather than leaving a gap: Google's category view carries no region table, and related topics need a search term to be about, so a run that asked for either gets its rows for the surfaces that do work plus one **uncharged** row naming what was left out and why — and the related-topics fee is never charged on a category-only run. Rows are the same shape as always, with `whole category` in the `keyword` column and the ID in `category`. A category set **beside** search terms still just narrows those terms, exactly as before, and a run with no category at all is unchanged in every respect.

- **A run billed at the Apify free plan column now says so on its own run page, and names what the same run costs on each paid rung.** A trend report is $9.00 per 1,000 on the Apify free plan, $6.00 on Bronze, $4.00 on Silver and $2.25 from Gold, and that table has been on the store page since the ladder was filed. The run page — the surface you are actually looking at while a run spends your credit — said nothing about it, so a buyer on the free plan had no way to see from that page that the same run is a quarter of the price on Gold. The status line now carries one clause naming the column that billed the run and what each paid rung costs. Every number in it is the filed ladder, checked against the repo's own pricing record on every build, so it cannot drift from your bill. The related-topics fee is not quoted: it is the same price on every plan and names no column. On a crowded run the clause is the first thing dropped to make room — ahead of the sample preamble, the warnings and the Issues ask — because it is a standing price the store page carries in full while everything else on that line is a fact about your run. A run on a paid plan reads exactly as it did before. No price, input field, output column or charged event changed.

### 1.1.63 — 2026-09-20

- **The run page's one line now always fits, so the stop, the charge statement and the Issues ask can no longer be cut off.** The platform shows the first 500 characters of a run's status line and drops the rest — and the rest is exactly where this line put the things you act on: what stopped the run and how to raise it, whether anything was charged, and where to tell us if something looked wrong. On a run that carried several of those at once the line ran to 660 characters, so the page cut it mid-sentence. From this build the line measures itself and gives way in a fixed order until it fits: the sample-run preamble first, then the warnings about settings this run ignored or cut — which fold to a count, never to silence — and only then the Issues ask. Every count, every "not charged" and the stop's own remedy stay on the line whatever else has to go. No input field, output column, charged event or price changed.

### 1.1.62 — 2026-09-20

(1.1.61 was built and withdrawn before it was ever tagged latest — its filter-only Start failed the actor's own output check; 1.1.62 is the same change with that fixed. Buyers never ran 1.1.61.)

- **The paid price is now $2.25 per 1,000 trend reports, down from $7.50, and one report covers a keyword's whole answer instead of one surface.** The change was notified on 5 September and took effect at 22:00 UTC on 19 September; this build is the page and the form catching up to it. The full ladder, printed on the page for the first time: $9.00 per 1,000 on the Apify free plan, $6.00 Bronze, $4.00 Silver, $2.25 Gold and above. Platform usage is still included in that price, there is still no start fee, no minimum and no subscription, and a failed, blocked or empty fetch is still never charged.
- **A keyword's timeline, its related queries and its region table now settle as ONE report, so asking for all three costs what asking for one used to cost.** They used to be three separately billed results. A run of 100 keywords on all three default surfaces was 300 results and is now 100 reports — before the price cut. Two things are billed on their own and the page says so plainly: each trending-now row is its own report, because a trending feed has no keyword to belong to, and a complete related-topics set is a Related topics report at a flat $0.0075 on every plan, charged only when you ask for that surface. Nothing about your input or your output columns changed.
- **Press Start with nothing filled in and you now get today's data instead of a canned answer.** An API call with no input at all — or the untouched form — used to return frozen sample rows captured months ago. It now runs a real, small sample: one example keyword (`bitcoin`) on the three default surfaces, worldwide, over the last 12 months, inside its own three-minute window, charged like any run at one trend report. If Google does not serve it, nothing is charged and you still get one row per result saying so, plus the run summary.
- **Change a setting, leave the search terms empty, and you now get today's data under that setting — and two kinds of run that used to stop with "Unexpected error" now finish normally.** Naming no search terms but picking, say, a country or a shorter time range used to return a stored example captured months ago, and a setting that example could not be shown under was refused outright: you got no rows at all. It now reads the same one example keyword (`bitcoin`) live, using everything you did set — your location, your time range, your category, your search property, your choice of surfaces — and one uncharged row names the settings it ran under. The only thing it still cannot do is compare, because a comparison needs two to five of your own terms; that asks you for search terms, uncharged, exactly as before. The same build fixes an internal output check that could stop a run outright: a run that owed you an uncharged note — the one above, the one naming a country this actor had to read from its name, or the one saying a term list longer than 300 was shortened — could fail on its own bookkeeping row and deliver nothing. Those runs now complete, with their rows, their note and their summary — and they no longer tell you a result returned no data, or invite you to open an issue, over a note that only means the run did exactly what you asked.
- **Every run now ends with its own uncharged receipt row, and every result that did not arrive gets its own uncharged row.** Both were impossible until the price change above, because on the old pricing a row in your dataset *was* the charge — so telling you what did not arrive would have billed you for the telling. The last row of every run carries `_summary: true`, `charged: false`, `delivered`, `chargedEvents` and `stoppedBy`, so what you were charged reconciles from the dataset alone; a result Google did not serve ships a `surface: "notice"` row naming which surface it was owed on and what to do about it. Export with `clean=true` and reconcile from the summary row straight away, or from the run's own charge counter about twelve seconds after the run ends. The page's Output section now describes all of it.
- **A run that waited out a Google rate limit no longer tells you to "wait a minute or two and try again".** On the related-topics surface that was the whole of the advice, and it was exactly what the run had just spent minutes doing on your behalf — so it read as though nothing had been tried. The run record now says the run already waited and that the surface is worth asking for again later. A run with no wait behind it says exactly what it said before.
- **The page now states both dataset row shapes instead of only describing them in passing.** Keyword rows carry the eleven-field envelope; trending-now rows carry five, because a trending feed has no keyword, time range or comparison, and this actor will not pad a row with six columns that could only ever say "not applicable". That five-field shape is unchanged and stays unchanged — it was promised on this page and it is kept. A CSV or Excel export unions the two for you, so trending columns come back blank rather than missing.

### 1.1.60 — 2026-09-19

- **The whole "Maximum cost per run" you set is now spent on trend reports.** A capped run used to hold back about a tenth of your cap as a cushion against platform usage — but on this actor's pricing your cap pays for the reports and nothing else, so that tenth was simply cap you had asked to spend and did not get: a cap worth eleven reports planned ten, and a cap worth a hundred planned ninety. A run now plans every report its cap can pay for, and it still ends the way it always has — on its own line naming your cap and the exact count of what was left to fetch, never on a run the platform cuts short. Nothing about the price, the charged event, the input form or any output column changed.

### 1.1.59 — 2026-09-18

- **The fees this page mentions on three neighbouring actors are live now, so the page states them plainly instead of announcing them.** The comparison and shelf sections told you that keyword volume's fresh lookup, profile posts' profile lookup and Google Jobs' search fee would begin on a coming date. Those three fees took effect, so the sentences are now in the present tense and no longer read as something still to come — the amounts, the actors and the delivery conditions behind them are unchanged, and each of those actors' own pages states its fee. This build changes nothing about this actor: no input field, output column, charged event or price of its own moved.

### 1.1.58 — 2026-09-16

- **Type a country's name into "Location" and the run now reads that market, instead of sending your spelling to Google unchanged.** "Location" (`geo`) and "Trending now country" took an ISO code and passed anything else straight through, so someone who typed "India" had `geo=India` sent to Google Trends: nothing charted, and no row said why. Both fields now read the three-letter code (IND, GBR, USA), the country's full English name ("India", "United Kingdom", "Saudi Arabia") and the ordinary spellings people use (USA, UK, Great Britain, Holland, South Korea, UAE), punctuation and accents included ("U.S.A.", "Türkiye"). Whenever the run has to read a spelling rather than a code it says so on one uncharged note row — "Read "India" as IN" — so you always see which market the numbers are for. Two deliberate limits. Google's own region and metro codes (`US-CA`, `US-CA-807`) are passed through exactly as you typed them and are never rewritten, because this actor carries no table of them and guessing one would chart a place you did not ask about — so a region NAME like "California" is never turned into a region code either. And a value that names no country at all is still sent to Google as you typed it, never swapped for a guess; what is new is that you now get an uncharged row saying it was not recognised, which is why the results may come back empty. Plain two-letter codes and an empty "Location" (worldwide) behave exactly as before. No input field, output column, charged event or price changed.

### 1.1.57 — 2026-09-16

- **The last minute of every run used to buy nothing; it now buys the reads it can afford.** Before starting a fetch the run checked whether it had a full minute left, because a fetch used to be able to take that long. Since the last release every read is cut off at whatever time the run actually has, so a fetch can no longer overrun — but the old check was still turning away reads with plenty of time for them, and a short run could end with nothing collected and a message saying it ran out of time. The check is now sized to what a fetch really needs, keeping back what the run still owes for writing your rows and the summary. Short runs collect more; a run that genuinely cannot fit another fetch still stops cleanly with the same honest message, and nothing about pricing or what is charged changes.

### 1.1.56 — 2026-09-15

- **A run whose connection to Google goes quiet now finishes inside your run timeout, with its results and its summary, instead of being killed for overrunning it.** Each read was allowed fifteen seconds of its own, counted from the moment that read began and enforced by the network library rather than by this actor — so a connection that stalled without ever closing could run on past the point where your run had to be finished, and the platform stopped the run mid-read: no closing status line, no run-summary row, and no record of what was still left to fetch. Every read is now bounded by the run's own clock as well: it gets the smaller of its fifteen seconds and the time the run still has above what it needs to write your results, and this actor now ends the read itself rather than waiting on the network library to do it. A read the clock cuts is reported as the run timeout it is — "stopped before the run timeout with N results left" — never as Google having no data, so the results it did fetch, what was left, and why it stopped all still reach you. Rows already delivered are unaffected, a run with time to spare reads exactly as it did before, and nothing about your input, your columns, your events or your prices changed.

### 1.1.55 — 2026-09-13

- **This page now names the price DROP that lands on 19 September 2026, with its date.** Paid plans pay from $7.50 per 1,000 trend reports today; from 19 September 2026, 22:00 UTC that falls to $2.25 per 1,000 — the Apify free plan stays at $9.00 per 1,000 — and a report stops being one keyword on one surface and becomes one keyword's whole trend report: the timeline, the related queries, the region table and trending-now together, one report per keyword however many of those surfaces you ask for. Related topics bill on their own from that date at $7.50 per 1,000 on every plan. Both the headline price line and the comparison table say so, so the page is true on either side of that instant. Nothing about your input, your rows or your columns changes, and until that instant every run still bills exactly as it does today.

### 1.1.54 — 2026-09-13

- **A run that names the search-terms field in the singular now works, instead of coming back with nothing.** If you — or an AI agent calling this actor — send `searchTerm`, `keyword`, `keywords`, `term`, `query` or another obvious name for the same thing, those terms are now read and scraped as though you had used this actor's own field name, `searchTerms`, and the run log says which name you sent and which field was read. Until this build the platform passed the unrecognised name straight through, the terms were dropped, and the run answered that no search terms were provided — to someone who had provided them. If you set both names, everything you typed is kept and a term sent twice is still one result. Sending one of those names with nothing in it now says so, naming the field you set and the field this actor reads, instead of returning the sample rows. Nothing about money moved: no input field, output column, event or price changed, and the form still shows `searchTerms`.
- **The store description now says which surfaces a plain run delivers and which you ask for.** It listed interest over time, related queries, related topics, region breakdown, compare and trending now in one breath, as though a run with no surfaces named returned all six. It does not: a plain run returns interest over time, related queries and the region breakdown; compare, related topics and trending now are options you switch on, and related topics is billed as its own report rather than riding on the three default surfaces. The card now says so. Nothing else moved: no input field, output column, event or price changed, and every surface still works exactly as it did.

### 1.1.53 — 2026-09-12

- **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.

### 1.1.52 — 2026-09-12

- **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.
- **The store page now says how often to re-run, window by window.** It used to say only "schedule the run to repeat daily or weekly", which is the wrong advice for half the time ranges this actor takes: Google refreshes a 12-month answer about once a week, a daily window about daily, and the hour windows far more often, so a schedule that does not match the window you chose either buys the same report twice or misses the change you were watching for. The page now names the cadence for each window, and walks through setting it up — save the input as a Task, put the Task on a Schedule, add an integration on run succeeded — and names `fetchedAt` as the field to chart by when each run appends its rows to a sheet. The step-by-step list near the top points at the same place instead of repeating the flat advice.
- **The input form now opens with a description of the whole job, where it had none at all.** Above the fields you now get the one-line call that works, the 300-keyword cap, which three surfaces run if you name none, what a run costs at most and the never-charged rule, how to cap a run's spend, and what `geo`, `timeRange`, `compare` and trending-now do. This is also the screen an AI agent reads when it is deciding whether this actor can do the job — until this build that screen was blank.
- **Three pricing sentences now quote the ceiling rather than a fixed unit.** The input form and the store page said a result *equals* one keyword on one surface; what we actually promise is that you are billed *at most* that — where several surfaces for one keyword settle together as one report you pay less, which has always been true and is stated on the pricing section already. The wording now matches across the form and the page, and the page quotes the free plan's price rather than repeating a paid figure that belongs on the store header. No price, event, input field or output column moved.
- **A list of more than 300 search terms no longer refuses to start the run.** The 300-term cap lived in the input form itself, so sending 400 terms — from the API, from an integration, or from an AI agent handing over its whole list — did not start a run at all: you got a validation error, no rows, no status line and nothing to look at. The cap is still 300 per run. What changed is what a longer list does: the run now starts, uses the first 300, and writes one uncharged row saying how many you sent, how many it used, and that the rest was neither fetched nor charged — so you know exactly what to send in the next run. The same line appears on the run's status and in the run's ERRORS record. Nothing about what a run costs moved.
- This actor still keeps no memory of past runs, deliberately — a fresh fetch is the product. Nothing else moved: no input field, output column, event or price changed.

### 1.1.51 — 2026-09-11

- **A run that hits a busy Google window now waits once more before giving a term up.** When Google refuses a surface, the run pauses and tries that term again on a fresh connection instead of reporting it as unserved straight away. Until this build that pause could be cut short while Google was still refusing, and the term was given up a minute too early. Now, where the pause was cut short and the very next try is refused again, the run waits one further time — a little over a minute in total — and only then reports the term. Nothing else about the walk changes: a term Google answers, and a term Google says it has no data for, are both settled at once as before, and the extra pause only ever happens on a term that is being refused.
- **What you should see.** Slightly longer runs during the hours Google is busiest, and fewer terms coming back unserved in those same hours. A run still ends inside your time limit, still reports every term it asked for, and still ships the results it already has.
- **Charges are unchanged.** Only delivered results are charged, every uncharged row stays uncharged, and no wait is ever charged — a term the run waits for and still cannot get is reported uncharged, exactly as before. No price, event, input field or output column moved.

### 1.1.50 — 2026-09-11

- **A wording build: nothing about your runs changes, and there is no reason to re-run anything.** The store page and the input form now say plainly that **related queries is the surface Google most often has nothing for**. Google computes related queries only where a keyword carries enough search volume, so lower-volume terms — and any term narrowed to a smaller region or a shorter time window — frequently have none at all. That is Google's answer rather than a fault here: the keyword is reported as having no data on that surface, **nothing is charged for it**, and the run carries on through the rest of your list. Re-running the same term returns the same answer. Interest over time is charted for terms far below the level related queries needs, so keeping that surface selected is what gets you a trend line for a term related queries cannot answer. This is how the actor has always behaved; it was simply not written anywhere you could read it before buying.
- **A charted keyword that looks empty now says on the row that it was charged.** A term just above Google's volume floor arrives as a complete timeline that is mostly 0 — one measurable week and 52 zeros is a real Google answer, not a failed fetch. The note already on those rows said Google charted the term and the result was delivered; it now also says the result is charged as one, so a row that looks empty explains its own line on your bill. The row, its columns and what it costs are identical to before.
- **Two things that were already true, now easy to find.** A 12-month interest-over-time answer refreshes about once a week (daily windows about daily), so re-asking the same keyword sooner buys you the identical report — this actor keeps no memory of past runs by design, and the page says so under pricing. And where a run has already waited for Google to clear, the notice rows it ships ask you to re-run **later**, never "shortly": a row never advises minutes the run itself just spent.
- **Charges are unchanged.** Only delivered results are charged, every uncharged row stays uncharged, and no wait is ever charged. No price, event, input field or output column moved.

### 1.1.49 — 2026-09-11

- **A maintenance build: nothing about your runs changes.** The top of this actor's store page now 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 all four sat far enough down the page that one never reached them. Every word about what this actor does, what it returns and what it costs is unchanged.
- **The private run-report this actor writes for our own support** — counts only, never anything you typed — now also carries the per-event prices the run was billed at, so a run's own record says what it was charged instead of leaving it to be worked out afterwards. Nothing you can see moved: no input, no output column, no price, no event.
- **Charges are unchanged.** Only delivered results are charged, every uncharged row stays uncharged, and no wait is ever charged.

### 1.1.48 — 2026-09-10

- **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 — now says how many times a run waited for Google to clear before giving up on a keyword, how long those waits took, and how many of them ended in results. Until now those figures were left blank here, so a run that waited minutes and was still refused looked exactly like a run that never waited at all, and we could not tell whether waiting is helping you or only costing you time. Where a run genuinely cannot tell the two apart it reports nothing rather than guessing. Nothing you can see moved: no input, no output column, no price, no event, and the waiting itself behaves exactly as it did in 1.1.46.
- **Charges are unchanged.** Only delivered results are charged, every uncharged row stays uncharged, and no wait is ever charged.

### 1.1.47 — 2026-09-10

- **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.
- **Charges are unchanged.** Only delivered results are charged, every uncharged row stays uncharged, and no wait is ever charged.

### 1.1.46 — 2026-09-09

- **Waiting out a Google block is now sized by what the pending keywords are worth.** Since 1.1.44 a refused keyword got a patient retry bounded only by the run's clock; on a busy day that could mean minutes of waiting for a handful of rows. The wait is now bounded by the value of the rows still open — a small ask waits briefly, a large one longer — and a run that has delivered nothing yet always keeps one short retry, so a keyword Google refused early is still given a real second chance.
- **A run that stops waiting says so.** Where the wait ended because it was not worth more time, the row says the keyword was not served and asks for a later re-run, exactly as a waited row already did.
- **Charges are unchanged.** Only delivered results are charged, every uncharged row stays uncharged, and no wait is ever charged.

### 1.1.45 — 2026-09-09

- **When our own retry route has no exits for the Proxy country you chose, the run says so straight away.** Until now it waited minutes on that route and then reported the keyword as something Google did not serve. The row is uncharged, says plainly that the problem is ours and not Google's, and names the input that fixes it: set Proxy country to a nearby country, or leave it as US, and run the same input again.
- **A route that has no exits is dropped for the rest of the run.** One dead route now costs one result, not every result after it; the remaining results fall back to the next route.
- **The ERRORS record no longer quotes our transport's own wording.** It carries the same plain sentence as the notice row, marked not retryable.
- A run that holds nothing only because of our own route still finishes as a successful run rather than a failed one. Nothing else moved: no price, event, input field or output column changed, and only delivered results are charged.

### 1.1.44 — 2026-09-08

- **A run blocked before its first result now waits, instead of giving up in seconds.** Since 1.1.39 a run that had already delivered something and then hit a block would wait a minute or two, come back on a fresh connection and ask again. A run blocked on its very first search terms did not: it tried three times, gave up in about a minute and a half, and handed back "please re-run shortly" while almost the whole run was still ahead of it. That was backwards — a run holding nothing is the one with the most to gain from waiting. Those search terms now get the same patient retry the rest of the run already had, so a term that would have been reported as missing is often simply delivered.
- **The waiting is bounded, and it is never charged.** It only happens when Google actually refused, and only while the run still has the time for it. A search term Google charts nothing for, and a request Google refuses outright, are answers rather than blocks — they are still reported at once, with no wait, exactly as before. A run too short to wait behaves exactly as before.
- **A notice row no longer says "re-run shortly" about minutes the run already spent.** Where the run waited, the row says so and asks you to re-run later. Rows on runs that did not wait are worded exactly as they were.
- **Plainer wording where a run reports a block.** The run used to state that Google was rate-limiting, or that it had "blocked or answered empty". Neither is something the run can actually know — the same symptom covers a dropped connection on our side — so it now reports only what was seen: results did not come back.
- **A waiting run says it is waiting.** The progress line added in 1.1.42 now names the wait while it is happening, rather than still reporting that it is reading Google Trends.
- Nothing else moved: no price, event, input field or output column changed, and only delivered results are charged.

### 1.1.43 — 2026-09-08

- **The progress line counts two different things, and now says which is which.** 1.1.42's new progress line reported results delivered and progress through your list with one word for both — so a run part-way through its first search term read "1 result delivered so far, 0 of 6 results looked at", which contradicts itself and undercounts what has been done. Results and search terms are not the same unit: six terms across three surfaces is eighteen results. The line now reads "1 result delivered so far, 1 of 6 search terms looked at", and counts a term from the moment it is started rather than only when it is finished.
- Nothing else moved: no price, event, input field or output column changed.

### 1.1.42 — 2026-09-08

- **A running job now tells you it is alive.** This actor said nothing at all between its first few setup lines and the end of the run. Reading one search term takes several attempts across each surface you asked for, and when Google is rate-limiting it waits and tries again on a fresh connection — deliberately, and for minutes at a time. None of that reached your log: the lines describing it were written at a level the platform does not display. Nothing was wrong during that silence and the work was going ahead normally, 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, and how many results have been delivered so far. The same line now also appears on the run page beside the run itself, so you can see it 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.

### 1.1.41 — 2026-09-07

- **"Google Shopping" now works in "Search property", instead of ending the run.** The value this field has always taken for shopping interest is `froogle`, an old Google name for the service, while the form itself labels that option "Google Shopping". Typing what the form showed you ended the whole run before anything was measured. "Google Shopping" and "shopping" now reach it, and the same goes for the other options' own labels — "Image Search", "News Search", "YouTube Search" and "Web Search" all work, as do "google images" and "google news".
- **A property this actor cannot measure is still refused before anything is charged, and so is "all".** "all" could mean web search only or every property at once, and measuring interest on a property you did not name would read exactly like the right answer. This actor names the values that exist rather than guessing between two.
- Nothing else moved: no price, event, output column or charge changed, and only delivered results are charged.

### 1.1.40 — 2026-09-06

- **A block of links pasted into the search terms box now stops the run with a message instead of scraping it.** "Search terms" asks Google Trends about words. A whole block of links pasted into a single row used to be scraped as one term, which can only come back as an empty timeline. The run now ends immediately, uncharged, with a message saying how many links it found and that this box takes keywords, one per row.
- **Your search text is never split apart.** Only you know whether "red running shoes" is one search or three, so nothing is guessed — a row holding words rather than links runs exactly as before.
- Nothing else moved: no price, event, output column or charge changed, and only delivered results are charged.

### 1.1.39 — 2026-09-05

- **A surface Google walls part-way through a run is now waited out instead of abandoned.** If a term charted its timeline and Google then refused the related-queries or region call for it, the run used to give up on that half within seconds and hand back an uncharged "please re-run shortly" notice — with almost the whole run still ahead of it. It now waits a minute or two for the block to pass, comes back on a fresh connection and asks that surface again, once, before reporting anything as missing. Blocks like this usually clear inside the minutes the run already had.
- **An answer is still reported at once.** A term Google charts nothing for, and a request Google refuses outright, are answers — not blocks — so they are reported immediately with no wait, exactly as before. A run that is too short to wait, or that has already spent its maximum cost, also behaves exactly as before.
- **Nothing about charging changed:** a result that does not arrive is never charged, and the waiting itself is never charged.

### 1.1.38 — 2026-09-05

- **A keyword with no measurable region is no longer delivered — or charged — as a page of zeros.** Interest by region for a term Google has no volume for came back as every region at 0 (Google's own answer marks each one as having no data), and that was shipped as a delivered, charged row. It is now reported like the same term's empty timeline: named in `ERRORS` as a keyword with no data on that surface, and never charged. A keyword with real regional interest is untouched, and a **compare** run still ships every term's region row — there the numbers are a share of the comparison, so a term reading 0 everywhere is a real reading of that comparison and the row says so.

### 1.1.37 — 2026-09-05

- **A compared keyword Google has no volume for is no longer delivered as a line of zeros — or charged for one.** Run a thin term on its own and Google answers that it has nothing to chart, uncharged. Compare that same term against a strong one and the same nothing used to come back as a full timeline of literal 0s: a delivered, charged row, with a note that read "measurable in 0 of 53 weeks". It is now reported exactly as it is on its own — named in `ERRORS` as a keyword with no data on that surface, never charged — while every other term in the comparison keeps its row. A keyword that Google charts even once in the window is unchanged: that is a delivered result, and its note still explains the shape.
- **Compared region rows now say what their numbers mean.** Under **compare**, `interestByRegion` scores each region as your keywords' SHARE of the comparison, not each keyword's own level — so a much bigger term reads close to 100 in nearly every region and a smaller one close to 0. That is the comparison working, and the row now says so in `data.note`. Run the terms without compare to get each one's own regional spread. Nothing about what is delivered or charged on those rows changed.
- **The store page says the same thing** — what `sharedScale: true` does to the numbers, and when to run terms separately.

### 1.1.36 — 2026-09-05

- **A keyword that delivers one surface and gets nothing on another is now reported for both.** If you asked for interest over time and related queries and Google charted the timeline but had no related queries for that term, the run used to deliver the one row and say nothing at all about the other: the result you asked for simply was not there, with no entry, no count and no line about it. It is now reported like any other result Google had no data for — named in `ERRORS` with its keyword AND its surface, counted on the status line, and never charged. Nothing that was delivered changed, and nothing about what is charged changed.
- **Everything the run reports is now counted in the same unit you buy in: one result = one keyword × one surface.** So the arithmetic closes on every run — results asked for = results delivered + results reported as having no data, blocked, or not attempted. The status line says "N results with no data" where it used to say "N keywords".
- **Compare runs now say which surfaces they left out.** Related queries and related topics are per-keyword surfaces with no shared scale, so a compare run has always dropped them; it now records that, uncharged, in `ERRORS` with the reason and what to do instead, rather than leaving a silent gap between what you selected and what arrived.
- **The `ERRORS` record is described for what it holds** — everything you asked for that did not arrive, none of it billed.

### 1.1.35 — 2026-09-05

- **A keyword Google has no data for is now named in the run's `ERRORS` record.** That answer used to live only in the run's status sentence, so a run whose keywords were all below Google's volume floor finished SUCCEEDED with an empty dataset and nothing your code could read to see which keyword it was — while this page said the answer was reported in `ERRORS`. It is now: one entry per such keyword, carrying the keyword, the region, the time window, the surfaces you asked for, `"charged": false`, and a plain sentence saying Google answered and had nothing to chart. Nothing about what is charged changed — that answer was never billed and still is not, and it is never presented as something to re-run.
- **The status line points at the record.** A run with keywords Google had no data for now reads "… keywords with no data — not charged, see ERRORS". Where the run ships uncharged notice rows instead, the line still points at the rows, as before.
- **The store page and the console labels say what actually happens.** The `ERRORS` record is described as what it is — failed fetches and keywords with no data, neither ever billed.

### 1.1.34 — 2026-09-05

- **A run that hits a broad Google rate limit mid-list now waits it out instead of stopping.** When Google refuses several keywords in a row and the run has delivered nothing yet, it used to stop at the fifth refusal — often two or three minutes into a ten-minute run — leave the rest of your list unattempted, and ask you to re-run shortly. A run with time in hand now pauses for a couple of minutes, tries the refused keywords again, and carries on with your list when Google answers. The wait is bounded: never past the run's own timeout, never more than eight minutes in total, and never more than half the time the run had left when the refusals began. A run too short to hold a wait stops exactly as before. A short list refused from start to finish gets the same second chance.
- **Keywords Google answers as having no data are still answered at once** — they were never part of a rate-limit wave and they never wait; neither does a request Google refuses outright.
- **The status line says whether the run waited.** A wave that did not clear after the wait reads "waited N minutes, it did not clear" and asks you to re-run later, not shortly; a run that could not wait keeps its old words. Nothing is charged for a keyword that was not delivered, as always.
- **A keyword charted at the edge of Google's volume floor now explains itself.** A term just above the floor comes back as a complete timeline that is mostly 0 — Google measured it and found interest in only a few weeks. That row is a delivered result, and it now carries a short note in `data.note` saying how many periods were measurable, so a mostly-zero timeline is never mistaken for a failed fetch. Nothing about what is charged changed.
- **This page now says how often an answer refreshes** — a 12-month interest-over-time report about weekly, daily windows about daily — so you can schedule repeats to the window instead of re-buying the identical report.

### 1.1.33 — 2026-09-04

- **Change a setting but name no search terms and you now get the sample rows, not a note asking for terms.** An API call with no input at all always returned the frozen sample rows — a real `bitcoin` capture for the United States over the last 12 months, returned without contacting Google. Changing one thing first — narrowing the surfaces, setting the proxy country, picking the United States yourself — used to cancel them: you received one uncharged note asking for search terms and no rows at all. Narrowing a setting made the run worse than touching nothing, which is backwards. The sample rows now come back **under** what you set, wherever the capture can honestly answer under it.
- **A setting the frozen rows cannot honestly answer under still gets the uncharged note — and the note now names the setting.** Another location, another time window, another category, another search property, or compare on: returning a United States "bitcoin" capture wearing your setting's name would be the wrong data, so it is refused rather than relabelled, and the note says which field to fix and how to get live data instead. It never repeats the value you typed back at you.
- **Narrowing the surfaces narrows the sample.** Ask for interest over time alone and you get that one row. A surface the frozen capture does not hold — related topics — is named rather than silently dropped.
- **The rows themselves say what settings they ran under**, and the run's status line names them too.
- **Nothing about the daily `{}` run changed.** The same three rows, the same charge, the same words.

### 1.1.32 — 2026-09-04

- **A keyword with too little search volume no longer stops the rest of your run.** Google answers a long-tail term below its volume floor with a complete, empty answer. The run used to read that as upstream trouble, retry it on three routes, and — after a few such terms in a row — stop early saying Google was rate-limiting broadly, leaving the rest of your list unattempted. It is now reported as a keyword with no data, never charged, and the run works through your whole list. A real rate limit, a blocked route and a torn answer are unchanged: still retried, still able to stop a run early.
- **A trending-searches feed that answers with nothing published is reported as that, not as upstream trouble.**
- **The run status line names the keywords Google had no data for**, and a run whose only outcome is that answer no longer asks you to open an issue about it.

### 1.1.31 — 2026-09-04

- **An unexpected error while collecting trending searches no longer ends the whole run.** It is reported as that one unit's miss, and everything the run had already delivered stays delivered and charged as it was.
- **A run refused for an input mistake now tells us which field was refused** — 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.

### 1.1.30 — 2026-09-04

- **A region or category Google does not recognise is now told to you as such.** When Google refuses the request outright, the run used to retry it on three different routes and then report it as temporary upstream trouble with "please re-run shortly" — for an input that would have been refused again every time. The row now says the request was refused, names the region and category fields to check, and the run still costs nothing. A genuine rate limit, an empty answer and a server error are unchanged.

### 1.1.29 — 2026-09-04

- **A run that stops before it starts now reports its outcome too** — a run refused for its memory setting, and a run given an input it cannot act on, now reach us the same way every other run does: counts and reason codes only, never your input or your rows.

### 1.1.28 — 2026-09-04

- **The zero-network sample run and the ledger-blocked exit now report their outcome too** — the run record reaches us on those paths as well.

### 1.1.27 — 2026-09-04

- **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.

### 1.1.26 — 2026-09-04

- **A mistyped input field no longer pushes the run's own counts off the page.**
- **Run status lines fit the run page again; sample-run wording shortened.**

### 1.1.25 — 2026-09-04

**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, stop before the end, or stop the run outright as a precaution. 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.

### 1.1.24 — 2026-09-04

- **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.

### 1.1.23 — 2026-09-03

The two screenshots on this page now load from Apify's own storage instead of an outside website, and the opening line names Google Trends in plain text rather than linking to it. Same pictures, same words, same page. Nothing about what this actor delivers or charges changed.

### 1.1.22 — 2026-09-03

The comparison table on this page no longer links out to another vendor's website. The row still names the product and quotes its listed price, read on the date shown, exactly as before. Nothing about what this actor delivers or charges changed.

### 1.1.21 — 2026-09-02

The suite blocks at the bottom of this page now state the three delivery-conditional fees that start 16 September 2026 on sibling actors — keyword volume's fresh lookup, profile posts' profile lookup, and Google Jobs' search fee. This page also now says "nothing charged for starting a run" wherever it used to say "no start fee" — the same promise, in the words the whole shelf uses. Nothing changes on this actor: same price, same events, same rows.

### 1.1.20 — 2026-09-01

This page now opens with what you get and what it costs, shows the input form and a real result table, and compares this actor with the alternatives on public numbers. Nothing about what this actor delivers or charges changed.

- **What you get, then what it costs, then the guarantee.** The first screen used to lead with the no-charge-on-miss promise; it now leads with the data — the surfaces, the row shape, today's price — and keeps the promise where it belongs, right after.
- **Two real screenshots.** The input form, and the dataset table from a real run (`bitcoin` and `ethereum`, three surfaces, US, past 12 months) — so you can see the output before you run it.
- **How it compares.** A table of the alternatives — Apify's own Google Trends scraper, the most-used third-party one, SerpApi and pytrends — on listed price, what one unit is, whether platform usage is billed on top, start fees and public success rates, all read on the date shown.
- **The trending-now row shape, stated exactly.** Keyword rows carry the full eleven-field envelope; trending-now rows carry five (`schemaVersion`, `surface`, `geo`, `fetchedAt`, `data`) because a trending feed has no keyword or time range. This page used to say every row carried the same envelope; it now says which rows carry which.
- **Suite links carry the current names** of every steadyfetch actor, and the MCP snippet uses the current `tools=` form of the server URL.

### 1.1.19 — 2026-08-31

Sending `null` for a setting you do not want now means "use the default", instead of stopping the run before it starts.

- **An optional setting sent as `null` now takes its default.** Agents, n8n templates and MCP callers routinely fill every field in a template and send `null` for the ones they have no value for. Until now Apify refused those runs before the container even started — you got a validation error, no run and no rows, and the fix was to know that you had to leave the key out entirely. Every setting on this actor now accepts `null` and reads it as "use the default", which is exactly what omitting it does.
- **`searchTerms` sent as `null` returns the sample rows.** That is what leaving the field out has always done, and the two now behave identically. An explicitly empty list still asks you for terms — sending `[]` is a choice, sending `null` is not.
- **The Search property field now also accepts a value typed straight in.** It is still the same dropdown with the same five properties, but it no longer refuses anything else outright — which is what let it accept `null`. A value that is not one of them is still refused, uncharged, and the message now names the ones that work; before, Apify refused it with a generic validation error. Nothing is ever quietly measured on the wrong property.

### 1.1.18 — 2026-08-30

The linked example dataset is re-shot from a run of the current build. Nothing about what this actor delivers or charges changed.

- **The example dataset now shows exactly what a paid run returns today** — the three `bitcoin` surfaces worldwide (each row reading `"geo": "worldwide"`) plus the US trending-now feed, 13 rows, unedited. The output table on this page quotes that run.

### 1.1.17 — 2026-08-30

Worldwide rows now say so, and the run's own summary row is in place for the day it can ship free of charge. Nothing about what this actor charges changed.

- **A row from a run with no location set now reads `"geo": "worldwide"` instead of an empty string.** A blank in that column could not tell you whether the run was worldwide or the field had failed; the word can. Your input is unchanged — leave `geo` empty for worldwide, exactly as before.
- **The uncharged run-summary row, held until it can be free.** Every steadyfetch actor ends its dataset with one uncharged `_summary` row — how many results were delivered, exactly what was charged, and why the run stopped — that reconciles against the rows above it. On this listing's current billing every row written to the dataset is a charged result, so that row is deliberately not written yet rather than charged to you. It will appear, uncharged and last, as soon as the listing's billing can carry a free row; nothing in today's datasets changes.

### 1.1.16 — 2026-08-30

Related topics now tells you the one thing worth knowing when it comes back empty, and no failure message describes machinery instead of your result. Nothing about what this actor delivers or charges changed.

- **A related-topics result that does not arrive now says what to do about it.** Google meters its topics feed and serves it to a limited number of lookups at a time, so this one surface can come back empty on a busy moment. The report used to describe the refusal in our own terms and offer generic advice — narrowing an input, which recovers nothing on a single-keyword topics run. It now says plainly that related topics is a live surface that normally delivers, that nothing was charged, and that running the same input again a minute or two later normally works. This actor's own runs bear that out: the surface delivered real topic entities the same day.
- **The related-topics caveat is now stated on this page, before you buy.** The listing sold the surface without mentioning that a lookup can come back empty. It is the only surface here with that caveat, and it is now written into the table, the surface's description in the input form, and the FAQ — along with the fact that an empty topics lookup is never charged and never shipped as an empty row.
- **Failure reports describe your result, not our retry machinery.** The report attached to a run said how many fetches "failed after retries", described "empty payloads" and "degraded answers", and labelled every entry with an internal word. It now names what did not arrive, whether running again is worth your time, and where the detail is — using the same three-word vocabulary the rest of this suite uses.

### 1.1.15 — 2026-08-30

This page's wording refreshed — what happens on a blocked or empty fetch is now described more plainly. Nothing about what this actor delivers or charges changed.

### 1.1.14 — 2026-08-30

Clearer release notes — this page's notes now read more plainly. Nothing about what this actor delivers or charges changed.

### 1.1.13 — 2026-08-30

Suite links now point at the full live shelf — every actor named in this README is a live
store link. Nothing about what this actor delivers or charges changed.

### 1.1.12 — 2026-08-30

Review-fix build: what you are charged and what your dataset shows now agree in every failure the platform can produce.

- **A result that fails to save no longer leaves its billing record behind.** When results were fetched but the dataset save failed, the run's own books still marked that keyword as delivered and billed — so when another surface later delivered the same keyword, its rows could ship with an incomplete billing record and the run's accounting disagreed with the dataset. The books are now written only after the save lands: a failed save is still reported exactly as before, nothing is marked done, and every row's billing record matches what actually reached your dataset.
- **A resumed run that cannot trust its own delivery record now stops rather than charging again.** Right after a run is moved or resurrected, the dataset read-back can momentarily lag behind what has already been charged. A run that trusted such a read would start the work over — fetching, delivering and charging a second time for results you had already paid for. It now notices that its charges exceed what the record shows, stops cleanly without charging anything more, and says so. Re-running once the record has settled carries on normally.
- **A pricing record that momentarily lists no billable event can no longer be spent against.** While a pricing change rolls out there can be an instant where nothing on the listing is billable at all. Such a run used to read its budget as unlimited and could work through your whole input; it now stops before spending anything, says the pricing record needs fixing, and never stamps a row as charged. The two normal in-between states of a pricing rollout are unaffected and behave exactly as before.

### 1.1.11 — 2026-08-29

An answer with nothing in it is no longer a row, and a run that stops early now tells you exactly what is left.

- **An empty related-queries or related-topics answer is no longer delivered or charged.** Google sometimes answers a related request with a well-formed reply that carries no queries and no topics at all. That reply used to become a row in your dataset — an empty `top` and an empty `rising` — and it was charged like any other result. It now delivers nothing and costs nothing. Under the current pricing that simply means the row does not appear; the keyword's other surfaces are unaffected and still deliver normally.
- **A run stopped by your cost cap during Trending now no longer says "0 results left".** When your maximum cost per run cut the trending feed short, the status line reported nothing left to fetch — telling you a raised cap would buy you nothing. It now reports the exact number of trending results the cap left behind, so "raise Maximum cost per run to fetch everything" means what it says.
- **An input field name this actor does not recognise is now named back to you, even when the run still has work to do.** Sending a typo like `searchTerm` alongside Trending now, or a misspelled setting beside real search terms, used to be silently dropped: the run did the part it could read and never mentioned the part it could not. The run still does that work, and the status line now names every field it did not recognise so you can see what was ignored.
- **Related topics will be billed as its own kind of report.** Related topics costs us considerably more to fetch than the other surfaces, so it is being separated from the general trend report onto its own event rather than being averaged into everyone's price. Nothing on your bill changes until the actor's pricing record lists that event, and Apify notifies every pricing change in advance — until then, related-topics rows are delivered without a separate charge.

### 1.1.10 — 2026-08-29

Related topics is now a real surface — delivered rows, never empty ones.

- **New opt-in surface: `relatedTopics`.** Add it to `surfaces` to get the related topics for a keyword — the top and rising topic entities, each with its knowledge-graph id (`mid`), title, type, score, and explore link, in the same schema-stable row envelope as every other surface. It is opt-in and stays out of the default surfaces, so existing runs and their costs are unchanged. In compare mode it is per-keyword (no shared scale) and is left out, exactly like related queries.
- **Why it was not offered before, and what holds now.** Google withholds the topics feed from most automated sessions — the reason this actor previously declined to sell the surface, and the reason tools that do sell it typically ship empty topics lists. This release fetches topics in a way Google actually answers. When Google still withholds or rate-limits a topics fetch, it is retried on a fresh connection and, if it cannot be delivered, it is reported in `ERRORS` and never charged — an empty answer never becomes a row in your dataset.

### 1.1.9 — 2026-08-29

An empty answer we could not confirm is now something to re-run, never a verdict on your keyword.

- **An empty reply that survives every retry is no longer reported as "no data for this keyword".** Google sometimes serves a valid-looking but empty reply when it is struggling, and from the outside that reply is indistinguishable from a keyword that truly has no data. A keyword whose every fresh attempt came back empty used to be given a definitive "Google Trends returned no data in the selected time range and region" plus advice to change your input — a temporary problem described as a permanent one. It is now reported as a temporary, uncharged miss that asks you to re-run shortly, and only suggests broadening your input if it keeps happening.
- **A broad wave of empty answers now stops the run early with re-run guidance.** When several keywords in a row come back empty and nothing has been delivered, the run stops and says so — the same early stop a broad rate-limit wave already gets — instead of working the whole list and blaming every keyword. The stop message and the nothing-delivered message now name empty answers alongside rate limits, so the status always describes what actually happened.
- **A preparation step that answers incompletely is retried instead of surfacing an unclear failure.** Each surface needs a small preparation step before it can fetch data. When that step comes back well-formed but incomplete, it is now recognised as the same temporary degradation as an empty data reply and retried on a fresh connection; previously it could surface as an unclear error, and a run that delivered nothing because of it could read as failed.

### 1.1.8 — 2026-08-29

- **A typo in an input field name now gets a helpful pointer instead of sample rows.** Apify ignores any field an actor does not declare, so an input like `{"keywords": ["bitcoin"], "geo": "GB"}` used to look exactly like a run with no input at all and came back with the frozen sample rows — reading as if the typo had worked. Such a run now stops immediately, uncharged, with a message naming the field it did not recognise and naming `searchTerms` as the field you meant. Sending only settings — a location, a time range — with no search terms gets the same pointer. A run with no input at all still returns the sample rows exactly as before, and a run that does carry search terms is unchanged, unknown field beside it or not.
- **A bad value is now always reported, even when no search terms came with it.** An unusable `timeRange` or an unknown entry in `surfaces` sent without search terms used to be answered with sample rows and never mentioned; that run now stops with the message explaining the value, as it already did whenever search terms were present.

### 1.1.7 — 2026-08-28

- **The run status speaks one vocabulary.** A run that stops early — at your cost cap, at the timeout, or during a broad Google rate-limit wave — now tells you what is left in the same terms the rest of the status and the pricing use: results, one keyword × one surface. Previously the same message mixed "results delivered" with "units left". The count is exact: anything already delivered, including by an earlier server before a migration, is never counted as left, and a not-yet-fetched Trending now feed is named rather than estimated as a number.

### 1.1.6 — 2026-08-28

- **Fixed: retries of rate-limited requests work again.** The fresh connection used to retry a request Google had rate-limited could be rejected by an internal naming check before it ever reached Google, so that retry failed instantly instead of fetching your data. Affected fetches were reported as failed and were never charged; they now retry as designed.

### 1.1.5 — 2026-08-28

- **Runs now stop cleanly at your time limit instead of being cut off.** When the time left in a run is no longer enough to safely finish the next fetch — including its retries and cool-downs — the run ends on its own with an honest partial status ("stopped before the run timeout with N unit(s) left") instead of being killed mid-fetch by the platform timer. Everything already delivered stays in your dataset, and nothing undelivered is charged.
- **The sample run no longer depends on Google's mood.** Running the actor with no search terms now returns a small frozen sample — real rows from a "bitcoin" capture, one per surface — that shows the exact output shape without contacting Google at all. Put your own keywords in `searchTerms` to fetch live data. A trending-now-only run no longer also fetches the sample keyword.

### 1.1.4 — 2026-08-27

- **Interest by region is never delivered — or charged — as an empty answer.** Google sometimes replies to a by-region request with a valid but empty result. That reply used to be accepted at face value: the run delivered a row whose region list was empty, and charged for it. It is now recognised for what it is, retried on a fresh connection, and if Google still will not answer, the keyword is reported as an uncharged miss instead. The other surfaces already worked this way; by-region was the last one that did not.
- **A run no longer ends on an unclear error when Google rate-limits the retry itself.** The fallback used to set up its retry outside the normal retry path, so a rate-limit hit during that step escaped as an unexplained failure rather than being retried like every other rate-limited request.

### 1.1.3 — 2026-08-27

- **Faster runs, same price.** Requests now go out on the run's own connection first and only fall back to a fresh identity to retry something Google rate-limited. In our own measurements every rate-limited request retried that way came back with data on the next try. Typical runs finish noticeably quicker; what you pay per result is unchanged.
- **An interrupted run no longer repeats itself.** If Apify moves your run to another server mid-way — or you resurrect a finished run — it now recognises the results already sitting in your dataset. Nothing is fetched twice, no duplicate rows appear, and nothing is charged twice. If a charge was interrupted after a result was delivered, the run settles that one charge and only that one.
- **A run moved between servers keeps its original time budget** instead of starting a fresh one, so a long job cannot quietly run twice as long.
- **A "Maximum cost per run" that affords exactly one result now delivers that one result**, instead of stopping with nothing and asking you to raise a cap that was already enough.
- The **Proxy country** field now describes what it actually does: it applies only to the connection used to retry a rate-limited request. Most runs never need it.
- The suite directory now links the sibling actors that have gone live.

### 1.1.2 — 2026-08-27

- A run no longer stops dead if saving results or recording a charge fails part-way through. It now finishes with a clear status, the rows already delivered stay in your dataset, and nothing undelivered is ever charged — the details land in `ERRORS`.
- Delivery and billing problems on our side are now reported separately from failed fetches, so a run that did deliver your rows never reads as "the fetch failed". A "no data from Google" notice row is no longer written when the problem was ours.
- Keywords that Google genuinely answers with no data no longer count toward the "Google is rate-limiting broadly" early stop, so a list that starts with a few empty keywords is now worked all the way through. A real rate-limit wave still stops early exactly as before.
- README: added the unofficial / not-affiliated-with-Google note, and refreshed the directory of the other steadyfetch actors.

### 1.1.1 — 2026-08-27

- Fixed: a compare run started from the form's default surface selection no longer fails. Compare now returns the surfaces that share a 0–100 scale — interest over time and interest by region — and skips related queries, which is per-keyword and has no shared scale. Related queries stay available in a normal (non-compare) run.

### 1.0.13 — 2026-08-27

- The README now opens with an **Output** section — a table of real rows from the live example run, the compare screenshot, and the full JSON envelope — so you can see exactly what a result looks like before spending anything.
- Added a copy-and-paste block for AI agents and LLM clients: the actor id, a complete input example with every option explained, the output fields, and the event price.
- Clearer compare-mode guidance: related queries is a per-keyword surface with no shared scale, so leave it out of a compare run and fetch it in a separate run.
- New directory of the other steadyfetch actors — Facebook, Google Ads, TikTok, LinkedIn and Instagram Reel transcripts — with their free n8n templates.

### 1.0.12 — 2026-08-21

- Billing accuracy improvement for runs with a **Maximum cost per run**: capped runs now deliver every result the cap affords — a rounding quirk could previously stop one result early.

### 1.0.11 — 2026-08-19

- Documentation: pricing examples updated to the current paid-plan tier prices.

### 1.0.10 — 2026-07-30

- Runs started with memory outside the tuned range (256 MB–2 GB) now exit immediately with clear guidance — nothing charged. Normal runs are unaffected; the input form already uses the right range.
- The default run memory is now 256 MB (was 512) — validated side-by-side with identical results. Pricing is per-result and unchanged.

### 1.0.9 — 2026-07-29

- When Google is rate-limiting broadly, zero-result runs now stop early with clear retry guidance instead of slowly working through the whole keyword list. You're charged nothing either way — this just saves time.
- The status message for zero-result runs now reflects all-inclusive pricing correctly: such runs cost you nothing at all.
- Every run now finishes within a bounded time window, regardless of custom timeout settings — no more runs that linger.
- Search terms are capped at 300 per run (documented in the input form); split larger lists across runs.
- Quieter run logs: transient retry chatter moved to debug level.

### 1.0.8 — 2026-07-29

- Runs with a tight **Maximum cost per run** now keep a little more headroom near the cap, removing rare cases where the platform could abort a capped run right at its ceiling instead of the run stopping cleanly with a "raise your cap" message. Nothing changes about what you're charged.
- Pricing docs updated: the transitional notes from the July 19 all-inclusive change-over are gone — one flat price per result is simply how it works now.
- The default run timeout is now 10 minutes (was 60). Typical runs finish in well under two; large batches can raise the timeout in run options as always.

### 1.0.7 — 2026-07-05

- **Pricing becomes all-inclusive on July 19, 2026** (announced to all users): platform usage will be included in the event price — one flat, predictable price per result, no separate usage line, and retries for failed fetches cost you nothing at all.
- The run-budget logic now follows the actor's active pricing model automatically: under the new pricing, runs with a **Maximum cost per run** deliver the full number of results the cap affords (the old model's usage headroom no longer applies once usage stops being billed separately).
- README pricing section updated for the transition.

### 1.0.6 — 2026-06-16

- A run that returns no results **only because Google rate-limited or blocked every request** now finishes as a **successful** run (no result fee charged) with a clear "please retry shortly" message — instead of failing. You never pay a result fee for a run that delivered nothing, and genuine errors still fail loudly so you notice them.
- Runs that reach your **"Maximum cost per run"** now always stop cleanly with a "raise your cap to fetch everything" message instead of being aborted mid-run.

### 1.0.5 — 2026-06-16

- Input mistakes no longer fail the run. A cleared keyword, an invalid `timeRange`, a wrong compare-term count, or any other input-validation error now produces a **SUCCEEDED** run that charges nothing and writes a clear `INPUT_GUIDANCE` record to the key-value store telling you exactly what to fix — instead of a FAILED run. Genuine internal errors still fail loudly; nothing is ever charged on an input-error run.

### 1.0.4 — 2026-06-12

- Zero-input runs (platform automated health checks, bare API calls) now run the bitcoin demo instead of failing: `searchTerms` and `surfaces` gained schema `default` values — `prefill` alone is form-only and is not submitted on empty input.

### 1.0.3 — 2026-06-11

- Listing screenshots (input form, multi-keyword compare output).
- Second live sample dataset: 4-keyword compare (chatgpt / claude / gemini / copilot) on one shared scale.

### 1.0.1 — 2026-06-10

Initial release.

- All working Google Trends surfaces in one schema-stable JSON: interest over time, multi-keyword compare (2–5 on a shared scale), related queries (top + rising), interest by region, trending now (with traffic estimates and news links).
- Reliability engineering: rotating sessions, fail-fast timeouts, bounded retries with cooldowns, proactive session rotation.
- Detects Google's valid-but-empty degraded replies and retries instead of delivering empty rows; failed fetches are reported in `ERRORS` and never charged.
- Budget-aware: stops cleanly at your max cost per run and before the run timeout, always reporting exactly what was delivered and what remains.
- Related topics intentionally not offered while Google's topics feed returns empty data platform-wide.
