gnews-io / gnews-io-php
Official PHP client for the GNews API: search news articles and top headlines from 80,000+ sources.
Requires
- php: ^8.4
- ext-json: *
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- phpunit/phpunit: ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Official PHP client for the GNews API: search news articles and top headlines from 80,000+ sources in 41 languages.
- PHP 8.4+, built on Guzzle
- Exceptions carry the API message and HTTP status
- Automatic retry on rate limit (429), server (5xx) and network errors
- The API key is sent in a header, so it never appears in URLs or error messages
Installation
composer require gnews-io/gnews-io-php
Usage
<?php require_once 'vendor/autoload.php'; $client = new \GNews\GNews('YOUR_API_KEY');
Get a free API key at gnews.io/register.
Search
$articles = $client->search('bitcoin', [ 'lang' => 'en', // language of the articles 'country' => 'us', // country of the source 'max' => 10, // articles per request, 1 to 100 depending on your plan 'in' => 'title,description', // fields to search 'from' => new DateTime('2026-01-01'), // DateTimeInterface or ISO 8601 string 'to' => '2026-12-31T23:59:59Z', 'sortby' => 'relevance', // 'publishedAt' (default) or 'relevance' ]); echo $articles->getTotalArticles() . " articles found\n"; foreach ($articles as $article) { echo $article->getPublishedAt() . ' ' . $article->getSourceName() . ' ' . $article->getTitle() . "\n"; }
The query supports quotes, AND, OR, NOT and parentheses: see the query syntax.
Top headlines
$articles = $client->getTopHeadlines([ 'category' => 'technology', // general (default), world, nation, business, technology, // entertainment, sports, science, health 'lang' => 'en', 'country' => 'us', 'max' => 10, 'q' => 'apple', // optional keywords ]);
Both methods also accept nullable, page and truncate. See the documentation for every parameter.
Response format
The API results are returned in an ArticleCollection object:
| Method | Description |
|---|---|
getTotalArticles() |
Returns the total number of available articles |
getArticles() |
Returns an array of Article objects |
count() |
Returns the number of articles in the collection |
| Array access | You can access articles with $articles[0] |
| Iteration | You can use foreach ($articles as $article) |
Each Article exposes:
| Method | Description |
|---|---|
getId() |
Article ID (also accessible via ->id) |
getTitle() |
Title (also accessible via ->title) |
getDescription() |
Description (also accessible via ->description) |
getContent() |
Content, truncated on the Free plan (also accessible via ->content) |
getUrl() |
Article URL (also accessible via ->url) |
getImage() |
Image URL (also accessible via ->image) |
getPublishedAt() |
Publication date, ISO 8601 UTC (also accessible via ->publishedAt) |
getLang() |
Language (also accessible via ->lang) |
getSource() |
Complete source information array (also accessible via ->source) |
getSourceId() |
Source ID |
getSourceName() |
Source name |
getSourceUrl() |
Source home page |
getSourceCountry() |
Source country, only returned by search (null for top headlines) |
Error handling
API, network and invalid-response errors are thrown as GNews\GNewsException. Its code is the HTTP status (0 for network errors), and getErrors() returns the API error payload.
try { $articles = $client->search('bitcoin'); } catch (\GNews\GNewsException $e) { if ($e->getCode() === 403) { echo "Daily quota reached, it resets at 00:00 UTC\n"; } else { echo $e->getMessage() . "\n"; // e.g. "Invalid API Key provided." } }
| Code | Cause |
|---|---|
| 400 | Invalid parameter or query syntax error |
| 401 | Invalid API key |
| 403 | Daily quota reached or subscription expired |
| 429 | Too many requests per second (1/s on Free, 10/s on paid plans) |
| 5xx | Server error or maintenance |
Rate limit, server and network errors are retried twice with a short randomized backoff (about 1 s, then 2 s) before throwing.
Options
$client = new \GNews\GNews( 'YOUR_API_KEY', timeout: 10000, // ms per request maxRetries: 2, // retries on 429, 5xx and network errors httpClient: null, // custom GuzzleHttp\ClientInterface, e.g. with a proxy );
Development
composer install
composer test
Set GNEWS_API_KEY to also run the integration tests against the real API.
Releases: update GNews::VERSION and CHANGELOG.md, then push a vX.Y.Z tag. Packagist picks up the tag automatically.
License
MIT