Code examples

Copy-paste-ready snippets in a few popular languages.

Node.js — basic fetch

fetch-standings.jsjavascript
const TOKEN = process.env.STATS_API_TOKEN
const COMP_ID = 4

const res = await fetch(`https://stats-api.ds2.app/api/v1/competitions/${COMP_ID}/standings`, {
  headers: { Authorization: `Bearer ${TOKEN}` },
})
if (!res.ok) throw new Error(`API ${res.status}`)
const { data } = await res.json()
console.table(data.teams.map(t => ({
  pos: t.position, name: t.name, points: t.points, diff: t.point_diff,
})))

Node.js — live match monitor

monitor-match.jsjavascript
import Echo from 'laravel-echo'
import Pusher from 'pusher-js'
global.WebSocket = (await import('ws')).WebSocket // Node doesn't have WS natively
global.Pusher = Pusher

const TOKEN = process.env.STATS_API_TOKEN
const MATCH_ID = 123

const echo = new Echo({
  broadcaster: 'reverb',
  key: 'stats-admin-public-key',
  wsHost: 'stats-api.ds2.app',
  wssPort: 443,
  forceTLS: true,
  enabledTransports: ['ws'],
  authEndpoint: 'https://stats-api.ds2.app/api/v1/broadcasting/auth',
  auth: { headers: { Authorization: `Bearer ${TOKEN}` } },
})

echo.private(`match.${MATCH_ID}`)
  .listen('.event.received', (d) => {
    console.log(`[${d.event.period}Q ${d.event.clock}] ${d.event.type} — ${d.home_score}:${d.away_score}`)
  })
  .listen('.status.changed', (d) => {
    console.log(`Status: ${d.status}`)
    if (d.status === 'finished') process.exit(0)
  })

console.log('Listening… Ctrl+C to stop.')

PHP — with Guzzle

StatsApiClient.phpphp
<?php
use GuzzleHttp\Client;

class StatsApiClient {
    private Client $http;

    public function __construct(string $token) {
        $this->http = new Client([
            'base_uri' => 'https://stats-api.ds2.app/api/v1/',
            'headers' => ['Authorization' => "Bearer {$token}"],
            'timeout' => 10,
        ]);
    }

    public function standings(int $competitionId): array {
        $res = $this->http->get("competitions/{$competitionId}/standings");
        return json_decode($res->getBody(), true)['data'];
    }

    public function match(int $matchId): array {
        return json_decode($this->http->get("matches/{$matchId}")->getBody(), true)['data'];
    }

    public function boxScore(int $matchId): array {
        return json_decode($this->http->get("matches/{$matchId}/box-score")->getBody(), true)['data'];
    }
}

$client = new StatsApiClient(getenv('STATS_API_TOKEN'));
$standings = $client->standings(4);
foreach ($standings['teams'] as $t) {
    printf("%2d. %-30s %d\n", $t['position'], $t['name'], $t['points']);
}

Python — requests

stats_api.pypython
import os
import requests

BASE = 'https://stats-api.ds2.app/api/v1'
TOKEN = os.environ['STATS_API_TOKEN']
HEADERS = {'Authorization': f'Bearer {TOKEN}'}


def get_standings(competition_id: int) -> list[dict]:
    r = requests.get(f'{BASE}/competitions/{competition_id}/standings', headers=HEADERS, timeout=10)
    r.raise_for_status()
    return r.json()['data']['teams']


def get_box_score(match_id: int) -> dict:
    r = requests.get(f'{BASE}/matches/{match_id}/box-score', headers=HEADERS, timeout=10)
    r.raise_for_status()
    return r.json()['data']


if __name__ == '__main__':
    for t in get_standings(4):
        print(f"{t['position']:2}. {t['name']:30} {t['points']}")

Python — live WebSocket with pysher

live_match.pypython
import os
import requests
import pysher

TOKEN = os.environ['STATS_API_TOKEN']
MATCH_ID = 123
APP_KEY = 'stats-admin-public-key'

pusher = pysher.Pusher(
    key=APP_KEY,
    host='stats-api.ds2.app',
    port=443,
    secure=True,
    custom_host='stats-api.ds2.app',
)

def get_auth(socket_id: str, channel: str) -> str:
    r = requests.post(
        'https://stats-api.ds2.app/api/v1/broadcasting/auth',
        headers={'Authorization': f'Bearer {TOKEN}'},
        data={'socket_id': socket_id, 'channel_name': channel},
    )
    r.raise_for_status()
    return r.json()['auth']

def on_connect(data):
    socket_id = pusher.connection.socket_id
    channel_name = f'private-match.{MATCH_ID}'
    auth = get_auth(socket_id, channel_name)
    channel = pusher.subscribe(channel_name, auth=auth)
    channel.bind('event.received', lambda d: print(f'Event: {d}'))
    channel.bind('status.changed', lambda d: print(f'Status: {d}'))

pusher.connection.bind('pusher:connection_established', on_connect)
pusher.connect()

input('Press Enter to disconnect\n')

cURL quick tests

bash
# My account
curl https://stats-api.ds2.app/api/v1/me -H "Authorization: Bearer $TOKEN"

# Every allowed competition
curl https://stats-api.ds2.app/api/v1/competitions -H "Authorization: Bearer $TOKEN"

# Standings
curl https://stats-api.ds2.app/api/v1/competitions/4/standings -H "Authorization: Bearer $TOKEN"

# Schedule — upcoming matches only
curl "https://stats-api.ds2.app/api/v1/competitions/4/schedule?time=upcoming&limit=10" \
  -H "Authorization: Bearer $TOKEN"

# Box score
curl https://stats-api.ds2.app/api/v1/matches/123/box-score -H "Authorization: Bearer $TOKEN"

# Play-by-play
curl https://stats-api.ds2.app/api/v1/matches/123/play-by-play -H "Authorization: Bearer $TOKEN"