DocumentationCompetitions
Volleyball competitions API
GET/v1/competitions
Competitions newest first, from world championships and tours to national leagues and cups, filtered by discipline, gender, season or a word in the name.
Parameters
All optional.
| Name | Type | What it does | Example |
|---|---|---|---|
discipline | enum | One of indoor, beach. | beach |
gender | enum | One of men, women, mixed. | men |
season | int | The year a season starts in, like 2025. | 2025 |
q | text | A word in the competition's name, 2 to 80 characters. | |
page | int | Page number, from 1. Adds totals to meta. | 2 |
per_page | int | Rows a page, 1 to 200. 50 when not sent. | 200 |
cursor | string | The next_cursor from the last answer. Send it alone. |
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.
# Competitions, newest first, filtered by discipline, gender, season or name curl "https://api.volleyballapi.com/v1/competitions?discipline=beach&per_page=2" \ -H "Authorization: Bearer $VBA_KEY"
$q = http_build_query(['discipline' => 'beach', 'per_page' => '2']); $ch = curl_init('https://api.volleyballapi.com/v1/competitions?' . $q); 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", params={"discipline": "beach", "per_page": "2"}, headers={"Authorization": f"Bearer {os.environ['VBA_KEY']}"}, ) print(r.json()["data"])
const res = await fetch("https://api.volleyballapi.com/v1/competitions?discipline=beach&per_page=2", { headers: { "X-API-Key": process.env.VBA_KEY }, }); const { data, meta } = await res.json();
Response
Every answer is data plus meta. A first call with page adds totals to meta; a call with cursor carries only the next cursor, which is quicker over long ranges. This is a real answer to the request above, counted 2026-10-12, with long lists cut short.
{
"data": [
{
"id": "cp_mmra2w7x",
"name": "FIVB Beach Volleyball World Championships",
"discipline": "beach",
"gender": "men",
"season": 2027,
"start_date": "2027-08-13",
"end_date": "2027-08-22",
"country_code": "NL"
},
{
"id": "cp_v15a0yfs",
"name": "FIVB Beach Volleyball World Championships",
"discipline": "beach",
"gender": "women",
"season": 2027,
"start_date": "2027-08-13",
"end_date": "2027-08-22",
"country_code": "NL"
}
],
"meta": {
"plan": "Complete",
"count": 2,
"next_cursor": "eyJvIjoyLCJwIjoyfQ",
"page": 1,
"per_page": 2,
"total": 9291,
"total_pages": 4646,
"next_page": 2,
"prev_page": null
}
}Fields
| Field | Type | What it holds |
|---|---|---|
id | string | Stable competition id, cp_ |
name | string | The competition's name |
discipline | enum | indoor or beach |
gender | enum | men, women or mixed |
season | int | The year the season starts in |
start_date, end_date | date | First and last day, where known |
country_code | string | Two-letter country of a national competition |
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, or per_page outside 1 to 200 |
| 401 | unauthorized | No key, or a key that is not known or was revoked |
| 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.