DocumentationMatches
Volleyball matches API
GET/v1/matches
Matches on one day or between two days, indoor and beach, filtered by discipline, gender, status, competition or team. Every match carries the set-by-set score, durations, round and pool, and comes back once even when it was played under two names.
Parameters
All optional. Send date, or from and to, not both. With no day, range, competition or team you get today. 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 |
|---|---|---|---|
date | date | One day, in the venue's own calendar. Today when no day, range, competition or team is given. | 2023-08-30 |
from | date | First day of a range. Send with to; a range covers 31 days at most. | 2026-10-12 |
to | date | Last day of the range, included. | 2026-10-12 |
discipline | enum | One of indoor, beach. | indoor |
gender | enum | One of men, women, mixed. | women |
status | enum | One of scheduled, live, finished, awarded, cancelled. | scheduled |
competition | id | A competition id, cp_. | |
team | id | A team id, tm_. Matches under every name the team has played as. | |
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.
# Matches on a day or between two days, filtered by discipline, gender, status, competition or team curl "https://api.volleyballapi.com/v1/matches?date=2023-08-30&gender=women" \ -H "Authorization: Bearer $VBA_KEY"
$q = http_build_query(['date' => '2023-08-30', 'gender' => 'women']); $ch = curl_init('https://api.volleyballapi.com/v1/matches?' . $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/matches", params={"date": "2023-08-30", "gender": "women"}, headers={"Authorization": f"Bearer {os.environ['VBA_KEY']}"}, ) print(r.json()["data"])
const res = await fetch("https://api.volleyballapi.com/v1/matches?date=2023-08-30&gender=women", { 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": "mt_tsgn6rdt",
"discipline": "beach",
"gender": "women",
"status": "finished",
"current_set": null,
"date": "2023-08-30",
"time_local": "21:00",
"start_utc": null,
"competition": {
"id": "cp_ad93tcps",
"name": "yuh Beachmasters Bern",
"season": 2023
},
"round": null,
"pool": null,
"team_a": { "id": "tm_hshj0353", "name": "Hüberli/Brunner" },
"team_b": { "id": "tm_5zxmphfc", "name": "Betschart, M./Marolf" },
"score": { "a": 2, "b": 0 },
"winner": "a",
"sets": [
{ "set": 1, "a": 21, "b": 16, "duration_s": 1140 },
{ "set": 2, "a": 21, "b": 18, "duration_s": 1140 }
],
"sets_complete": true,
"duration_s": 2280,
"updated_utc": "2026-09-29T12:37:06Z"
},
{
"id": "mt_40454qnx",
"discipline": "beach",
"gender": "women",
"status": "finished",
"current_set": null,
"date": "2023-08-30",
"time_local": "16:00",
"start_utc": null,
"competition": {
"id": "cp_ad93tcps",
"name": "yuh Beachmasters Bern",
"season": 2023
},
"round": null,
"pool": null,
"team_a": { "id": "tm_f0dnkt3x", "name": "Menia/Lutz A." },
"team_b": { "id": "tm_16wy4gb5", "name": "Kernen/Annique" },
"score": { "a": 2, "b": 0 },
"winner": "a",
"sets": [
{ "set": 1, "a": 21, "b": 9, "duration_s": 840 },
{ "set": 2, "a": 21, "b": 15, "duration_s": 1140 }
],
"sets_complete": true,
"duration_s": 1980,
"updated_utc": "2026-09-29T12:37:06Z"
},
...
],
"meta": {
"plan": "Complete",
"count": 25,
"next_cursor": null,
"page": 1,
"per_page": 50,
"total": 25,
"total_pages": 1,
"next_page": null,
"prev_page": null
}
}Fields
The same match object comes back from every list. GET /v1/matches/{id} adds venue, city, country, spectators, referees and links to the rallies and player figures when they exist.
| Field | Type | What it holds |
|---|---|---|
id | string | Stable match id, mt_ |
discipline | enum | indoor or beach |
gender | enum | men, women or mixed |
status | enum | scheduled, live, finished, awarded or cancelled |
current_set | int | The set being played, while live; otherwise null |
date, time_local | date, time | The venue's calendar day and clock |
start_utc | datetime | Scheduled start in UTC, ISO 8601 |
competition | object | id, name and season |
round, pool | string | "Semifinals", "Pool B", or null |
team_a, team_b | object | id and name: a club, a national team or a beach pair |
score | object | Sets won by each side |
winner | enum | a or b, null until finished |
sets | array | Each set: number, points each side, duration in seconds |
sets_complete | bool | false when the source's set scores do not add up to its result, so some sets are missing |
duration_s | int | Match length in seconds |
updated_utc | datetime | When anything in the match last changed |
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 | date and from/to sent together, a range over 31 days, to before from, a malformed date or per_page outside 1 to 200 |
| 401 | unauthorized | No key, or a key that is not known or was revoked |
| 403 | upgrade_required | A day outside your plan: the free key reads today and yesterday, Live the last 30 days |
| 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.