Node.js/TypeScript SDK for the APITube News API — access global news articles, headlines, stories, sentiment analysis, and more.
- Node.js 18+
- TypeScript 5+ (optional, fully typed)
npm install @apitube/news-apiimport { Client } from '@apitube/news-api';
const client = new Client({ apiKey: 'your-api-key' });
// Search news articles
const response = await client.news('everything', {
title: 'artificial intelligence',
'language.code': 'en',
per_page: 5,
});
for (const article of response.articles) {
console.log(article.title);
console.log(article.url);
}import { Client } from '@apitube/news-api';
const client = new Client({
apiKey: 'your-api-key',
baseUrl: 'https://api.apitube.io', // optional, default value
});You can pass a custom axios instance:
import axios from 'axios';
import { Client } from '@apitube/news-api';
const httpClient = axios.create({ timeout: 30_000 });
const client = new Client({ apiKey: 'your-api-key', httpClient });const response = await client.news('everything', {
title: 'climate change',
'language.code': 'en',
per_page: 10,
});
console.log(`Page: ${response.page}`);
console.log(`Has next page: ${response.hasNextPages ? 'yes' : 'no'}`);
for (const article of response.articles) {
console.log(article.title);
console.log(`Source: ${article.source?.domain}`);
console.log(`Sentiment: ${article.sentiment?.overall?.polarity}`);
// English translation of the headline for non-English articles
// (null for English articles — fall back to the original title)
console.log(article.translations?.en?.title ?? article.title);
}Instead of assembling filters by hand, describe what you want in the prompt parameter. The API
translates the sentence into the regular filters before searching and returns what it used in
meta.prompt:
const response = await client.news('everything', {
prompt: 'Tesla and Elon Musk news in English for the last 10 days',
per_page: 5,
});
// { 'person.name': 'Elon Musk', 'organization.name': 'Tesla', 'language.code': 'en', 'published_at.start': 'NOW-10DAY' }
console.log(response.meta?.prompt?.applied);
console.log(response.meta?.prompt?.ignored); // values understood but not used, each with a reason
console.log(response.meta?.prompt?.cached); // true = served from cache, no extra chargeThe prompt must be 3–500 characters. Filters you pass yourself always win over the prompt.
Translating a prompt costs 2 extra points, but only the first time a given wording is used —
interpretations are cached for 24 hours. See the
prompt reference.
const response = await client.news('everything', {
title: 'artificial intelligence',
per_page: 5,
}, 'v1');By default, the SDK uses v1.
const response = await client.news('top-headlines', {
'language.code': 'en',
per_page: 10,
});
for (const article of response.articles) {
console.log(`${article.title} — ${article.source?.domain}`);
}const response = await client.news('article', { id: 'article-id' });
const article = response.articles[0];
console.log(article.title);
console.log(article.body);const response = await client.news('story', { id: 'story-id' });
for (const article of response.articles) {
console.log(article.title);
}Fetch recently discovered articles before parsing and enrichment:
const response = await client.news('raw', {
per_page: 50,
'sort.by': 'published_at',
'sort.order': 'desc',
});
for (const article of response.articles) {
console.log(article.title);
}Count articles matching the same filters as everything:
const count = await client.count({
title: 'artificial intelligence',
'language.code': 'en',
});
console.log(`Matching articles: ${count}`);Supported types: categories, topics, industries, entities.
const items = await client.suggest('categories', 'spo');
for (const item of items) {
console.log(`${item.name} (id: ${item.id})`);
}Each entity exposes a paginated list method and a profile method by ID:
// List
const people = await client.people({ name: 'Elon', per_page: 5 });
for (const person of people.results) {
console.log(`${person.name} (id: ${person.id})`);
}
// Profile with coverage statistics
const profile = await client.person(people.results[0].id);
console.log(`Articles: ${profile.coverage?.article_count}`);
// Same shape for the other entities:
await client.companies({ name: 'Tesla' });
await client.company(id);
await client.sources({ country: 1 });
await client.source(id);
await client.journalists({ name: 'Smith' });
await client.journalist(id);const balance = await client.balance();
console.log(`Plan: ${balance.plan}`);
console.log(`Points: ${balance.points}`);const isAvailable = await client.ping();
console.log(isAvailable ? 'API is available' : 'API is unavailable');import {
ApiException,
AuthenticationException,
RateLimitException,
} from '@apitube/news-api';
try {
const response = await client.news('everything', { title: 'node' });
} catch (e) {
if (e instanceof AuthenticationException) {
console.log(`Auth error: ${e.message}`);
} else if (e instanceof RateLimitException) {
console.log(`Rate limited. Retry after: ${e.retryAfter} seconds`);
} else if (e instanceof ApiException) {
console.log(`API error (${e.statusCode}): ${e.message}`);
console.log(`Request ID: ${e.requestId}`);
}
}npm install
npm testMIT