DocumentationCompetitions
Volleyball standings and league tables API
GET/v1/competitions/{id}/standings
The table for every pool or league phase of a competition, worked out from its finished matches, one for each stage and pool: played, won, lost, league points, sets and points for and against, and the last five results. Indoor tables give 3 points for a 3-0 or 3-1 win, 2 for a 3-2 win and 1 for a 3-2 loss, and rank by points, then wins, set ratio and point ratio. Beach pools give 2 for a win and 1 for a loss and rank by wins. Knockout rounds are left out unless you ask for them.
Parameters
All optional. Days you can read depend on your plan: the free key reads today and yesterday, Live the last 30 days, Archive and Complete every season since 2001.
| Name | Type | What it does | Example |
|---|---|---|---|
id | path | The competition id, in the address. Required. | cp_n3fgwt1r |
stage | enum | table (the default) counts league and pool matches only; all counts every finished match, knockout rounds included. | table |
pool | text | Only the tables whose pool or stage name contains this, like Pool B or Winners. |
Request
Send your key in the Authorization header as a Bearer token, or in X-API-Key. A key in the address is refused, so it never ends up in a log.
# League tables for a competition, one per pool, worked out from its results curl "https://api.volleyballapi.com/v1/competitions/cp_n3fgwt1r/standings" \ -H "Authorization: Bearer $VBA_KEY"
$ch = curl_init('https://api.volleyballapi.com/v1/competitions/cp_n3fgwt1r/standings'); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('VBA_KEY')], CURLOPT_RETURNTRANSFER => true, ]); $res = json_decode(curl_exec($ch), true); print_r($res['data']);
import os, requests r = requests.get( "https://api.volleyballapi.com/v1/competitions/cp_n3fgwt1r/standings", headers={"Authorization": f"Bearer {os.environ['VBA_KEY']}"}, ) print(r.json()["data"])
const res = await fetch("https://api.volleyballapi.com/v1/competitions/cp_n3fgwt1r/standings", { headers: { "X-API-Key": process.env.VBA_KEY }, }); const { data, meta } = await res.json();
Response
Every answer is data plus meta. This is a real answer to the request above, counted 2026-10-12, with long lists cut short.
{
"data": {
"competition": {
"id": "cp_n3fgwt1r",
"name": "Club Friendly",
"discipline": "indoor",
"gender": "men",
"season": null
},
"tables": [
{
"stage": null,
"pool": null,
"rows": [
{
"rank": 1,
"team": { "id": "tm_e67np8na", "name": "Unirea Dej" },
"played": 6,
"won": 4,
"lost": 2,
"points": 13,
"sets_won": 14,
"sets_lost": 7,
"set_ratio": 2,
"points_won": 498,
"points_lost": 454,
"point_ratio": 1.097,
"form": "LLWWW"
},
{
"rank": 2,
"team": { "id": "tm_c6sryc7f", "name": "Slovan Bratislava" },
"played": 3,
"won": 3,
"lost": 0,
"points": 9,
"sets_won": 9,
"sets_lost": 1,
"set_ratio": 9,
"points_won": 250,
"points_lost": 224,
"point_ratio": 1.116,
"form": "WWW"
},
{
"rank": 3,
"team": { "id": "tm_9khjmvfr", "name": "Craiova" },
"played": 4,
"won": 3,
"lost": 1,
"points": 9,
"sets_won": 9,
"sets_lost": 4,
"set_ratio": 2.25,
"points_won": 304,
"points_lost": 269,
"point_ratio": 1.13,
"form": "WWLW"
},
{
"rank": 4,
"team": { "id": "tm_90nj8th8", "name": "Ziraat Bankasi" },
"played": 3,
"won": 3,
"lost": 0,
"points": 8,
"sets_won": 9,
"sets_lost": 3,
"set_ratio": 3,
"points_won": 292,
"points_lost": 249,
"point_ratio": 1.173,
"form": "WWW"
},
...
]
}
]
},
"meta": { "plan": "Complete", "matches": 73, "pending": 0, "tables": 1 }
}Fields
| Field | Type | What it holds |
|---|---|---|
competition | object | id, name, discipline, gender and season |
tables | array | One entry a table: stage and pool (null where the competition has none) and rows |
rows[].rank | int | Place in the table |
rows[].team | object | id and name |
rows[].played, won, lost | int | Matches counted |
rows[].points | int | League points |
rows[].sets_won, sets_lost, set_ratio | mixed | Sets for and against |
rows[].points_won, points_lost, point_ratio | mixed | Rally points for and against, where every set is known |
rows[].form | string | Last five results, newest last: W or L |
meta.matches | int | Finished matches counted |
meta.pending | int | Matches in the table still to be played |
Errors
Errors come back as {"error": {"code", "message", "docs"}}, with plan and pricing added when a plan would answer. Every error.
| HTTP | Code | When |
|---|---|---|
| 400 | bad_request | A value of the wrong shape |
| 401 | unauthorized | No key, or a key that is not known or was revoked |
| 404 | not_found | An id that does not exist |
| 422 | unknown_parameter | A parameter this endpoint does not take; the answer lists the ones it does |
| 429 | rate_limited | Too many calls this minute; Retry-After says when to try again |
| 429 | quota_exceeded | The day's or month's allowance is used; the answer says when it resets |
Try it
Fill in what you need; the request is built as you type. Paste your key to run it here, straight against the API.