Tournament Brackets
Build interactive tournament bracket visualizations
Fetching Tournament Data
// Get tournament details and bracket
const { data: tournament } = await cito.valorant.tournaments.get('vct-americas-2026');
// Response includes bracket structure
{
"id": "vct-americas-2026",
"name": "VCT Americas 2026",
"format": "double_elimination",
"teams": [...],
"bracket": {
"upper": [
{
"round": 1,
"matches": [
{
"id": "match_1",
"team_a": { "id": "sen", "name": "Sentinels", "score": 2 },
"team_b": { "id": "c9", "name": "Cloud9", "score": 1 },
"status": "completed",
"winner": "sen"
}
]
}
],
"lower": [...],
"grand_final": {...}
}
}Bracket Component
TournamentBracket.tsx
interface Match {
id: string;
team_a: Team | null;
team_b: Team | null;
winner: string | null;
status: 'upcoming' | 'live' | 'completed';
}
interface Round {
round: number;
matches: Match[];
}
function BracketMatch({ match }: { match: Match }) {
return (
<div className={`bracket-match ${match.status}`}>
<div className={`team ${match.winner === match.team_a?.id ? 'winner' : ''}`}>
<span>{match.team_a?.name || 'TBD'}</span>
<span>{match.team_a?.score ?? '-'}</span>
</div>
<div className={`team ${match.winner === match.team_b?.id ? 'winner' : ''}`}>
<span>{match.team_b?.name || 'TBD'}</span>
<span>{match.team_b?.score ?? '-'}</span>
</div>
{match.status === 'live' && (
<span className="live-indicator">LIVE</span>
)}
</div>
);
}
function BracketRound({ round, roundNumber }: { round: Round; roundNumber: number }) {
return (
<div className="bracket-round">
<h4>Round {roundNumber}</h4>
<div className="matches">
{round.matches.map(match => (
<BracketMatch key={match.id} match={match} />
))}
</div>
</div>
);
}
export function TournamentBracket({ tournament }) {
return (
<div className="tournament-bracket">
<h2>{tournament.name}</h2>
<div className="upper-bracket">
<h3>Upper Bracket</h3>
<div className="rounds">
{tournament.bracket.upper.map((round, i) => (
<BracketRound key={i} round={round} roundNumber={i + 1} />
))}
</div>
</div>
<div className="lower-bracket">
<h3>Lower Bracket</h3>
<div className="rounds">
{tournament.bracket.lower.map((round, i) => (
<BracketRound key={i} round={round} roundNumber={i + 1} />
))}
</div>
</div>
<div className="grand-final">
<h3>Grand Final</h3>
<BracketMatch match={tournament.bracket.grand_final} />
</div>
</div>
);
}Real-time Updates
Subscribe to tournament events for live bracket updates:
// Subscribe to tournament events
await cito.webhooks.create({
url: 'https://yourapp.com/webhook',
events: [
'tournament.match.started',
'tournament.match.ended',
'tournament.bracket.updated'
],
filters: {
tournament_id: 'vct-americas-2026'
}
});
// Handle updates in your app
socket.on('bracket-update', (data) => {
setBracket(prev => ({
...prev,
...data.bracket
}));
});Standings Table
// Get tournament standings
const { data: standings } = await cito.valorant.tournaments.standings('vct-americas-2026');
function StandingsTable({ standings }) {
return (
<table>
<thead>
<tr>
<th>#</th>
<th>Team</th>
<th>W</th>
<th>L</th>
<th>Map Diff</th>
<th>Points</th>
</tr>
</thead>
<tbody>
{standings.map((team, i) => (
<tr key={team.id}>
<td>{i + 1}</td>
<td>{team.name}</td>
<td>{team.wins}</td>
<td>{team.losses}</td>
<td>{team.map_diff > 0 ? '+' : ''}{team.map_diff}</td>
<td>{team.points}</td>
</tr>
))}
</tbody>
</table>
);
}