Round-robin leagues have a standings table; knockout tournaments have a bracket. The Olympics, World Championship playoff rounds, and continental championships all eventually narrow down to elimination rounds — and Live Volleyball API surfaces this structure directly through a bracket field, rather than making you reconstruct it from a flat match list.
Where Bracket Data Appears
Two endpoints return a bracket object:
/league_fixtures— the full tournament's bracket structure/live_match_details— the bracket context for one specific match, including round names
For round-robin leagues (regular domestic seasons, most league play), bracket is simply null — this field only populates for knockout-stage competitions.
Fetching a Tournament's Bracket
import requests
response = requests.get(
'https://live-volleyball-api.com/api/v1/league_fixtures',
params={'api_key': 'YOUR_KEY', 'league_id': 'b823d3cc-6286-1e9b-8ed5-e492f1761c40', 'lang': 'en'}
).json()
bracket = response['data']['bracket']
if bracket is None:
print("This is a round-robin league — no bracket")
else:
print("Rounds:", bracket['round_names'])
Understanding the Bracket Structure
The bracket has two parts: round_names (an ordered list like ["Round of 16", "Quarterfinal", "Semifinal", "Final"]) and rounds (an array of ties, one sub-array per round, in the same order as the names):
function BracketView({ bracket }) {
if (!bracket) return <p>No bracket available — this is a league format.</p>;
return (
<div className="bracket">
{bracket.round_names.map((roundName, i) => (
<div key={roundName} className="bracket-round">
<h3>{roundName}</h3>
{(bracket.rounds[i] || []).map((tie, j) => (
<BracketTie key={j} tie={tie} />
))}
</div>
))}
</div>
);
}
Handling Rounds That Haven't Been Played Yet
Early in a tournament, later rounds exist in round_names as labels but their corresponding entry in rounds is often an empty array — the bracket knows the tournament format before it knows who's actually reached each stage:
function BracketRound({ name, ties }) {
if (!ties || ties.length === 0) {
return (
<div className="bracket-round bracket-round-pending">
<h3>{name}</h3>
<p className="tbd">Teams to be determined</p>
</div>
);
}
return (
<div className="bracket-round">
<h3>{name}</h3>
{ties.map((tie, i) => <BracketTie key={i} tie={tie} />)}
</div>
);
}
Showing a Match's Position Within the Bracket
Rather than building a full bracket visualization for a single match page, /live_match_details gives you just enough context — the tournament's round names — to show "this match is the Quarterfinal" without fetching the entire bracket tree:
const response = await fetch(
`.../live_match_details?api_key=YOUR_KEY&match_id=${matchId}&lang=en`
);
const data = (await response.json()).data;
if (data.bracket) {
console.log(`Tournament stage: ${data.bracket.round_names.join(' → ')}`);
}
Combining Bracket View with a Match Detail Link
A typical bracket UI links each tie through to the actual match page — pair the bracket structure with each tie's id (assuming ties carry match references) to make the whole bracket clickable:
function BracketTie({ tie }) {
return (
<a href={`/match/${tie.id}`} className="bracket-tie">
<div className="tie-team">
<img src={tie.home.logo} alt="" />
<span>{tie.home.name}</span>
<strong>{tie.home.sets}</strong>
</div>
<div className="tie-team">
<img src={tie.away.logo} alt="" />
<span>{tie.away.name}</span>
<strong>{tie.away.sets}</strong>
</div>
</a>
);
}
Detecting League vs Knockout Format Automatically
Since bracket is simply null for round-robin competitions, you can use its presence to decide which UI to render for a given league without maintaining your own list of which competitions use which format:
function CompetitionView({ league_id, fixtures }) {
return fixtures.bracket
? <BracketView bracket={fixtures.bracket} />
: <StandingsTable league_id={league_id} />;
}
This is more reliable than hardcoding a list of "which competitions are knockout format," since that list would need manual maintenance as new tournaments get added.
Frequently Asked Questions
Can a competition have both a group stage and a bracket?
Yes, many tournaments (World Championship, Olympics) run round-robin group stages followed by a knockout bracket — in that case, use /league_standings for the group phase and check bracket from /league_fixtures for the elimination phase once it begins.
Does the bracket update automatically as later rounds are decided?
Yes, since the bracket is fetched live from /league_fixtures, re-fetching after a round concludes will show newly-determined ties for the next round rather than an empty placeholder.
Is round_names always the same four stages (Round of 16 through Final)?
No, the number and names of rounds depend on the tournament format — a smaller competition might only have a Semifinal and Final, while a larger one could include Round of 32. Always render whatever round_names actually contains rather than assuming a fixed set.
What happens if I call league_fixtures for a round-robin league?
The weeks array populates normally with the regular season schedule, and bracket simply returns null — no error, just an empty bracket field indicating the format doesn't apply.