apitube/news-api

PHP SDK for the APITube News API

Maintainers

Package info

github.com/apitube/news-api-php

pkg:composer/apitube/news-api

Statistics

Installs: 870

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

1.2.0 2026-05-29 23:38 UTC

This package is not auto-updated.

Last update: 2026-05-29 23:39:49 UTC


README

GitHub Release Latest Stable Version PHP Version Require License PRs Welcome PSR-18 Compatible Made with Love

PHP SDK for the APITube News API — access global news articles, headlines, stories, sentiment analysis, and more.

Requirements

  • PHP 8.1+
  • A PSR-18 HTTP client (e.g. Guzzle)
  • A PSR-17 HTTP factory

Installation

composer require apitube/news-api

Quick Start

use APITube\Client;

$client = new Client(apiKey: 'your-api-key');

// Search news articles
$response = $client->news('everything', [
    'title' => 'artificial intelligence',
    'language.code' => 'en',
    'per_page' => 5,
]);

foreach ($response->articles as $article) {
    echo $article->title . "\n";
    echo $article->url . "\n\n";
}

Usage

Initialize the client

use APITube\Client;

$client = new Client(
    apiKey: 'your-api-key',
    baseUrl: 'https://api.apitube.io', // optional, default value
);

You can pass any PSR-18 HTTP client:

$client = new Client(
    apiKey: 'your-api-key',
    httpClient: new \GuzzleHttp\Client(['timeout' => 30]),
);

Search articles

$response = $client->news('everything', [
    'title' => 'climate change',
    'language.code' => 'en',
    'per_page' => 10,
]);

echo "Page: {$response->page}\n";
echo "Has next page: " . ($response->hasNextPages ? 'yes' : 'no') . "\n";

foreach ($response->articles as $article) {
    echo "{$article->title}\n";
    echo "Source: {$article->source?->domain}\n";
    echo "Sentiment: {$article->sentiment?->overall?->polarity}\n\n";
}

Specify API version

$response = $client->news('everything', [
    'title' => 'artificial intelligence',
    'per_page' => 5,
], version: 'v1');

By default, the SDK uses v1.

Top headlines

$response = $client->news('top-headlines', [
    'language.code' => 'en',
    'per_page' => 10,
]);

foreach ($response->articles as $article) {
    echo "{$article->title}{$article->source?->domain}\n";
}

Get a single article

$response = $client->news('article', [
    'id' => 'article-id',
]);

$article = $response->articles[0];
echo $article->title . "\n";
echo $article->body . "\n";

Get articles by story

$response = $client->news('story', [
    'id' => 'story-id',
]);

foreach ($response->articles as $article) {
    echo "{$article->title}\n";
}

Raw articles

Fetch recently discovered articles before parsing and enrichment:

$response = $client->news('raw', [
    'per_page' => 50,
    'sort.by' => 'published_at',
    'sort.order' => 'desc',
]);

foreach ($response->articles as $article) {
    echo "{$article->title}\n";
}

Count articles

Count articles matching the same filters as everything:

$count = $client->count([
    'title' => 'artificial intelligence',
    'language.code' => 'en',
]);

echo "Matching articles: {$count}\n";

Autocomplete suggestions

Supported types: categories, topics, industries, entities.

$items = $client->suggest('categories', 'spo');

foreach ($items as $item) {
    echo "{$item['name']} (id: {$item['id']})\n";
}

Reference data (people, companies, sources, journalists)

Each entity exposes a paginated list method and a profile method by ID:

// List
$people = $client->people(['name' => 'Elon', 'per_page' => 5]);
foreach ($people->results as $person) {
    echo "{$person['name']} (id: {$person['id']})\n";
}

// Profile with coverage statistics
$profile = $client->person($people->results[0]['id']);
echo "Articles: {$profile['coverage']['article_count']}\n";

// Same shape for the other entities:
$client->companies(['name' => 'Tesla']);
$client->company($id);
$client->sources(['country' => 1]);
$client->source($id);
$client->journalists(['name' => 'Smith']);
$client->journalist($id);

Check balance

$balance = $client->balance();

echo "Plan: {$balance->plan}\n";
echo "Points: {$balance->points}\n";

Ping

$isAvailable = $client->ping();
echo $isAvailable ? 'API is available' : 'API is unavailable';

Error Handling

The SDK throws typed exceptions:

use APITube\Exceptions\ApiException;
use APITube\Exceptions\AuthenticationException;
use APITube\Exceptions\RateLimitException;

try {
    $response = $client->news('everything', ['title' => 'php']);
} catch (AuthenticationException $e) {
    // Invalid or missing API key (HTTP 401)
    echo "Auth error: {$e->getMessage()}\n";
} catch (RateLimitException $e) {
    // Rate limit exceeded (HTTP 429)
    echo "Rate limited. Retry after: {$e->retryAfter} seconds\n";
} catch (ApiException $e) {
    // Other API errors
    echo "API error ({$e->getCode()}): {$e->getMessage()}\n";
    echo "Request ID: {$e->requestId}\n";
}

Testing

composer install
vendor/bin/phpunit

License

MIT