Quickstart
Five minutes to your first endpoint call. This guide walks you through: getting a token, your first HTTP request, and your first WebSocket subscription.
1. Get an API token
We issue API tokens manually after agreeing on a plan. Email us:
hello@ds2.app — tell us which competitions you need and in what form (HTTP only, or HTTP+WS).
You'll receive a Bearer token that looks like:
14|PdsNjlFjl9MwSEuXhXs1xdgXRFwHQ4mQKgRjNsfH4b750a06⚠️ Treat it like a password. Never commit it to git. If it leaks — let us know, we'll revoke it and issue a new one.
2. Your first HTTP call
Every endpoint requires an Authorization: Bearer {token} header. Check what your token is authorized for:
curl https://stats-api.ds2.app/api/v1/me \
-H "Authorization: Bearer YOUR_TOKEN"Response:
{
"data": {
"client": {
"id": 12,
"name": "Acme Sports",
"plan": "pro",
"rate_limit_per_minute": 3000,
"allow_websocket": true
},
"access": {
"all_competitions": false,
"competition_ids": [4, 5],
"competition_count": 2
}
}
}3. Fetch competition standings
curl https://stats-api.ds2.app/api/v1/competitions/4/standings \
-H "Authorization: Bearer YOUR_TOKEN"Returns positions, points, point differential, wins/losses — authoritative from DScore (with correct head-to-head tiebreakers applied).
4. Subscribe to a live match
A WebSocket subscription delivers every stat event in <100ms. First install the clients:
npm install laravel-echo pusher-jsimport Echo from 'laravel-echo'
import Pusher from 'pusher-js'
window.Pusher = Pusher
const echo = new Echo({
broadcaster: 'reverb',
key: 'stats-admin-public-key',
wsHost: 'stats-api.ds2.app',
wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
authEndpoint: 'https://stats-api.ds2.app/api/v1/broadcasting/auth',
auth: {
headers: {
Authorization: 'Bearer YOUR_TOKEN',
},
},
})
// Match ID 123 — must belong to a competition included in your subscription
echo.private('match.123')
.listen('.event.received', (data) => {
console.log('New event:', data)
// data = { match_id, home_score, away_score, event: { type, team_id, player_id, x, y, ... } }
})
.listen('.status.changed', (data) => {
console.log('Match status:', data.status)
})Next
- Authentication and rate limits — how tokens work, headers, errors
- REST endpoints — full list of HTTP routes
- WebSocket integration — channels, events, auth flow
- Code examples — snippets in Node.js, PHP, Python