August 18, 2026 · GNews Team
News API: What It Returns, How to Choose One, and How to Call It (Python, JS, cURL)
A news API is a REST endpoint that returns published news articles as structured JSON, so your app can query the world's news the way it queries its own database. With the GNews API you get two endpoints (search for keyword queries, top-headlines for category feeds), a query syntax with exact phrases and boolean operators, and a normalized article object you can index or render directly. This guide covers what a news API returns, how to judge one before you integrate it, and how to run production-grade requests in Python, JavaScript, and cURL, with real responses including a real error payload.
What a news API is (and what it returns)
A news API is a REST service that crawls news publishers, deduplicates and normalizes what they publish, and exposes the result as JSON over HTTP. You send a query, you get back an array of article objects with the same field names every time, whatever the publisher. That normalization is the product: without it you would be maintaining one scraper per outlet. Be precise about the boundary, because it is where most integrations go wrong. A news API returns metadata and excerpts:
title,description,content,url,image,publishedAt,lang, and asourceobject. It does not hand you the publisher's full licensed article body. On the GNews free plancontentis truncated by design, and theurlis there so you send readers to the publisher. It also returns no analysis: no sentiment score, no named entities, no topic label. Those are layers you add on top of the stream.
That holds across news APIs generally. What separates one news data API from the next is coverage, query power, and what the response object contains.
How to choose a news API: six things to check first
Six criteria separate a news API you can build on from one you will replace in six months. Coverage: how many languages and countries the index spans, and whether the sources you care about are in it. Run your real query, not the vendor's demo query. Freshness: how quickly a newly published article becomes retrievable, and whether you can sort by publication time and bound a request to a window instead of hoping the default order is recent. Query expressiveness: exact phrases and boolean operators, or just a bag of words. A bag of words means you filter client side and burn quota on articles you throw away. Response shape: which fields come back, whether
contentis truncated, and whether the source is identified well enough to attribute and deduplicate. Quotas and rate limits: requests per day, and whether hitting the ceiling gives you a documented status code or a silent empty array. Terms and attribution: what you may store, cache, and display.
The rest of this guide checks GNews against those six: lang and country for coverage, sortby=publishedAt with from and to for freshness (Step 4), exact phrases plus AND, OR, NOT and in for query power (Step 3), documented status codes for quotas (Step 5). The response shape is in the JSON response reference, and plan limits and terms live on your gnews.io dashboard.
What you'll build
A news client that runs a precise topic query, bounds it to the last 7 days, pages past the first batch, handles a quota error, and drops duplicates. Running example: renewable energy coverage.
Prerequisites
- A free GNews API key: create an account at gnews.io and copy it from your dashboard. New to the API? The first-call walkthrough covers signup step by step.
- Python 3, or Node.js 18 or newer for the built-in
fetch. The cURL samples need no runtime.
Step 1: Pick your endpoint (search or top-headlines)
Use search when the topic comes from the user or from your app's logic: it is the only endpoint built around a query string. Use top-headlines for a ready-made news feed API on a broad category, and both when you need a default feed plus a search box.
# query-driven
curl "https://gnews.io/api/v4/search?q=%22renewable%20energy%22&lang=en&country=us&max=5&apikey=$GNEWS_API_KEY"
# category-driven
curl "https://gnews.io/api/v4/top-headlines?category=general&lang=en&country=us&max=5&apikey=$GNEWS_API_KEY"
top-headlines accepts nine category values: general, world, nation, business, technology, entertainment, sports, science, health. Everything below uses search.
Step 2: Make the request
The minimal precise call: an exact phrase, one language, one country, five results.
Python
import json, os, urllib.parse, urllib.request
API_KEY = os.environ["GNEWS_API_KEY"]
params = {
"q": '"renewable energy"',
"lang": "en",
"country": "us",
"max": 5,
"apikey": API_KEY,
}
url = "https://gnews.io/api/v4/search?" + urllib.parse.urlencode(params)
with urllib.request.urlopen(url, timeout=30) as resp:
data = json.load(resp)
print(data["totalArticles"], "matches")
for article in data["articles"]:
print(article["publishedAt"], article["source"]["name"], article["title"])
JavaScript
const params = new URLSearchParams({
q: '"renewable energy"',
lang: "en",
country: "us",
max: "5",
apikey: process.env.GNEWS_API_KEY,
});
const res = await fetch(`https://gnews.io/api/v4/search?${params}`);
if (!res.ok) throw new Error(`GNews ${res.status}: ${await res.text()}`);
const data = await res.json();
console.log(data.totalArticles, "matches");
for (const a of data.articles) {
console.log(a.publishedAt, a.source.name, a.title);
}
cURL
curl "https://gnews.io/api/v4/search?q=%22renewable%20energy%22&lang=en&country=us&max=5&apikey=$GNEWS_API_KEY"
Keep the key in an environment variable. A key pasted into client-side JavaScript is a key anyone can read and spend.
Step 3: Write a precise query
The q parameter is a small query language, capped at 200 characters, and the highest-leverage part of a REST news API: every article you filter server side is one you do not store or score.
Exact phrase: wrap the words in double quotes.
q="renewable energy"matches that word sequence, whileq=renewable energymatches documents containing both words anywhere. AND: a space already acts as AND, and you can write it explicitly. OR: matches either term, and it binds tighter than AND, soa AND b OR cis not what you probably mean. NOT: removes matching articles, as in"renewable energy" NOT opinion. Parentheses: required to make mixed operators behave, for example"renewable energy" AND (solar OR wind). Special characters must be inside quotes to be accepted.in: chooses which attributes are searched, fromtitle,descriptionandcontent, comma-separated. It defaults totitle,description, so the default already keeps a passing mention buried in an article body from matching. Addingcontentwidens the net deliberately.
The call this guide runs combines all of it:
GET https://gnews.io/api/v4/search
?q="renewable energy" AND (solar OR wind) NOT opinion
&in=title,description&lang=en&country=us&sortby=publishedAt&max=10
Run it next to the plain phrase and compare totalArticles. On 2026-08-18, q="renewable energy" matched 3316 articles and the operator version above matched 833, a drop of roughly 75 percent. Those 2483 articles are ones you would otherwise have paged through, stored, and filtered yourself. Widening in to title,description,content pushed it back up to 16396, the cost of searching article bodies.
URL-encoding the query
Quotes, spaces and parentheses are not URL-safe, which is why the cURL samples show q=%22renewable%20energy%22. Never build the URL by hand: use urllib.parse.urlencode in Python and URLSearchParams in JavaScript.
Step 4: Control freshness and page through results
For real-time news API behaviour, sort explicitly. sortby=publishedAt returns the most recently published first, sortby=relevance the best textual match first. Use publishedAt for a live feed and relevance for answering a question.
To bound a request in time, pass from and to as ISO 8601 datetimes, for example from=2026-08-11T06:03:00Z&to=2026-08-18T06:03:00Z for a rolling 7-day window. Publication dates come back in UTC, so build the window in UTC too. Adding that window to the operator query above took totalArticles from 833 down to 5.
max and totalArticles are independent. max is how many articles this response contains, between 1 and 100, capped by your subscription. totalArticles is how many matched in total, so a five-figure count next to max=10 is normal.
To walk past the first batch, use page, which defaults to 1. The search endpoint reference states that you cannot paginate more than 1000 articles, so paging reads the top of a result set rather than exporting it. Beyond that, narrow the query and slice by time, walking from and to backwards a day at a time.
Step 5: Handle errors, quotas, and duplicates
Read the status code, not just the body. GNews documents seven:
200success,400malformed request,401no API key provided or key invalid,403daily quota reached (it resets at 00:00 UTC),429too many requests in a short period,500server-side failure,503maintenance. Split them in two and treat them differently.400and401are your fault: the request or the key is wrong, retrying changes nothing, so log loudly and stop.403,429,500and503are transient: retry with exponential backoff and a cap, and on403back off until the UTC reset rather than hammering a quota that will not move. Error bodies come back in one of two shapes,{"errors": ["message"]}or{"errors": {"attribute": "message"}}when one parameter is at fault, so handle both.
Here are two real captured responses, both from running the Step 2 call with a deliberately bad apikey. A well-formed but invalid 32-character key returns HTTP 401:
{
"errors": [
"Invalid API Key provided."
]
}
A value the API will not read as a key at all returns HTTP 400:
{
"errors": [
"You did not provide an API key."
]
}
Neither failure is an HTTP 200 with an empty articles array, which is what makes the status code safe to branch on.
Two more production habits. Cache responses: a news query is not user-specific, so cache the JSON for a few minutes keyed by the full parameter set, because a page refresh should not spend a request. Deduplicate before display: the same story reaches you through several outlets, so key on the article id.
seen, unique = set(), []
for article in data["articles"]:
if article["id"] in seen:
continue
seen.add(article["id"])
unique.append(article)
Example response
The Step 2 call, answered on 2026-08-18. It returned five article objects; one is shown in full.
{
"totalArticles": 3316,
"articles": [
{
"id": "9e04464cdc2855ec00e20e5b99f2d45b",
"title": "India Lets Delayed Renewable Projects Pay to Keep Grid Access",
"description": "India is allowing delayed renewable-energy developers to pay compensation charges to retain scarce grid connectivity while they complete their projects.",
"content": "India’s authorities have given solar developers missing their deadlines the option to pay to keep their grid connectivity instead of losing it, Reuters has reported, citing the country’s Central Electricity Regulatory Commission. With grid connectivity a limited resource, space should not be kept unused, the regulator said.\nAccording to the regulator, if a solar or wind developer misses its own project deadline, they can remain on the list for a grid connection, but they would have to pay the equivalent of $10.48 per megawatt per day until they complete their project. Developers would have to pay three times that if they delay the start of commercial operations at their installations.\nThe relief is not permanent, however. Developers would have three months to catch up on land requirements, six months for finding the money to build their installation, and 12 months to commission the completed projects, the Central Electricity Regulatory Commission also said.\nEarlier this month, New Delhi told wind and solar developers they would be exempt from transmission charges if their projects face commissioning delays because of transmission capacity constraints.\nThe relief will only cover projects whose developers had signed at least seven-year power sale contracts by the end of this year. In earlier moves to stimulate more wind and solar, the government began phasing out interstate transmission charges for alternative energy generation projects in July last year.\nIndia’s government has a target of building 500 GW of non-hydrocarbon generation capacity by 2030. Solar power currently accounts for 29% of the country’s non-hydrocarbon generation capacity. Plans were to expand it from 162 GW currently to over 292 GW by 2030, but this target has come under threat due to recent legislative changes seeking to reduce dependence on imported solar components from China, because while local module capacity is substantial, at 200 GW, solar cell manufacturing capacity is just 27 GW.\nBy Irina Slav for Oilprice.com\nMore Top Reads From Oilprice.com\nKazakhstan Accuses Big Oil of $10.7 Billion Corruption in Kashagan Oil Project\nHormuz Crisis Pushes Asian Refiners Toward U.S. Oil\nIndia's Coal Demand Set to Hit 1.6 Billion Tons by 2030",
"url": "https://oilprice.com/Latest-Energy-News/World-News/India-Lets-Delayed-Renewable-Projects-Pay-to-Keep-Grid-Access.html",
"image": "https://d32r1sh890xpii.cloudfront.net/news/1200x675/2026-08-17_fipgzo2jk9.jpg",
"publishedAt": "2026-08-17T06:45:00Z",
"lang": "en",
"source": {
"id": "1fc0d2b0cf3d92c9d8bfae0b4ee9b6ce",
"name": "OilPrice",
"url": "https://oilprice.com",
"country": "us"
}
}
]
}
The fields, per the JSON response reference:
| Field | What it holds |
|---|---|
totalArticles |
Articles matching the query in total, independent of max |
id |
Unique article identifier, the key to deduplicate on |
title |
Main title of the article |
description |
Short description |
content |
Article content, truncated on the free plan |
url |
Link to the article on the publisher's site |
image |
Main image |
publishedAt |
Publication date, always UTC |
lang |
Language of the article |
source.name |
Name of the publisher |
source.country |
Country the source is based in, search endpoint only |
What are you building? Pick your path
This page is the reference. Each of these goes deep on one job.
- Your first key and first call, plus whether Google publishes an official news API: the Google News API walkthrough.
- Market, company, and ticker news, including tickers that collide with common words: the financial news API guide.
- Pushing headlines into Slack or Discord, with webhooks and no double-posting: the messaging API news guide.
- Routing articles into topic channels automatically: AI sorted news channels.
FAQ
What is a news API? A news API is a REST endpoint that returns published news articles as structured JSON. The provider crawls many publishers, deduplicates and normalizes what they publish, and exposes the result as article objects with consistent field names: title, description, content excerpt, URL, image, publication date, language, and source. Your app sends an HTTP request with a query plus parameters such as language, country and result count, and gets back a JSON array it can index, filter, or render, without writing a scraper for each outlet.
Is there a free news API? Yes. GNews offers a free plan intended for development and testing. Request limits and feature gating change over time, so read the current numbers on the gnews.io pricing page and your dashboard.
What is the difference between search and top-headlines?
search is query-driven and requires a q parameter, so it is what you call when a topic comes from the user or from your app. top-headlines is category-driven and returns a ready-made feed for one of nine categories. See Step 1.
Does a news API return the full article text?
No. You get metadata plus a content excerpt, truncated on the free plan, along with the url to the publisher. Republishing complete article bodies is a licensing matter between you and the publisher, not a feature an API can toggle on.
How do I avoid hitting the rate limit?
Cache responses keyed by the full parameter set, poll on a schedule instead of on every page view, request only the max you render, and back off until the 00:00 UTC reset on a 403. Step 5 has the full status code split.
Next steps
Read the search endpoint reference for the complete parameter list, then wire the query language into your own search box. Start building for free: create a key, run the Step 2 call, and you have a working news feed.