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:

GET /api/v1/mebash
curl https://stats-api.ds2.app/api/v1/me \
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

json
{
  "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

GET /api/v1/competitions/{id}/standingsbash
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:

bash
npm install laravel-echo pusher-js
client.jsjavascript
import 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

Need help?
Email us — we usually reply within 24h.
hello@ds2.app