# Changelog of Google News Scraper — News by Query, Exact Limit, No Start Fee (`steadyfetch/google-news-rss-scraper`) Actor

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

## Changelog

### 1.0.21 — 2026-11-02

- **Plainer, truer words when Google News does not send the articles for a search, answers with none, or answers with something we cannot read.** Each of those rows and the run message now say what Google News did and what to do next, with no technical codes, and nothing changes about what is delivered, what is charged, the price or the input fields.
- **A search whose news list holds more articles than one run reads now shows false in the "Worth a re-run" column (retryable), where it showed true.** Running it again gets the same answer, so neither that row nor a Standby answer holding only that row asks you to try again, and the row is still not charged.

### 1.0.20 — 2026-10-27

- **A delivered article now costs $2.80 per 1,000 on Bronze, $2.40 on Silver and $1.60 from Gold.** This is the change announced on 13 October, in effect since 27 October 2026 at 08:43 UTC. The Apify free plan stays at $3.20 per 1,000, and the query check stays at $0.002. The README, the price table and its worked examples, the store description and the input description now quote it.
- Which rows are charged, the input fields and the output columns are unchanged, and anything we could not deliver is still never charged.

### 1.0.19 — 2026-10-22

- Rebuilt on the patched Node runtime (no code change).

### 1.0.18 — 2026-10-20

- **This actor now also answers plain HTTP requests (Standby).** An app or an AI agent can send the same input a run takes to `https://steadyfetch--google-news-rss-scraper.apify.actor` and get the article rows, the row per search or section and the receipt back in the response, charged per article and per Query check exactly as a run with that input. A request carries no account memory, so it cannot skip the articles you already have; schedule a run for that. Runs keep the price, which rows are charged, the input fields and the output columns as they were.
- **An article you already paid for is no longer charged again after several of your runs finish at the same moment.** When runs on one account ended together, an article one run had just remembered could be forgotten, and a later run delivered and charged it again. At the end of each run the memory now checks that its last write landed and puts it back if it did not; that check adds well under a second to most runs.
- **An article your account received in the last 90 days is no longer charged again once your account memory passes 50,000 entries.** Until now that memory kept only its newest 50,000 entries and quietly dropped the oldest, so a busy account could be charged a second time for an article it already had well inside the 90 days. The memory now keeps every entry for its full 90 days however many there are, and large memories load and save much faster: a run now saves only the newest part, older entries are kept in separate records that are written once, and your existing memory is moved to the new layout the first time a run saves to it, with nothing in it lost.

### 1.0.17 — 2026-09-26

- **A run cut off before it finishes is now accounted for.** The run now notes its own start in its internal record, so a run that ends without finishing — a hard abort, a crash or a timeout — is still accounted for on our side. Nothing changes about what is delivered, which rows are charged, the price, the input fields or the output columns.

### 1.0.16 — 2026-09-24

- **The `queries` field is no longer marked required in the input form.** An AI agent or API call that leaves it out gets the same sample run a bare Start always gave, and one that sets it gets the articles for its searches, exactly as before. No price, input field, output column or charged event changed.

### 1.0.15 — 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.0.14 — 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.0.13 — 2026-09-22

- **With "Skip articles you already have" switched off, the articles you already had now come back uncharged, as the setting always said.** The setting promised that repeats are "delivered again anyway, marked repeat: true, and still not charged", and each repeat row said "at no result fee" — but the run was charging each one as an Article. Now a repeat carries no charge, and your cost cap only stops the run at the first new article it cannot pay for. New articles and the Query check are charged exactly as before. No price, input field, output column or charged event changed.

### 1.0.12 — 2026-09-19

- **The whole "Maximum cost per run" you set is now spent on news items; before this build the run held back about a twelfth of it.** Your cap pays for news items and nothing else — the compute, the proxy and the data behind the run are ours, not yours — but the run was still reserving roughly 8% of your cap against those costs before it planned a single news item. So a cap worth ten news items bought nine, and the tenth was money you had authorised and could not spend. That reserve is gone. A run at its cap still ends the same honest way it always did: it stops itself, tells you what it cut and why, and charges you for nothing it did not deliver. No price, input field, output column or charged event changed.

### 1.0.11 — 2026-09-18

- **The run page keeps what you were not charged for, even on its longest lines.** When the status line ran out of room it used to drop those sentences one at a time — over the 360 endings a run can have, the "delivered once, not charged twice" count went on 309 of them, the short-feed count on 168 and the "you already had" count on 116 — while the 90-character "open an issue" line survived every one of those cuts. Now the three counts fold into a single sentence naming the total and pointing at the receipt row, which breaks each kind down, and the support ask is what gives way first.

### 1.0.10 — 2026-09-16

- **A country's three-letter code now works in "Country".** The full English name, locale tags and the everyday spellings ("India", "United Kingdom", "uk", "en-US", "Holland", "UAE", "Türkiye") have been read for a while; the three-letter ISO code had not, so "IND", "GBR" or "USA" was refused — and a refused country stops the whole run's edition. It is read now, and the refusal row lists it among the forms that work. Nothing else about the field changed: a value that names no country is still refused rather than swapped for another country or quietly defaulted, and a spelling can only ever land on a country the actor's own table already carries. No input field, output column, charged event or price changed.

Every entry here is one build on the Builds tab, 1:1, newest first. Prune convention `one`.

### 1.0.9 — 2026-09-16

- **The "Topics" field now says that a section name it does not know is never charged, early enough to be read.** That promise sat at the end of a long field description, past the point an AI agent’s tool screen cuts the text, so an agent choosing between the topic box and the search box could see the eight sections but not the assurance that a wrong one is answered rather than billed. The field now opens with an example section and puts the never-charged sentence second. The description at the top of the form also gained a routing line, saying where to go for how often a term is SEARCHED rather than what is published about it. Nothing about what is collected or charged changes.

### 1.0.8 — 2026-09-15

- **A run that is nearly out of time now stops with your rows and your receipt, instead of being cut
  off mid-fetch.** Each read of Google News was allowed its own 30 seconds no matter how little of
  your run timeout was left, so a run with 16 seconds to go could still start a read that ended 14
  seconds past the timeout — and the platform stopped the container while it was still waiting.
  Everything the run owed you at the end went with it: the summary row, the run page's own count,
  and the honest "we stopped here" line. A read is now given the smaller of its own 30 seconds and
  the time the run actually has left above what writing the results needs, so the run ends on its
  own terms: the articles already collected are delivered, the ones it did not reach are listed as
  stopped by the run timeout and carry no fee, and the receipt lands. The same bound now covers the
  sample a bare Start returns. A run with time to spare reads exactly as it did before. No price,
  input field, output column or charged event changed.

### 1.0.7 — 2026-09-14

- **A run that collected nothing now tells you what to put in the box, and says the reason in words
  rather than in our own shorthand.** A run whose only fault was a value this actor could not read
  said "Delivered 0 articles of 1 asked for across 1 input. Not delivered: 1 input error — none
  charged." That named a cause, in a vocabulary that is ours and not yours, and said nothing about
  what to do about it. The count now reads as a sentence — "1 from a value this run could not
  read" — and on a run that delivered nothing the page adds one plain next step for the biggest
  cause: the box to use and a working search term to copy, the eight section names that work and
  where anything else belongs, what a feed that carried no article means, and which of those a
  second run would change. A feed that would not answer at all, and a page this build could not
  read, are still never reported as "no news" — neither knows whether there is any. A run that did
  deliver is unchanged. No price, input field, output column or charged event changed.

- **The store page now shows a real article row before you spend anything.** The page described every column and never showed one, so the only way to see what you were buying was to run it. A real delivered row — headline, Google News link, Google's own article id, the ISO publication time, the publisher and how many outlets carried the story — now sits on the first screen, straight after the price, built by this actor's own parser from a harvested Google News feed. No price, input field, output column or charged event changed.

### 1.0.6 — 2026-09-14

- **A run started with a scoped API token now says why it could not skip what you already have.**
  The "already had it, not charged again" check lives in a key-value store in your own account, and
  an API token limited to "Restricted access" without key-value store permission cannot open it —
  so articles you already had were charged a second time and nothing said so. The run page now names
  the cause and the exact fix, the first row of the dataset carries the same sentence, and the run
  log says it too. Give the token key-value store Read, Write and Create, or set Actor runs to Full
  access, or run from the console. Nothing about what is charged changes, and a run with a full
  token is unaffected.
- **And a token that can READ your account memory but not WRITE it now says so too.** That one
  looked like a perfect run: every article you already had was still recognised and skipped, but
  nothing this run delivered could be written down — so your NEXT run paid for all of it again,
  with nothing anywhere to say why. The run now names it the moment the first write is refused, on
  the run page, on its own uncharged row in the dataset and in the run log, and tells you the
  permission to add: key-value store Write (and Create) under Settings → API & Integrations, or
  Actor runs set to Full access. A run with a full token is unaffected.

### 1.0.5 — 2026-09-13

- **The field name you guessed now works.** If you send your search terms as `query`, `keyword`,
  `keywords`, `searchQuery`, `searchQueries`, `searchTerm`, `searchTerms` or `q` — or a section as
  `topic` — the run reads them instead of collecting nothing: the values are used exactly as sent,
  a term you put in both places is collected once, and one uncharged note names the field to use
  next time. Nothing about what is charged changes.

### 1.0.4 — 2026-09-13

- **A run Apify moves to another server still stops at your row limit.** When a run was continued on
  a new server, it counted only the articles it had charged you for toward "Max rows to return" —
  so on a run where articles were delivered without a charge, the continuation could hand back a few
  rows past your own limit. Every article already delivered now counts toward that limit, charged or
  not, and the cap can no longer be overshot.

### 1.0.3 — 2026-09-12

- **The run page counts every article your query really carried, and a query check is charged only
  where it does.** Two things used to vanish from "asked for": articles Google published without a
  link or an id, and articles the run had already delivered for you before Apify moved it to
  another server. Either one could leave a real query reading "0 asked for" while the query check
  was still charged. Both are now counted and named on their own uncharged row, and an input whose
  articles another of your inputs already delivered in the same run is no longer charged a query
  check at all.

### 1.0.2 — 2026-09-12

- **What you asked for is what the run page counts.** Articles your account already had were being
  added to the ask, so a run that asked for 5, delivered 5 and charged 5 read as "5 of 25 asked
  for" — an 80% shortfall on a run that did exactly what it was told. The reconciliation is now
  your own `maxItems` and nothing else, and the repeats are reported beside it: "5 articles of 5
  asked for", then "20 more you already had were skipped, not charged". The receipt and each
  query's own row say the same, and nothing about what is charged changed.
- **A search box left blank is answered, not ignored.** Sending an empty entry in "Search queries"
  or "Topic sections" used to fall through to the built-in sample and report that no query was set
  — which was not true, and told you nothing about your own input. That entry is now refused
  before any request is sent, on one uncharged row naming the field, and the run page says so.

### 1.0.1 — 2026-09-12

First public build.

- A search query returns Google News articles as rows: the headline with the publisher suffix
  removed, the headline exactly as Google publishes it, the article's Google News link, Google's
  own stable article ID, the publication time as a real ISO-8601 UTC timestamp and again exactly as
  Google wrote it, the publisher's name and their site's home address, and how many other outlets
  Google grouped under the same story.
- **Four doors, one column set.** A search query, a Google News topic section (`TECHNOLOGY`,
  `BUSINESS`, `WORLD` and the rest), a place, or the top stories — each produces the same row, and
  `target` and `targetKind` say which door it came through, so a dataset mixing them is still one
  table.
- **`maxItems` is exact and it is the only number in this actor.** Ask for ten and ten rows land.
  Nothing is collected past your cap, and a run that hits it says so on the row where it stops
  rather than quietly returning a different number from the one you set.
- **The link is named for what it is.** `googleNewsUrl` is the article's link on Google News, not
  the publisher's own URL, and this actor does not claim to resolve it. Google publishes every
  article behind an opaque redirect; turning one into a publisher URL is a second undocumented
  request per article, and on the day this actor was built that endpoint refused every documented
  form of the call. What ships instead is solid: the Google News link, which always resolves for a
  reader, plus `publisherName` and `publisherHomeUrl` from Google's own data, present on every
  article measured. No surcharge, no separate event, and no promise that breaks silently.
- **Dates are parsed, never relative and never in the publisher's language.** `publishedAt` is
  ISO-8601 UTC or an explicit null; `publishedAtRaw` carries Google's own string beside it so the
  parse can be checked.
- **A query that matched nothing is an answer, not a failure.** Google serves it as an ordinary
  empty feed, so the run ships one uncharged row saying the query matched nothing and keeps going
  with the rest of your list. A feed Google would not serve is a different row again, uncharged and
  marked for re-running — the two are never confused.
- **A value we do not recognise is refused, never substituted.** An unknown language, country,
  topic or time window leaves one uncharged row naming the field, what was sent, and the values
  that work — and the rest of your target list is still collected. A swapped setting returns billed
  rows that look exactly like the ones you asked for, which is why this actor never guesses.
- Time window on the article's own publication time (`1h` through `1y`), language and country on
  Google's own feed parameters, a run clock, and account memory keyed on Google's article ID so a
  daily schedule pays only for what is new.
- **Click Start with nothing set** and the run returns a small built-in sample — one query, ten
  articles — so the output shape can be read before anything is collected, at no result fee. Touch
  only the filters and the sample runs under them.
- Two charged events, and nothing is charged for starting a run: **Article**, one article row that
  landed in your dataset, and **Query check**, one query, topic or place we successfully fetched and
  whose feed came back with articles in it — including a run where you already held every one of
  them and the answer is "nothing new since your last run". A target we could not fetch, one you set
  to a value we do not recognise, and one that matched nothing at all are charged none of them.
- **Every query and every topic section also gets one row of its own**, saying how many articles
  Google News is carrying for it, how many were delivered, how many your account already held, and
  whether the Query check was charged for it. It is the only row that ever carries a Query check,
  and no row bills two events. It exists so that a per-query charge has a row behind it: an
  all-repeat query has no article row to ride on, and a charge you cannot reconcile from your own
  dataset is the one thing this shelf will not ship.
- Every run ends with an uncharged receipt row reconciling what was asked for, what landed, what
  your account already held, what your time window dropped, what stopped the run, and the charged
  totals for both events. A cost cap or a time limit ends the collecting, never the delivering.
