Skip to content

Repository files navigation

APITube News API Node.js SDK

GitHub Release npm Version Node.js Version License PRs Welcome TypeScript Made with Love

Node.js/TypeScript SDK for the APITube News API — access global news articles, headlines, stories, sentiment analysis, and more.

Requirements

  • Node.js 18+
  • TypeScript 5+ (optional, fully typed)

Installation

npm install @apitube/news-api

Quick Start

import { 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);
}

Usage

Initialize the client

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 });

Search articles

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);
}

Search in plain language

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 charge

The 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.

Specify API version

const response = await client.news('everything', {
  title: 'artificial intelligence',
  per_page: 5,
}, 'v1');

By default, the SDK uses v1.

Top headlines

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}`);
}

Get a single article

const response = await client.news('article', { id: 'article-id' });
const article = response.articles[0];
console.log(article.title);
console.log(article.body);

Get articles by story

const response = await client.news('story', { id: 'story-id' });
for (const article of response.articles) {
  console.log(article.title);
}

Raw articles

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

Count articles matching the same filters as everything:

const count = await client.count({
  title: 'artificial intelligence',
  'language.code': 'en',
});
console.log(`Matching articles: ${count}`);

Autocomplete suggestions

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})`);
}

Reference data (people, companies, sources, journalists)

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);

Check balance

const balance = await client.balance();
console.log(`Plan: ${balance.plan}`);
console.log(`Points: ${balance.points}`);

Ping

const isAvailable = await client.ping();
console.log(isAvailable ? 'API is available' : 'API is unavailable');

Error Handling

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}`);
  }
}

Testing

npm install
npm test

License

MIT

About

Node.js SDK for the APITube News API - global news articles, headlines, stories, sentiment analysis, entities, and more. Written in TypeScript.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages