DocumentationBulk export
Volleyball point-by-point export
GET/v1/export/points
Every rally of every match between two days in one call, up to 14 days at a time: the score after each rally, who won it and who served.
Parameters
Parameters marked required must be sent; the rest are 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 |
|---|---|---|---|
from | date | First day of a range. Send with to; a range covers 31 days at most. | 2026-10-11 |
to | date | Last day of the range, included. | 2026-10-11 |
discipline | enum | One of indoor, beach. | indoor |
gender | enum | One of men, women, mixed. | men |
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.
# Every rally of every match between two days in one call (up to 14 days) curl "https://api.volleyballapi.com/v1/export/points?from=2026-10-11&to=2026-10-11" \ -H "Authorization: Bearer $VBA_KEY"
$q = http_build_query(['from' => '2026-10-11', 'to' => '2026-10-11']); $ch = curl_init('https://api.volleyballapi.com/v1/export/points?' . $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/export/points", params={"from": "2026-10-11", "to": "2026-10-11"}, headers={"Authorization": f"Bearer {os.environ['VBA_KEY']}"}, ) print(r.json()["data"])
const res = await fetch("https://api.volleyballapi.com/v1/export/points?from=2026-10-11&to=2026-10-11", { 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": [
{
"match": "mt_hnqdc25s",
"date": "2026-10-11",
"sets": [
{
"set": 1,
"rallies": [
{ "a": 0, "b": 1, "won_by": "b", "served_by": "b" },
{ "a": 1, "b": 1, "won_by": "a", "served_by": "b" },
{ "a": 1, "b": 2, "won_by": "b", "served_by": "a" }
]
}
]
}
],
"meta": {
"plan": "Complete",
"from": "2026-10-11",
"to": "2026-10-11",
"count": 67,
"rallies": 10577
}
}Fields
| Field | Type | What it holds |
|---|---|---|
data[].match, data[].date | string | The match id and its day |
data[].sets | array | As /v1/matches/{id}/points: per set, every rally |
meta.count, meta.rallies | int | Matches and rallies in the range |
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 a required parameter left out |
| 401 | unauthorized | No key, or a key that is not known or was revoked |
| 403 | upgrade_required | Your plan does not include this endpoint; the answer names the plans that do |
| 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. This endpoint answers on the Complete plans.