SDK

TypeScript SDK

Zero runtime dependencies, ESM and CommonJS with types, for Node 22+, Deno, Bun, browsers and edge runtimes. Every endpoint is a typed method.

Not published yet: the install lines go live with the first release.

Install

One package, no setup beyond your API key.

TypeScript
$ npm install github:sportsapiapp/sportsapi-js   # until it is published to npm
$ npm install sportsapi                          # once it is

Authenticate

Use the API key from your dashboard. Pass it to the client, or set SPORTSAPI_API_KEY and the client reads it.

TypeScript
import { SportsAPI } from 'sportsapi';

const client = new SportsAPI({ apiKey: process.env.SPORTSAPI_API_KEY });
// or leave apiKey out: SPORTSAPI_API_KEY is read by default

First calls

Every method returns the API's { data, meta } envelope, typed. Path parameters come first, in path order, then the query parameters with the API's own names.

TypeScript
const { data: live } = await client.livescores.list({ sport: 'football' });
const { data: table, meta } = await client.leagues.standings(17, { season: 61627 });
const { data: lineups } = await client.fixtures.lineups(211521);

Errors

One error type per HTTP status, each carrying the API's code, message and Retry-After. Branch on the code, never on the message.

TypeScript
import { NotFoundError, PermissionDeniedError } from 'sportsapi';

try {
  await client.fixtures.winProbability(211521);
} catch (e) {
  if (e instanceof PermissionDeniedError) console.error(e.code); // endpoint_not_in_plan, …
  if (e instanceof NotFoundError) console.error(e.code); // not_found | no_data | not_supported
}

Paging

Every endpoint with a page parameter has a pages iterator that walks the pages until there are no more.

TypeScript
for await (const page of client.teams.fixturesPages(42, { type: 'recent' }, { maxPages: 5 })) {
  console.log(page.meta.page, page.data.length);
}

WebSocket stream (Business)

The stream mints its own single-use ticket, subscribes, reconnects and replays what it missed, and merges every delta into the fixtures it holds.

TypeScript
const stream = client.stream(['livescores', 'fixture:211521']);

stream.on('delta', (frame) => console.log(frame.id, frame.changes));
stream.on('error', (err) => console.error(err));

// the merged state, current at any time
console.log(stream.fixtures('livescores').length, 'live');

stream.close();

Options

A 429 rate_limited or a 503 is retried after Retry-After (twice by default); a quota error never is.

TypeScript
new SportsAPI({
  apiKey,            // or SPORTSAPI_API_KEY
  baseUrl,           // or SPORTSAPI_BASE_URL
  timeout: 30_000,   // ms per attempt
  maxRetries: 2,
});
Every endpoint, with this SDK's call on each page→