npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@withqwerty/sportmonks-typescript-sdk

v1.3.0

Published

TypeScript SDK for SportMonks Football API v3

Readme

SportMonks TypeScript SDK

A comprehensive, production-ready TypeScript SDK for the SportMonks Football API v3. Built with modern TypeScript, featuring complete type safety, intuitive method chaining, automatic retries, real-time polling, and extensive test coverage.

npm version CI TypeScript License: MIT

Features

  • 🚀 Full TypeScript Support - Complete type definitions for all 50+ entities and responses
  • 🔗 Intuitive Method Chaining - Fluent API design for building complex queries naturally
  • 📦 Comprehensive Coverage - 10 resources with 56 endpoints covering all major football data
  • 🔄 Smart Retry Logic - Automatic retry with exponential backoff and rate limit awareness
  • 📊 Real-time Updates - Built-in polling utilities for livescores and transfer monitoring
  • Input Validation - Automatic validation of dates, IDs, and search queries with helpful errors
  • 🎯 Type-safe Includes - Full TypeScript support for relationship includes
  • 📈 Performance Optimized - Efficient pagination, response caching, and minimal dependencies
  • 🧪 Battle-tested - 330+ tests with 97.6% coverage and real API validation
  • 📝 Extensive Documentation - Comprehensive JSDoc comments, examples, and guides

Installation

npm install @withqwerty/sportmonks-typescript-sdk

Quick Start

import { SportMonksClient } from '@withqwerty/sportmonks-typescript-sdk'

const client = new SportMonksClient('YOUR_API_KEY')

// Get fixtures for today
const fixtures = await client.fixtures
  .byDate('2024-01-15')
  .include(['localteam', 'visitorteam', 'venue'])
  .get()

// Get Premier League standings
const standings = await client.standings.bySeason(19735).include(['participant']).get()

Interactive REPL

Test and explore the API interactively with the built-in REPL:

# Set up your API key (one-time setup)
export SPORTMONKS_API_KEY=your_api_key_here
# OR create a .env file with: SPORTMONKS_API_KEY=your_api_key_here

# Run the interactive REPL
npx sportmonks-repl

# Run with advanced features (type browsing, better formatting)
npx sportmonks-repl --advanced

# In the REPL, you can directly use resources without 'client.' prefix:
sportmonks> await leagues.all().limit(5).get()
sportmonks> await teams.search('Liverpool').get()
sportmonks> await fixtures.byDate('2024-03-30').include(['participants', 'scores']).get()

See the REPL documentation for more details and examples.

Configuration

const client = new SportMonksClient('YOUR_API_KEY', {
  baseUrl: 'https://api.sportmonks.com/v3',
  timeout: 30000,
  includeSeparator: ',',
  retry: {
    maxRetries: 3,
    retryDelay: 1000,
    maxRetryDelay: 30000,
    retryOnRateLimit: true,
    retryStatusCodes: [502, 503, 504],
  },
})

Available Resources

Core Resources

Leagues

// Get all leagues
const leagues = await client.leagues.all().get()

// Get league by ID
const league = await client.leagues.byId(8).get()

// Search leagues
const searchResults = await client.leagues.search('Premier').get()

// Get leagues with live fixtures
const liveLeagues = await client.leagues.live().get()

Teams

// Get team by ID with relationships
const team = await client.teams.byId(1).include(['country', 'venue', 'squad']).get()

// Search teams
const teams = await client.teams.search('Manchester').get()

// Get teams by season
const seasonTeams = await client.teams.bySeason(19735).get()

Fixtures

// Get fixtures by date range
const fixtures = await client.fixtures
  .byDateRange('2024-01-01', '2024-01-31')
  .include(['localteam', 'visitorteam', 'events', 'statistics'])
  .get()

// Get head-to-head
const h2h = await client.fixtures.headToHead(1, 14).get()

// Search fixtures
const matches = await client.fixtures.search('derby').get()

// Get fixtures by TV station
const tvFixtures = await client.fixtures.upcomingByTvStation(1).get()

Players

// Get player details
const player = await client.players.byId(30981).include(['team', 'statistics']).get()

// Search players
const players = await client.players.search('Ronaldo').get()

Standings

// Get season standings
const standings = await client.standings.bySeason(19735).include(['participant', 'league']).get()

// Get live standings
const liveStandings = await client.standings.liveByLeague(8).get()

// Get standing corrections
const corrections = await client.standings.correctionsBySeason(19735).get()

Livescores

// Get in-play fixtures
const inplay = await client.livescores
  .inplay()
  .include(['localteam', 'visitorteam', 'scores', 'events'])
  .get()

// Get all livescores (15 min before kickoff)
const upcoming = await client.livescores.all().get()

// Get recently updated
const updates = await client.livescores.latest().get()

News

// Get pre-match news for a league
const preMatch = await client.news.prematch().filter('league_id', 8).get()

// Get post-match news for a fixture
const postMatch = await client.news.postmatch().filter('fixture_id', 18535482).get()

// Get specific news article
const article = await client.news.byId(123).get()

Team Squads

// Get current squad
const currentSquad = await client.teams.squad(1).include(['player']).get()

// Get squad for a specific season
const historicalSquad = await client.teams.squad(1, 21646).include(['player']).get()

Player Statistics

// Get all player statistics
const playerStats = await client.players.statistics(278).get()

// Get player statistics for a specific season
const seasonStats = await client.players.statisticsBySeason(278, 21646).get()

Additional Resources

  • Transfers - Player transfers with date filtering
  • Coaches - Coach information and history
  • Referees - Referee data and assignments
  • Venues - Stadium/venue information
  • News - Pre-match and post-match news articles

Advanced Features

Pagination

const teams = await client.teams.all().page(2).perPage(25).get()

Filtering

const standings = await client.standings
  .all()
  .filter('season_id', 19735)
  .filter('stage_id', 77457866)
  .get()

Sorting

const venues = await client.venues
  .all()
  .orderBy('-capacity') // Descending order
  .get()

SportMonks Syntax Support

The SDK fully supports SportMonks' advanced query syntax:

// Field selection on includes
const fixtures = await client.fixtures
  .byDate('2024-01-15')
  .includeFields('lineups', ['player_name', 'jersey_number'])
  .includeFields('events', ['player_name', 'related_player_name', 'minute'])
  .get()

// Complex includes with field selection
const match = await client.fixtures
  .byId(123456)
  .withIncludes({
    lineups: ['player_name', 'jersey_number'],
    events: ['player_name', 'minute', 'type'],
    participants: true, // Include all fields
    venue: ['name', 'city', 'capacity'],
  })
  .get()

// Multiple filter values
const goalEvents = await client.fixtures
  .byDate('2024-01-15')
  .filter('eventTypes', [14, 15, 16]) // Goals, own goals, penalties
  .get()

// Advanced SportMonks syntax
import { SportMonksSyntaxBuilder } from 'sportmonks-typescript-sdk'

// Build complex includes programmatically
const includeString = SportMonksSyntaxBuilder.buildIncludes({
  lineups: { fields: ['player_name'] },
  events: { fields: ['player_name', 'minute'] },
  league: {
    fields: true,
    nested: {
      country: { fields: ['name'] },
    },
  },
})
// Result: "lineups:player_name;events:player_name,minute;league;league.country:name"

Real-time Polling

import { createLivescoresPoller } from 'sportmonks-typescript-sdk'

// Poll for live scores every 10 seconds
const poller = createLivescoresPoller(() => client.livescores.inplay().get(), {
  interval: 10000,
  onData: data => {
    console.log('Live update:', data)
  },
  onError: error => {
    console.error('Polling error:', error)
  },
})

poller.start()
// Later: poller.stop();

Date Helpers

import { formatDate, getToday, getDaysFromNow } from 'sportmonks-typescript-sdk'

// Get fixtures for today
const today = await client.fixtures.byDate(getToday()).get()

// Get fixtures for next week
const nextWeek = await client.fixtures.byDateRange(getToday(), getDaysFromNow(7)).get()

Rate Limiting

The SDK automatically handles rate limiting information returned by the API:

const response = await client.leagues.all().get()

console.log(response.rate_limit?.remaining) // Requests remaining
console.log(response.rate_limit?.resets_in_seconds) // Reset time

With retry enabled, the SDK will automatically wait and retry when rate limits are exceeded.

Error Handling

import { SportMonksError } from 'sportmonks-typescript-sdk'

try {
  const team = await client.teams.byId(99999).get()
} catch (error) {
  if (error instanceof SportMonksError) {
    console.error('API Error:', error.message)
    console.error('Status Code:', error.statusCode)
    console.error('API Message:', error.apiMessage)
  }
}

Type Safety

All responses are fully typed:

import type { Team, League, Fixture } from '@withqwerty/sportmonks-typescript-sdk'

const fixture: Fixture = await client.fixtures.byId(18535517).get()
const homeTeam: Team = fixture.localteam!
const league: League = fixture.league!

Type Helpers

The SDK includes type helper utilities for better type safety:

import { hasInclude, TeamWithCountry, sortByName } from '@withqwerty/sportmonks-typescript-sdk'

const team = await client.teams.byId(1).include(['country']).get()

// Type-safe include checking
if (hasInclude(team.data, 'country')) {
  console.log(team.data.country.name) // ✅ TypeScript knows country exists
}

// Pre-defined types for common includes
function processTeam(team: TeamWithCountry) {
  console.log(`${team.name} from ${team.country.name}`)
}

// Type-safe sorting
const teams = await client.teams.all().get()
const sorted = teams.data.sort(sortByName)

See Type Helpers Guide for complete documentation.

API Coverage

Implemented Endpoints

Core Resources

  • Leagues (8 endpoints)
  • Teams (5 endpoints)
  • Fixtures (13 endpoints)
  • Players (5 endpoints)
  • Standings (5 endpoints)
  • Livescores (3 endpoints)

Additional Resources

  • Transfers (6 endpoints)
  • Coaches (5 endpoints)
  • Referees (5 endpoints)
  • Venues (4 endpoints)

Enhancements

  • Automatic retry with exponential backoff
  • Real-time polling utilities
  • Date validation and formatting
  • Input validation
  • Comprehensive TypeScript types
  • Response metadata (rate limits, subscription)

Not Implemented

  • Odds/Betting endpoints
  • Predictions
  • TV Stations

Full Documentation

For complete documentation, examples, and API reference, visit our documentation site.

Requirements

  • Node.js >= 14
  • TypeScript >= 4.5 (for development)
  • Valid SportMonks API key (Get one here)

NB: Check your subscription plan to see which endpoints you have access to

Testing

# Set your API key for integration tests
export SPORTMONKS_TEST_API_KEY=your_api_key_here

# Run all tests
npm test

# Run unit tests only
npm run test:unit

# Run integration tests (requires API key)
SPORTMONKS_TEST_API_KEY=your_key npm run test:integration

# Run tests with coverage
npm run test:coverage

Performance Considerations

  • Rate Limits: 3000 requests/hour per resource (automatically handled)
  • Response Size: Use select() to request only needed fields
  • Caching: Implement application-level caching for frequently accessed data
  • Polling: Use built-in polling utilities instead of manual intervals

Common Issues

Include Parameters Not Working

Some includes require premium subscriptions. Check the error message for details.

Filters Not Supported

Not all endpoints support all filters. The API will return helpful error messages indicating which filters are available.

Transfer Endpoint Semicolon

The transfers endpoint requires semicolon separators for includes:

const client = new SportMonksClient(API_KEY, { includeSeparator: ';' })

Interactive REPL

The SDK includes an interactive REPL (Read-Eval-Print Loop) for testing and exploring the API:

# Start the REPL
npm run repl

# Advanced REPL with more features
npm run repl:advanced

In the REPL, you can run queries directly:

// No need to type 'client.' - just use the resources directly
await teams.search('Liverpool').get()
await fixtures.byDate('2024-01-15').include(['localteam', 'visitorteam']).get()
await leagues.all().limit(5).get()

See docs/REPL.md for full REPL documentation.

Migration Guide

Migrating from Previous Versions

If you're migrating from an older version that used method-based API calls, here's how to update your code:

Old API (method-based)

// Old way
const leagues = await client.getLeagues({
  page: 1,
  per_page: 50,
  include: ['country', 'seasons'],
})

const team = await client.getTeam(1, { include: ['squad'] })

New API (resource-based)

// New way
const leagues = await client.leagues.all().page(1).perPage(50).include(['country', 'seasons']).get()

const team = await client.teams.byId(1).include(['squad']).get()

Key Changes

  1. Resource-based Architecture: Methods are now organized by resource (leagues, teams, fixtures, etc.)
  2. Fluent Query Builder: Chain methods to build your query before calling .get()
  3. Response Structure: All responses now return { data: T } instead of just T
  4. Type Imports: Import from @withqwerty/sportmonks-typescript-sdk instead of the old package name

Currently Missing Methods

The following methods from the old SDK are not yet implemented:

  • Player career methods: players.careerStatistics(), players.transfers(), players.career()
  • Extended squad methods: teams.extendedSquad()

These will be added in future releases.

Changelog

See CHANGELOG.md for release history.

License

MIT - see LICENSE for details.

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/rahulkeerthi/sportmonks-typescript-sdk.git

# Install dependencies
npm install

# Run tests
npm test

# Build the project
npm run build

Support

Credits

Built with ❤️ by Rahul Keerthi

Special thanks to SportMonks for providing an excellent sports data API.