> ## Documentation Index
> Fetch the complete documentation index at: https://docs-ts.playservices.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Results & Leaderboards

> Access real-time tournament rankings, final results, prize distributions, and historical tournament data

# Results & Leaderboards

The Results & Leaderboards APIs provide access to real-time tournament rankings, final results, prize distributions, and historical tournament data for casino operators.

## Real-time Leaderboards

### Get Tournament Leaderboard

Retrieve current tournament rankings and player positions:

```http theme={null}
GET /api/tournaments/{tournamentId}/leaderboard
Authorization: Bearer {your-api-key}
```

**Query Parameters:**

* `limit` - Number of players to return (default: 50, max: 200)
* `offset` - Pagination offset
* `includeEliminated` - Include eliminated players (default: false)

**Response:**

```json theme={null}
{
  "tournamentId": "12345",
  "status": "in_progress",
  "currentRound": 3,
  "totalRounds": 5,
  "lastUpdated": "2024-01-15T20:25:30Z",
  "leaderboard": [
    {
      "position": 1,
      "playerId": "tp_player_456",
      "displayName": "PlayerName",
      "points": 2150,
      "status": "active",
      "entryCount": 2,
      "totalPaid": 20.00,
      "currentRound": 3,
      "lastActivity": "2024-01-15T20:24:45Z"
    },
    {
      "position": 2,
      "playerId": "tp_player_789",
      "displayName": "TopPlayer",
      "points": 1980,
      "status": "active",
      "entryCount": 1,
      "totalPaid": 10.00,
      "currentRound": 3,
      "lastActivity": "2024-01-15T20:25:20Z"
    }
  ],
  "pagination": {
    "total": 67,
    "limit": 50,
    "offset": 0,
    "hasMore": true
  },
  "prizePool": {
    "totalAmount": 870.00,
    "distribution": {
      "1st": 435.00,
      "2nd": 261.00,
      "3rd": 174.00
    }
  }
}
```

### Live Leaderboard Updates

For real-time leaderboard updates, use polling or WebSocket connections:

```javascript theme={null}
class LiveLeaderboard {
  constructor(tournamentId, apiKey) {
    this.tournamentId = tournamentId;
    this.apiKey = apiKey;
    this.updateInterval = null;
    this.lastUpdate = null;
  }
  
  startPolling(intervalMs = 5000) {
    this.updateInterval = setInterval(async () => {
      try {
        await this.updateLeaderboard();
      } catch (error) {
        console.error('Leaderboard update failed:', error);
      }
    }, intervalMs);
  }
  
  async updateLeaderboard() {
    const url = `/api/tournaments/${this.tournamentId}/leaderboard`;
    const params = this.lastUpdate ? `?since=${this.lastUpdate}` : '';
    
    const response = await fetch(`${url}${params}`, {
      headers: {
        'Authorization': `Bearer ${this.apiKey}`
      }
    });
    
    if (response.ok) {
      const leaderboard = await response.json();
      this.onLeaderboardUpdate(leaderboard);
      this.lastUpdate = leaderboard.lastUpdated;
    }
  }
  
  onLeaderboardUpdate(leaderboard) {
    // Update UI with new leaderboard data
    this.displayLeaderboard(leaderboard.leaderboard);
    this.updatePrizePool(leaderboard.prizePool);
  }
  
  stopPolling() {
    if (this.updateInterval) {
      clearInterval(this.updateInterval);
      this.updateInterval = null;
    }
  }
}
```

## Final Tournament Results

### Get Tournament Results

Retrieve complete tournament results after completion:

```http theme={null}
GET /api/tournaments/{tournamentId}/results
Authorization: Bearer {your-api-key}
```

**Response:**

```json theme={null}
{
  "tournamentId": "12345",
  "name": "Daily Championship",
  "status": "completed",
  "startTime": "2024-01-15T20:00:00Z",
  "endTime": "2024-01-15T21:15:30Z",
  "duration": 4530,
  "gameSlug": "crash-classic",
  "totalPlayers": 87,
  "totalRounds": 5,
  "prizePool": {
    "totalAmount": 870.00,
    "currency": "USD",
    "entryFees": 870.00,
    "operatorFee": 87.00,
    "netPrizePool": 783.00
  },
  "winners": [
    {
      "position": 1,
      "playerId": "tp_player_456",
      "displayName": "ChampionPlayer",
      "finalScore": 2150,
      "entryCount": 2,
      "totalPaid": 20.00,
      "prizeAmount": 391.50,
      "netWinnings": 371.50,
      "survivalTime": 4530,
      "eliminationRound": null
    },
    {
      "position": 2,
      "playerId": "tp_player_789",
      "displayName": "SecondPlace",
      "finalScore": 1980,
      "entryCount": 1,
      "totalPaid": 10.00,
      "prizeAmount": 234.90,
      "netWinnings": 224.90,
      "survivalTime": 4530,
      "eliminationRound": null
    },
    {
      "position": 3,
      "playerId": "tp_player_321",
      "displayName": "ThirdPlace",
      "finalScore": 1750,
      "entryCount": 1,
      "totalPaid": 10.00,
      "prizeAmount": 156.60,
      "netWinnings": 146.60,
      "survivalTime": 4485,
      "eliminationRound": 5
    }
  ],
  "statistics": {
    "averageScore": 1245.5,
    "medianScore": 1150.0,
    "averageSurvivalTime": 2890,
    "totalEntryFees": 870.00,
    "totalRebuys": 23,
    "rebuyRevenue": 230.00,
    "operatorRevenue": 110.00
  },
  "completedAt": "2024-01-15T21:15:30Z"
}
```

### Detailed Player Results

Get individual player performance data:

```http theme={null}
GET /api/tournaments/{tournamentId}/results/players/{playerId}
Authorization: Bearer {your-api-key}
```

**Response:**

```json theme={null}
{
  "tournamentId": "12345",
  "playerId": "tp_player_456",
  "displayName": "ChampionPlayer",
  "finalResults": {
    "position": 1,
    "finalScore": 2150,
    "prizeAmount": 391.50,
    "netWinnings": 371.50
  },
  "participation": {
    "registeredAt": "2024-01-15T19:30:00Z",
    "entryCount": 2,
    "totalPaid": 20.00,
    "rebuyCount": 1,
    "survivalTime": 4530
  },
  "gameplayStats": {
    "totalRounds": 5,
    "roundScores": [
      { "round": 1, "score": 285, "position": 12 },
      { "round": 2, "score": 520, "position": 8 },
      { "round": 3, "score": 890, "position": 5 },
      { "round": 4, "score": 1450, "position": 3 },
      { "round": 5, "score": 2150, "position": 1 }
    ],
    "bestRoundScore": 660,
    "averageRoundScore": 430,
    "positionProgression": [12, 8, 5, 3, 1],
    "gameActions": {
      "totalActions": 47,
      "successfulCashouts": 23,
      "failedCashouts": 12,
      "cashoutRate": 0.489
    }
  }
}
```

## Prize Pool Information

### Get Prize Pool Details

Retrieve current prize pool calculation and distribution:

```http theme={null}
GET /api/tournaments/{tournamentId}/prize-pool
Authorization: Bearer {your-api-key}
```

**Response:**

```json theme={null}
{
  "tournamentId": "12345",
  "status": "in_progress",
  "currentPlayers": 87,
  "prizePool": {
    "type": "percentage",
    "totalAmount": 870.00,
    "currency": "USD",
    "breakdown": {
      "entryFees": 870.00,
      "rebuyFees": 230.00,
      "totalRevenue": 1100.00,
      "operatorFee": 110.00,
      "netPrizePool": 990.00
    },
    "distribution": {
      "percentages": [50, 30, 20],
      "amounts": {
        "1st": 495.00,
        "2nd": 297.00,
        "3rd": 198.00
      }
    },
    "guaranteedPrize": 500.00,
    "lastUpdated": "2024-01-15T20:25:30Z"
  },
  "playerContributions": {
    "totalEntries": 87,
    "totalRebuys": 23,
    "averageEntriesPerPlayer": 1.26
  }
}
```

### Prize Pool Calculations

```javascript theme={null}
// Calculate prize distribution
const calculatePrizeDistribution = (totalPrizePool, distribution, guaranteedPrize) => {
  const actualPrize = Math.max(totalPrizePool, guaranteedPrize);
  const prizes = {};
  
  distribution.forEach((percentage, index) => {
    const position = index + 1;
    const amount = (actualPrize * percentage) / 100;
    prizes[`${position}${getOrdinalSuffix(position)}`] = amount.toFixed(2);
  });
  
  return prizes;
};

const getOrdinalSuffix = (position) => {
  const suffixes = ['th', 'st', 'nd', 'rd'];
  const v = position % 100;
  return suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0];
};
```

## Historical Tournament Data

### List Tournament Results

Retrieve historical tournament results with filtering:

```http theme={null}
GET /api/tournaments?status=completed&gameSlug=crash-classic&limit=20
Authorization: Bearer {your-api-key}
```

**Query Parameters:**

* `status` - Filter by status (`completed` for results)
* `gameSlug` - Filter by game type
* `startDate` - Results from tournaments starting after date
* `endDate` - Results from tournaments starting before date
* `minPlayers` - Minimum player count
* `limit` - Results per page (default: 50, max: 100)
* `offset` - Pagination offset

**Response:**

```json theme={null}
{
  "tournaments": [
    {
      "tournamentId": "12345",
      "name": "Daily Championship",
      "gameSlug": "crash-classic",
      "status": "completed",
      "startTime": "2024-01-15T20:00:00Z",
      "endTime": "2024-01-15T21:15:30Z",
      "duration": 4530,
      "totalPlayers": 87,
      "prizePool": 870.00,
      "winner": {
        "playerId": "tp_player_456",
        "displayName": "ChampionPlayer",
        "prizeAmount": 391.50
      }
    }
  ],
  "pagination": {
    "total": 156,
    "limit": 20,
    "offset": 0,
    "hasMore": true
  },
  "aggregateStats": {
    "totalTournaments": 156,
    "totalPlayers": 13542,
    "totalPrizePool": 135420.00,
    "averagePlayersPerTournament": 86.8
  }
}
```

### Player Tournament History

Get a player's tournament participation history:

```http theme={null}
GET /api/players/{playerId}/tournaments?status=completed&limit=10
Authorization: Bearer {your-api-key}
```

**Response:**

```json theme={null}
{
  "playerId": "tp_player_456",
  "tournaments": [
    {
      "tournamentId": "12345",
      "name": "Daily Championship",
      "gameSlug": "crash-classic",
      "participatedAt": "2024-01-15T19:30:00Z",
      "result": {
        "position": 1,
        "finalScore": 2150,
        "prizeAmount": 391.50,
        "netWinnings": 371.50
      },
      "participation": {
        "entryCount": 2,
        "totalPaid": 20.00,
        "survivalTime": 4530
      }
    }
  ],
  "playerStats": {
    "totalTournaments": 24,
    "totalWinnings": 1248.50,
    "totalSpent": 890.00,
    "netProfit": 358.50,
    "averagePosition": 12.3,
    "winRate": 0.125,
    "bestResult": {
      "position": 1,
      "tournamentId": "12345",
      "prizeAmount": 391.50
    }
  }
}
```

## Analytics & Reporting

### Tournament Performance Metrics

```javascript theme={null}
class TournamentAnalytics {
  constructor(apiKey) {
    this.apiKey = apiKey;
  }
  
  async getTournamentMetrics(tournamentId) {
    const [results, prizePool] = await Promise.all([
      this.getResults(tournamentId),
      this.getPrizePool(tournamentId)
    ]);
    
    return {
      tournament: results,
      performance: {
        participationRate: this.calculateParticipationRate(results),
        playerRetention: this.calculateRetentionRate(results),
        revenueMetrics: this.calculateRevenueMetrics(results, prizePool),
        engagementMetrics: this.calculateEngagementMetrics(results)
      }
    };
  }
  
  calculateParticipationRate(results) {
    const playersWithRebuys = results.winners.filter(w => w.entryCount > 1).length;
    return {
      totalPlayers: results.totalPlayers,
      playersWithRebuys: playersWithRebuys,
      rebuyRate: playersWithRebuys / results.totalPlayers,
      averageEntriesPerPlayer: results.statistics.totalEntryFees / (results.totalPlayers * 10) // Assuming $10 entry
    };
  }
  
  calculateRevenueMetrics(results, prizePool) {
    return {
      totalRevenue: results.statistics.totalEntryFees + results.statistics.rebuyRevenue,
      operatorRevenue: results.statistics.operatorRevenue,
      prizePoolDistributed: prizePool.totalAmount,
      operatorMargin: results.statistics.operatorRevenue / (results.statistics.totalEntryFees + results.statistics.rebuyRevenue),
      revenuePerPlayer: results.statistics.operatorRevenue / results.totalPlayers
    };
  }
}
```

### Real-time Result Streaming

```javascript theme={null}
class ResultsStreamer {
  constructor(tournamentId, apiKey) {
    this.tournamentId = tournamentId;
    this.apiKey = apiKey;
    this.eventSource = null;
  }
  
  startStreaming(onUpdate) {
    const url = `/api/tournaments/${this.tournamentId}/results/stream`;
    
    this.eventSource = new EventSource(url, {
      headers: {
        'Authorization': `Bearer ${this.apiKey}`
      }
    });
    
    this.eventSource.onmessage = (event) => {
      try {
        const update = JSON.parse(event.data);
        onUpdate(update);
      } catch (error) {
        console.error('Failed to parse result update:', error);
      }
    };
    
    this.eventSource.onerror = (error) => {
      console.error('Results stream error:', error);
    };
  }
  
  stopStreaming() {
    if (this.eventSource) {
      this.eventSource.close();
      this.eventSource = null;
    }
  }
}

// Usage
const streamer = new ResultsStreamer('12345', 'your-api-key');
streamer.startStreaming((update) => {
  if (update.type === 'leaderboard_update') {
    updateLeaderboardUI(update.leaderboard);
  } else if (update.type === 'player_eliminated') {
    showEliminationNotification(update.player);
  }
});
```

## Integration Best Practices

<CardGroup cols={2}>
  <Card title="Polling Frequency" icon="clock">
    Use appropriate polling intervals - 5s for active tournaments, 30s for completed tournaments
  </Card>

  <Card title="Caching Strategy" icon="database">
    Cache leaderboard data to reduce API calls and improve user experience
  </Card>

  <Card title="Error Handling" icon="shield">
    Handle API failures gracefully with fallback data and retry mechanisms
  </Card>

  <Card title="Data Validation" icon="check">
    Validate result data consistency before displaying to users
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhooks & Events" icon="bell" href="/casino-integration/webhooks-events">
    Set up real-time tournament event notifications via webhooks.
  </Card>

  <Card title="Testing & Debugging" icon="bug" href="/casino-integration/testing-debugging">
    Tools and techniques for testing your tournament integration.
  </Card>
</CardGroup>
