Google News API
Google News results for any query, country and interface language, up to ten pages deep.
Price
$0.20 per 1,000 requests at Starter, down to $0.14 at Max, deducted from your prepaid USD balance.
Endpoint
POST /v1/monitor/google/news
Countries
71 countries.
Request
curl -X POST "https://api.answerline.dev/v1/monitor/google/news" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"electric vehicle battery","country":"FR","hl":"fr"}'
Request options
| Field | Type | Description |
|---|---|---|
query * |
string |
Query to run on Google News |
country |
string |
Country for localized news, as an ISO 3166-1 alpha-2 code. Google News publishes an edition in 71 countries, listed at https://answerline.dev/docs/coverage#countries; a request for another country is refused with a 400. |
gl |
string |
Google's own name for the result-geography parameter, usable in place of `country`. Takes ISO 3166-1 alpha-2 codes, as `country` does, in upper or lower case (`us` or `US`), and the country has to be one this endpoint supports (list them with `GET /v1/countries`; Google News has no `model` value there, and its edition countries are listed at https://answerline.dev/docs/coverage#countries). Send either `country` or `gl`; if both are sent with differing values, the request fails with `400`. |
hl |
string |
Interface language, in the format of Google's `hl` parameter (for example `en`, `de`, `pt-BR`). Case-insensitive free text; Google defines which codes exist. Takes precedence over the language Answerline infers from the country, which lets interface language and result geography differ. |
device |
"desktop" | "mobile" | "ios" | "android" |
Device to run the search on. Not served for Google News yet: its results are read without a device, and a request that sets one is refused with a 400. |
pages |
integer |
How many pages of news results to request (1-10). The feed returns one list of articles, so more pages add no articles; they are charged as requested. |
include |
object |
Flags that add extra data to the response (optional) |
include.html |
boolean |
A copy of the Google News feed the results were read from as it was when the answer was captured, stored on our file host and linked in `html`, to check the answer against. No extra cost. |
include.rawWire |
boolean |
Return the engine's own response as received in result.rawWire: the answer stream, the rendered results pages or the RSS feed, without Gemini's detected location or ChatGPT's session tokens; null where it was not captured. Free. See https://answerline.dev/docs/output-formats#raw-wire |
include.screenshot |
boolean |
Return a full-page PNG screenshot of the engine's page as it showed the finished answer, in result.screenshot: a link, or one link per results page on Google Search. On ChatGPT, Gemini, AI Mode, Google Search, Perplexity and Grok; other engines refuse it with a 400. Absent when the answer was read without a rendered page. Free. See https://answerline.dev/docs/output-formats#screenshots |
answerDepth |
"any" | "full" | "quick" |
How deep an answer the engine writes, where it offers a choice. any (the default): a full answer when the engine can give one now, else its short one. full: a full answer or a retryable error, never charged. quick: the short one, the fastest. Perplexity offers the choice; every other engine has one depth and ignores the field. provenance.answerDepth says what was served. Same price for every value. See https://answerline.dev/docs/engine-features/#answer-depth |
What you get back
Field in result | Type | Description |
|---|---|---|
newsResults | object[] | Articles returned by Google News |
Google News results versus developer APIs
This endpoint returns Google News results for a query, country and interface language as newsResults: the articles, their publishers, dates and positions as a reader sees them.
Google’s JSON API for web search, the Custom Search JSON API, does not return that list. Its overview (checked 2026-09-17, developers.google.com) says it returns web and image results from a Programmable Search Engine, is closed to new customers, and gives existing customers until January 1, 2027 to transition. Its cse.list reference (checked 2026-09-17, developers.google.com) does not mention news results.
A publisher feed or news database gives you coverage. It does not tell you which outlets Google surfaces for a query and in what order, which is what readers see first. The same query can also surface different publishers in different countries and languages; country/gl and hl make each edition a separate, repeatable measurement. Every article comes back on page 1, in position order, so you can measure how far down a story sits.
An annotated response
The excerpt follows the result schema for POST /v1/monitor/google/news. Values are illustrative.
{
"success": true,
"result": {
"newsResults": [
{
// 1-indexed position across the results returned.
"position": 1,
"title": "Battery makers race to cut cobalt use",
// A news.google.com redirect to the article.
"link": "https://news.google.com/rss/articles/CBMiExample?oc=5",
// Publisher name as shown.
"source": "Example News",
// Publication time, ISO 8601 UTC.
"date": "2026-10-19T08:30:00.000Z",
// Always 1: every article is on page 1.
"page": 1
},
{
"position": 2,
"title": "Electric vehicle battery prices: what changed this quarter",
"link": "https://news.google.com/rss/articles/CBMiExample2?oc=5",
"source": "Example Auto",
"date": "2026-10-18T16:05:00.000Z",
"page": 1
}
]
}
}
Parsing notes:
dateis an ISO 8601 UTC timestamp.sourceanddateare omitted when the feed has none.- There is no
snippet,thumbnailorredirectLink. linkis anews.google.comredirect.POST /v1/monitor/google/gotodoes not resolve it.
Synchronous calls
A synchronous call returns the results in the response and waits up to five minutes. One page costs $0.0002, the same as a task.
Python (requests)
import os
from collections import Counter
import requests
API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
resp = requests.post(
f"{API}/v1/monitor/google/news",
headers=HEADERS,
json={"query": "electric vehicle battery", "country": "FR", "hl": "fr"},
timeout=330,
)
if resp.status_code != 200:
raise RuntimeError(f"{resp.status_code} {resp.headers.get('X-Request-Id')} {resp.text}")
articles = resp.json()["result"].get("newsResults", [])
publishers = Counter(a.get("source") for a in articles)
print(len(articles), "articles")
print("top publishers:", publishers.most_common(5))
for a in articles[:5]:
print(a["position"], a.get("source"), "|", a.get("title"), "|", a.get("date"))
print("charged (USD):", resp.headers.get("X-Credits-Charged"))
TypeScript (fetch)
const API = "https://api.answerline.dev";
const res = await fetch(`${API}/v1/monitor/google/news`, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ query: '"Example Corp" lawsuit', gl: "us", hl: "en" }),
signal: AbortSignal.timeout(330_000),
});
if (!res.ok) throw new Error(`${res.status} ${res.headers.get("X-Request-Id")} ${await res.text()}`);
const { result } = await res.json();
for (const article of result.newsResults ?? []) {
console.log(article.position, article.source, article.title, article.date, article.link);
}
console.log("charged (USD):", res.headers.get("X-Credits-Charged"));
Batches: async tasks and a webhook
Scheduled news monitoring belongs in tasks: $0.0002 per page-one task, queued and posted to your webhook. POST /v1/async/task/batch accepts 1 to 500 tasks, each admitted on its own and answered by index.
Python: a watchlist across editions
import datetime
import os
import requests
API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
hour = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H")
watchlist = ['"Example Corp"', '"Example Corp" CEO', '"Example Corp" fine OR investigation']
editions = [("US", "en"), ("GB", "en"), ("DE", "de"), ("FR", "fr")]
tasks = [
{
"taskType": "GOOGLE_NEWS",
"payload": {"query": q, "country": country, "hl": hl},
"idempotencyKey": f"news-{i}-{country}-{hl}-{hour}",
"webhook": {"url": "https://your-app.example/hooks/news"},
}
for i, q in enumerate(watchlist)
for country, hl in editions
]
resp = requests.post(f"{API}/v1/async/task/batch", headers=HEADERS, json=tasks, timeout=60)
resp.raise_for_status()
body = resp.json()
print(body["summary"])
for item in body["results"]:
if not item["success"] and item["error"]["code"] != "RESOURCE_ALREADY_EXISTS":
print(tasks[item["index"]]["idempotencyKey"], item["error"]["code"])
TypeScript: receive deliveries and flag new articles (Express)
Each delivery carries the GET /v1/async/task/{taskId} body. Verify Webhook-Signature over the raw body before parsing.
import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";
const seenLinks = new Set<string>(); // use a database table in production
function verify(raw: Buffer, header: string | undefined, secret: string, toleranceSeconds = 300): boolean {
const pairs = (header ?? "").split(",").map((part) => part.split("="));
const stamps = pairs.filter(([k]) => k === "t").map(([, v]) => v);
const sigs = pairs.filter(([k]) => k === "v1").map(([, v]) => v);
if (stamps.length !== 1 || !/^\d+$/.test(stamps[0]) || sigs.length === 0) return false;
if (Math.abs(Date.now() / 1000 - Number(stamps[0])) > toleranceSeconds) return false;
const expected = createHmac("sha256", secret).update(`${stamps[0]}.`).update(raw).digest();
return sigs.some((sig) => {
const given = Buffer.from(sig, "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
});
}
const app = express();
app.post("/hooks/news", express.raw({ type: "application/json" }), (req, res) => {
if (!verify(req.body, req.get("webhook-signature"), process.env.WEBHOOK_SECRET!)) return res.sendStatus(400);
const delivery = JSON.parse(req.body.toString("utf8"));
if (delivery.test) return res.sendStatus(204);
const { task, response } = delivery;
if (task.status !== "COMPLETED") {
console.warn(task.idempotencyKey, "failed:", response.error.code);
return res.sendStatus(204);
}
for (const article of response.result.newsResults ?? []) {
if (seenLinks.has(article.link)) continue;
seenLinks.add(article.link);
console.log("NEW", task.idempotencyKey, article.source, article.title, article.link);
}
res.sendStatus(204);
});
app.listen(3000);
Deliveries can repeat and arrive out of order, so deduplicate on task.id. See webhooks.
Geo and language targeting
| Field | Values | Notes |
|---|---|---|
country or gl |
ISO 3166-1 alpha-2 | One is required; different values in both is a 400. The 71 editions are listed in coverage. |
hl |
Google interface language, e.g. fr, de, pt-BR |
Overrides the language derived from the country. |
pages |
1 to 10 | Every article is on page 1; pages above 1 are free and add none. |
device |
Not available | A request that sends device is refused with a 400 and not billed. |
Google News has no location or state; country and language set the edition. For multilingual watchlists, write the query in each edition’s language instead of reusing an English query everywhere; multilingual AI answers applies the same principle to assistants.
Include flags and what they cost
| Option | Adds | Credits |
|---|---|---|
| one page | newsResults |
$0.0002 |
pages 2 to 10 |
no further results | 0 |
include.html |
html: a link to a copy of the feed the results were read from (HTML snapshots) |
0 |
include.rawWire |
rawWire: the feed as received, when it was read; off by default (what it holds) |
0 |
A 10-page task costs $0.0002, the same as a one-page task, and returns the same articles.
result.provenance reads interface rss (all fields).
Common workloads
- News monitoring: coverage of a company, product or topic per edition. See news monitoring and the Google News API post.
- Adverse media screening: names combined with risk terms, run on a schedule and reviewed by analysts. See adverse media screening.
- Brand protection and crisis response: which outlets carry a story and how prominently. See brand protection and brand crisis AI monitoring.
- Threat intelligence: breach, fraud and impersonation coverage for an organization. See threat intelligence.
- AI answer context: pair news results with ChatGPT or Gemini answers on the same topic to see which coverage reaches assistant answers.
Pitfalls
Positions and the article set change as stories develop. Keep a stable cadence per query, put the run period in the idempotency key, and compare like-for-like periods.
Syndicated stories can share titles across publishers, so key articles on link and use source as the publisher.
Quote names to avoid partial matches, and review screening hits by hand: a surname match is not an adverse finding.
Pages above 1 are free but add no articles. Leave pages at 1.
Hourly watchlists across many editions add up. Tasks queue; a submission that would overflow your queue is rejected whole with 429 QUEUE_LIMIT_EXCEEDED. See rate limits.
How failures are billed
An accepted request reserves its cost and is charged it on success. A failed request is charged nothing and its reservation is released. Tasks that never start within 4 hours of creation fail uncharged with QUEUE_WAIT_EXCEEDED and can be resubmitted. Synchronous calls are charged on success even if your connection dropped, so resend them only when the request never reached the server. See credits.
Related: Google News RSS feeds and free news APIs.
Questions
How much does a Google News request cost?
A request costs $0.0002 for one page. Every article comes back on page 1, so leave pages at 1: each extra page, up to 10 in all, is free and adds no articles.
Can I choose the language of Google News results separately from the country?
Yes, where Google publishes that edition. Set country (or gl) for the edition's geography and hl for its language, for example country CA with hl fr, or US with hl es-419. hl overrides the language derived from the country. A pair Google has no edition for, such as FR with hl en, fails without billing instead of answering from another country's edition.
What fields does each Google News result have?
Each newsResults item has position, title, link, source, date and page. link is a news.google.com redirect to the article. There is no snippet, thumbnail or redirectLink.
Is the date field a timestamp?
Yes. date is the publication time as an ISO 8601 UTC timestamp, for example 2026-10-19T08:30:00.000Z.
Are failed Google News requests charged?
No. A failed request is charged nothing and its reservation is released. Completed requests are charged the base price.