1. Che cosa permetteno 'e API
Cu 'na chiave API puoie, d'o software tujo, leggere e scrivere 'ncopp'ô calannario d'e strutture toie:
- leggere strutture e campe cu 'e identificative d'e lloro, necessarie pe' tutte l'ati chiammate;
- leggere 'e prenotazzioni 'e 'nu periodo, 'e 'na struttura o 'e 'nu campo sulo, pe' l'allineà a l'archivio tujo;
- crià prenotazzioni da fora (pe' essempio quanno 'nu cliente prenota d'o sito tujo), cu 'e stessi cuntrolle 'e sovrapposizzione e chiusura d'o pannello;
- modificà o scancellà 'na prenotazzione ca già ce sta (spustamento 'e orario o 'e campo, incasso, note, annullamento);
- leggere 'a dispunibilità 'e 'nu campo dint'a 'nu juorno: slot già occupate, orarie 'e apertura e chiusure straordinarie, accussì da prupone 'e slot libbere senza replicà 'e regole;
- leggere 'o listino 'e 'nu campo pe' ammustrà 'e priezze ô cliente finale.
Ogni chiave è legata all'account gestore ca l'ha criata e vede sulo 'e strutture, 'e campe e 'e prenotaziune 'e chillu account. 'Na risorsa ca appartiene a n'ato gestore nun risponne 403 ma 404 not_found: nun ne vene svelata l'esistenza.
Nun fanno parte 'e chesti API 'e richieste d' 'e organizzature pe' l'uso d' 'e campe dint'ê turnee (s'approvano dall'app), 'a criazione 'e strutture e campe, 'o sarvaggio 'e orarie, chiuse e listino: so' operaziune d' 'o pannello gestore.
2. Requisiti e attivazzione
- Un account gestore campe VolleyFriends cu' ammeno 'na struttura e 'nu campo.
- 'Nu abbonamento in corso cu' 'nu piano ca include 'a funzione «API pe' gestionali esterni». L'intera
v1— pure 'e sole letture — è riservata a chi tene chesta funzione: è 'na funzione vennuta, no 'nu accessorio d' 'o pannello. - 'Na chiave API generata d' 'o gestionale: admin.volleyfriends.com → Impostaziune → Chiavi API → Chiave nova.
'A chiave tene 'a forma vfk_ seguito da 40 caratteri esadecimali (44 caratteri in tutto) e vene ammustrata 'na vota sola, sùbbeto doppo 'a criazione: dint'ô database resta sulo l'impronta soja sha256, quinni nun è recuperabile 'n nisciuno modo. Se 'a pierde, revocala e generane 'na nova. Dint'all'elenco d' 'o pannello vide sulo 'o prefisso (es. vfk_9f2c), 'a data 'e criazione e chella d' 'o l'urdemo utilizzo.
3. Autenticazzione
Ogni richiesta va autenticata cu' l'header X-Api-Key. Nun servono token, login, scadenze o rinnovi: 'a chiave resta valida finché nun 'a revochi.
# 'E chiavi 'e chesta pagina so' d'esempio: sostituisci cu' 'a toja.
curl -s https://www.volleyfriends.com/api/manager-api/v1/venues -H "X-Api-Key: vfk_9f2c41a7b83d05e6c19af4728b60d35e1c9a7f42"
Dint'all'esempi ca venono appriesso 'a chiave è letta d' 'a variabile d'ambiente VF_API_KEY, comme conviene fa' pure in produzione.
Header assente, cchiù curto 'e 12 caratteri, scanusciuto o ca appartiene a 'na chiave revocata: 'a risposta è 401 cu' chistu corpo.
{
"error": "invalid_key",
"message": "Chiave API mancante o non valida (header X-Api-Key)."
}
- 'A chiave vale comm'a 'na password cu' chini putere 'ncopp'ô calendario d' 'e strutture toje: nun 'a nzerì dint'a pagine, app o JavaScript lato browser, addò sarría leggibile da chiunque. Usala sulo da server a server.
- Nun 'a mettere dint'ô codice sorgente e manco dint'a 'nu repository: usa 'na variabile d'ambiente o 'nu archivio 'e segreti.
- Usa 'na chiave pe' ogni sistema cullegato (sito, gestionale, script 'e allineamento): accussì puo' revocarne una senza stutà 'e ate.
- Se suspetti ca sia stata esposta, revocala sùbbeto d' 'o pannello: 'a revoca è immediata e nun è maje bloccata d' 'o stato dell'abbonamento. Da chillu mumento ogni chiamata cu' chella chiave riceve
401 invalid_key. - Traffico sulo 'ncopp'a HTTPS; 'o campo «urdemo utilizzo» dint'ô pannello t'aiuta a t'accorgere 'e usi inattesi.
4. Base URL
https://www.volleyfriends.com/api
'E path ducumentati cca sotto vanno accudati 'a base. 'O prefisso /api appartiene ô reverse proxy, quinni l'indirizzo completo 'e 'nu endpoint è pe' esempio:
GET https://www.volleyfriends.com/api/manager-api/v1/availability
Tutte 'e risposte so' application/json cu' codifica UTF-8. 'E richieste cu' corpo (POST, PATCH) hanno da avé Content-Type: application/json.
5. Rate limiting
'O limite è 'e 120 richieste ô minuto pe' chiave API (fenesta scorrevole 'e 1 minuto). 'O cunto è pe' chiave, no pe' ndirizzo IP: 'e gestionali stanno spisso areto ô stesso ndirizzo d' 'o provider e 'nu limite pe' IP penalizzasse gestore diverse ospitate 'ncopp'â stessa nfrastruttura. Se l'header X-Api-Key manca d' 'o tutto, 'o cunto cade 'ncopp'ô ndirizzo IP.
Ogni rispuosta riporta 'o stato d' 'o cuntatore dint'e header x-ratelimit-limit, x-ratelimit-remaining e x-ratelimit-reset (seconne ô reset). Quanno se supera, se mmette pure retry-after.
Rispuosta ô superamento — 429
{
"error": "rate_limited",
"message": "Limite di 120 richieste al minuto superato per questa chiave API."
}
- Pe' l'allineamento periodico ausa una sola chiamata a
/bookingscu 'nu ntervallofrom–tolario, nvece 'e 'na chiamata ô juorno. - Metti 'n cache l'alenco 'e strutture e campe: cagna raramente.
- Dint'ô caso 'e
429aspetta e pruova n'ata vota cu backoff esponenziale (pe' essempio 2, 4, 8 seconne), rispettannoretry-after.
6. Endpoint
Sije endpoint, tutte sotto /manager-api/v1. Ogni chiamata passa p' 'a stessa catena 'e cuntrolle, dint'a l'ordine: chiave API valida → funzione «API per gestionali esterni» nclusa dint'ô chiano → rate limit → validazione d' 'e parametre → verfeca ca 'a risorsa è 'a toja.
6.1 Strutture e campe
/api/manager-api/v1/venuesElenca 'e strutture toje, ognuna cu 'e campe suoje annidate. È 'a chiamata da addò partì: l'id d' 'e campe (courtId) servono a tutte l'ate endpoint. 'E strutture stanno ordinate pe' nomme, 'e campe pe' nomme.
Parametre
Nisciuno.
Essempio 'e richiesta
curl -s https://www.volleyfriends.com/api/manager-api/v1/venues -H "X-Api-Key: $VF_API_KEY"
Essempio 'e rispuosta — 200
{
"venues": [
{
"id": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"name": "Centro Sportivo Aurora",
"city": "Verona",
"address": "Via delle Palestre 12",
"verified": true,
"courts": [
{
"id": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"venueId": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"name": "Campo 1",
"surface": "parquet",
"indoor": true,
"lighting": true
},
{
"id": "e2a71f64-9c03-4bd8-b512-38f6cd90a7e1",
"venueId": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"name": "Campo 2 beach",
"surface": "sabbia",
"indoor": false,
"lighting": true
}
]
}
]
}
Campe d' 'a rispuosta
| Campo | Tipo | Descrizione |
|---|---|---|
venues[].id | uuid | Identificativo d' 'a struttura (venueId dint'a l'ate endpoint). |
venues[].name | string | Nomme d' 'a struttura. |
venues[].city | string | null | Cità. |
venues[].address | string | null | Indirizzo. |
venues[].verified | boolean | true si 'a struttura tene 'o badge VERIFICATO. |
venues[].courts[] | array | Campi d' 'a struttura. Array vacante si nun ne tene. |
courts[].id | uuid | Identificativo d' 'o campo (courtId dint'a l'ati endpoint). |
courts[].venueId | uuid | Struttura a cui appartiene 'o campo. |
courts[].name | string | Nomme d' 'o campo. |
courts[].surface | string | null | Superficie, testo libero nzerito d' 'o gestore. |
courts[].indoor | boolean | Campo a 'o cupierto. |
courts[].lighting | boolean | Illuminazione disponibile. |
Si l'account nun tene ancora strutture 'a rispuosta è {"venues": []}.
Errure specifiche
Nisciuno oltre a chille generali.
6.2 Elenco prenotaziune
/api/manager-api/v1/bookingsRestituisce 'e prenotaziune d' 'e strutture toe, ordinate pe' orario 'e inizio a crescere. L'elenco è paginato: a 'o massimo limit righe pe' chiamata (default 500, tetto 1000) — si riceve overamente limit righe, chiamma n'ata vota cu offset aumentato pe' 'a pagina appriesso. In produzione filtra comunque sempe ammeno pe' intervallo 'e date.
Parametri (query string)
| Nomme | Tipo | Obbl. | Descrizione |
|---|---|---|---|
venueId | uuid | no | Limita a una struttura. Si nun è 'a toja: 404 not_found. |
courtId | uuid | no | Limita a nu campo. Se nun è 'o tujo: 404 not_found. Cumbinato cu nu venueId 'e n'ata struttura toja 'o risultato è n'elenco vacante. |
from | data o istante ISO | no | Estremo 'nferiore 'ncluso. Na data secca AAAA-MM-GG vale 'a mezanotte locale taliana 'e chillu juorno. |
to | data o istante ISO | no | Estremo superiore escluso. Na data secca vale 'a mezanotte locale d''o juorno appriesso: to=2026-08-31 'nclude tutto 'o 31 'e aùsto. |
limit | integer 1–1000 | no | Numero massimo 'e righe (default 500). |
offset | integer ≥ 0 | no | Righe da zumpà (default 0): offset=500 è 'a seconna paggena cu 'o limit 'e default. |
from e to s'applicano a l'istante d'inizio d''a prenotazzione. Na prenotazzione accumminciata primma 'e from e ancora 'n corso doppo nun cumpare: se te serve, allarga l'estremo 'nferiore 'e quacche ora. 'O filtro nun esclude 'e prenotazzione annullate: l'elenco tene pure chelle cu status: "cancelled".
Essempio 'e richiesta
curl -s -G https://www.volleyfriends.com/api/manager-api/v1/bookings -H "X-Api-Key: $VF_API_KEY" --data-urlencode "courtId=7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05" --data-urlencode "from=2026-08-01" --data-urlencode "to=2026-08-31"
Essempio 'e rispuosta — 200
{
"bookings": [
{
"id": "9d51c7b4-0e28-4f3a-a6d9-72b48e105c3f",
"venueId": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"courtId": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"courtName": "Campo 1",
"startsAt": "2026-08-12T16:00:00.000Z",
"endsAt": "2026-08-12T17:30:00.000Z",
"customerName": "Marta Bellini",
"customerPhone": "+39 340 1122334",
"customerEmail": "marta.bellini@example.com",
"priceCents": 3000,
"playersCount": null,
"status": "confirmed",
"paymentMethod": null,
"paymentLink": null,
"notes": "Prenotato dal sito della struttura",
"source": "api",
"recurrenceId": null,
"createdAt": "2026-07-28T09:14:02.517Z",
"updatedAt": "2026-07-28T09:14:02.517Z"
}
],
"limit": 500,
"offset": 0
}
Campi 'e na prenotazzione
'A stessa struttura vene turnata da POST e PATCH (dinto a 'a chiave booking).
| Campo | Tipo | Descrizione |
|---|---|---|
id | uuid | Identificativo d''a prenotazzione. |
venueId | uuid | Struttura. |
courtId | uuid | Campo prenotato. |
courtName | string | Nomme d''o campo, pe' comodità 'e visualizzazzione. |
startsAt | istante ISO | Inizio, sempe in UTC (suffisso Z). |
endsAt | istante ISO | Fine, estremo escluso. |
customerName | string | Nomme d''o cliente. |
customerPhone | string | null | Telefono. |
customerEmail | string | null | Email. |
priceCents | integer | null | Prezzo cuncurdato in centesime. null = da definire (maje 0 pe' «nun definito»). |
playersCount | integer | null | Numero 'e persone dichiarato (sulo prenotaziune 'ncoppa a fasce cu prezzo a persona). null = nun applicabile o nun innicato. |
status | string | pending · confirmed · paid · cancelled — vide stati. |
paymentMethod | string | null | cash · bank_transfer · paypal · stripe · other. null = nun 'ncassato. |
paymentLink | string | null | Link 'e pavamento cu carta generato d''o pannello, se ce sta. Sulo in lettura. |
notes | string | null | Note libbere. |
source | string | Origgene: manual (pannello) · api (sti API) · app (richiesta 'e 'nu jucatore d''a app) · tournament (turneo). |
recurrenceId | uuid | null | Presente e uguale 'ncoppa a tutte 'e ricurrenze 'e 'na serie ricurrente criata d''o pannello. |
createdAt | istante ISO | Criazione. |
updatedAt | istante ISO | Urdema modifica. |
Errure specifiche
| Codice | error | Quanno |
|---|---|---|
| 400 | invalid_input | venueId/courtId nun so' UUID, o pure from/to nun so' date ca se ponno 'nterpretà. |
| 404 | not_found | 'A struttura ("Struttura non trovata") o 'o campo ("Campo non trovato") nun esiste o nun è 'o tujo. |
6.3 Nova prenotazione
/api/manager-api/v1/bookingsCria 'na prenotazione 'ncoppa a 'nu campo tujo. 'A prenotazione nasce cu source: "api", accussì dint'ô pannello se distingue da chelle mise a mano, e 'o gestore riceve 'na notifica push «Nova prenotazione» 'ncoppa a l'app.
Veneno applicate 'e stesse regole d''o pannello, dint'a l'ordine:
- chiusura straordinaria d''a struttura dint'a data d'inizio →
409 venue_closed; - sovrapposizione cu n'ata prenotazione nun annullata d''o stesso campo →
409 overlap; - prezzo assente → calcolato d''o listino d''o campo (
nullse l'orario d'inizio nun cade dint'a nisciuna fascia). Se 'a fascia tene 'o prezzo a persona, serve pureplayersCount: senza, 'a richiesta vene rifiutata cu400 players_required(a meno ca nun se mposta 'nupriceCentsesplicito).
'E orari d'apertura nun bloccano 'a criazione: so' 'nformativi, 'o gestore resta sovrano 'ncoppa ô campo d''o suoio. Se vuo' 'mpedì prenotaziune fore orario, controlla tu hours turnato da /availability primma 'e chiammà 'a POST.
Cuorpo d''a richiesta (JSON)
| Nomme | Tipo | Obbl. | Descrizione |
|---|---|---|---|
courtId | uuid | sì | Campo da prenotà. Adda appartené a 'na struttura toja. |
startsAt | istante ISO 8601 cu offset | sì | Inizio. Songo accettate sia 'a forma 2026-08-12T18:00:00Z sia 2026-08-12T18:00:00+02:00. Senza offset: 400. |
endsAt | istante ISO 8601 cu offset | sì | Fine, adda essere successiva a startsAt. |
customerName | string (1–160) | sì | Nomme d''o cliente. |
customerPhone | string (max 40) | no | Telefono. |
customerEmail | email (max 200) | no | Email, validata comme indirizzo. |
priceCents | integer ≥ 0 | no | Prezzo 'n centesime. Se omesso vene calcolato d''o listino d''o campo. Inneca 0 sulo pe' 'na prenotazione overamente gratis. |
playersCount | integer 1–500 | no | Quante persone. Richiesto se 'o prezzo s'adda calcolà d''o listino e 'a fascia d''o orario d'inizio è a persona; 'o totale applica l'eventuale minimo garantito d''a fascia. |
notes | string (max 2000) | no | Note libbere, visibbile a 'o gestore dint'a 'o pannello. |
status | pending | confirmed | paid | cancelled | no | Default confirmed. Da 'nu gestionale esterno usa confirmed o paid: pending è riservato a 'e richieste ca arrivano d''all'app d''e jucature (vedi stati). |
paymentMethod | cash | bank_transfer | paypal | stripe | other | no | Comme è stato (o sarrà) incassato. Omesso = nun incassato. |
recurrence | object | no | Nun supportato da cheste API: se ce sta, 'a richiesta vene rifiutata cu 400 recurrence_unsupported (nisciuna prenotazione criata). 'E serie ricurrente restano 'na funzione d''o pannello: da 'nu gestionale esterno ripeti 'a POST pe' ogne occorrenza. |
Essempio 'e richiesta
curl -s -X POST https://www.volleyfriends.com/api/manager-api/v1/bookings -H "X-Api-Key: $VF_API_KEY" -H "Content-Type: application/json" -d '{
"courtId": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"startsAt": "2026-08-12T18:00:00+02:00",
"endsAt": "2026-08-12T19:30:00+02:00",
"customerName": "Marta Bellini",
"customerPhone": "+39 340 1122334",
"customerEmail": "marta.bellini@example.com",
"notes": "Prenotato dal sito della struttura"
}'
Esempio 'e risposta — 201
{
"booking": {
"id": "9d51c7b4-0e28-4f3a-a6d9-72b48e105c3f",
"venueId": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"courtId": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"courtName": "Campo 1",
"startsAt": "2026-08-12T16:00:00.000Z",
"endsAt": "2026-08-12T17:30:00.000Z",
"customerName": "Marta Bellini",
"customerPhone": "+39 340 1122334",
"customerEmail": "marta.bellini@example.com",
"priceCents": 3000,
"playersCount": null,
"status": "confirmed",
"paymentMethod": null,
"paymentLink": null,
"notes": "Prenotato dal sito della struttura",
"source": "api",
"recurrenceId": null,
"createdAt": "2026-07-28T09:14:02.517Z",
"updatedAt": "2026-07-28T09:14:02.517Z"
}
}
Dint'a l'esempio priceCents nun era stato innecato: 90 minute 'ncoppa a 'na fascia da 20,00 €/ora danno 3000 centesime ('o calcolo è proporzionale a 'e minute effettive, cu 'a tariffa d''a fascia addò accummincia 'a prenotazione).
Errure specifiche
| Codice | error | Quanno |
|---|---|---|
| 400 | invalid_input | Cuorpo nun valido: campo obbligatorio ca manca, istante senza offset, endsAt ca nun vene doppo startsAt, email nun valida, lunghezze fore limite. |
| 400 | players_required | Prezzo da calcolà d''o listino 'ncoppa a 'na fascia a persona, ma playersCount assente. |
| 400 | recurrence_unsupported | 'O cuorpo tene recurrence: 'e ricorrenze nun songo disponibbile da cheste API. |
| 403 | subscription_required | Nisciuno abbonamento gestore in corso. |
| 404 | not_found | "Campo non trovato" — 'o courtId nun esiste o nun è 'o tujo. |
| 409 | venue_closed | 'A struttura tene 'na chiusura straordinaria dint'â data 'e inizio. |
| 409 | overlap | 'O campo tene già 'na prenotazione nun annullata ca se sovrappone a l'intervallo. |
// 409 — sovrapposizione
{ "error": "overlap", "message": "Il campo è già prenotato in quell'orario." }
// 409 — chiusura straordinaria ('o mutivo, se nnicato d' 'o gestore, sta dint'ô messaggio)
{ "error": "venue_closed", "message": "Struttura chiusa in quella data (manutenzione)." }
Nun esiste 'na chiave 'e idempotenza: repetere 'a stessa POST doppo 'nu timeout può crià 'nu duplicato o, cchiù spisso, turnà 409 overlap pecché 'o primmo tentativo era gghiuto a buon fine. Dint'a 'nu caso 'e rispuosta ncerta, primma 'e turnà a pruvà verifeca cu GET /bookings ncopp'a l'intervallo nteressato.
6.4 Cagna prenotazione
/api/manager-api/v1/bookings/{id}Aggiurna 'na prenotazione ca già ce sta. È n'aggiurnamento parziale: manna sulo 'e campe ca cagnano, l'ate restano tale e quale. 'O cuorpo adda tené almanco 'nu campo.
Nun esiste n'endpoint 'e cancellazione: pe' annullà 'na prenotazione s'addorza status: "cancelled". 'O storeco resta dint'ô pannello e 'o slot turna libbero ('e prenotazzione annullate nun occupano 'o campo e nun generano overlap).
Parametro 'e percorso
| Nomme | Tipo | Obbl. | Descrizione |
|---|---|---|---|
id | uuid | sì | Id d' 'a prenotazione, da GET /bookings o d' 'a rispuosta d' 'a POST. |
Cuorpo d''a richiesta (JSON)
Tutti 'e campe so' opzionali. Chille marcate «annullabile» accettano null pe' svutà 'o valore.
| Nomme | Tipo | Note |
|---|---|---|
courtId | uuid | Sposta 'a prenotazione ncopp'a n'ato campo tujo, pure 'e n'ata struttura toja (venueId vene aggiurnato 'e conseguenza). |
startsAt | istante ISO cu offset | Nuovo inizio. |
endsAt | istante ISO cu offset | Nuova fine. 'O resultato finale adda restà successivo a l'inizio, pure cumbinando sulo n'estremo cu 'o valore già sarvato. |
customerName | string (1–160) | — |
customerPhone | string (max 40) | Annullabile. |
customerEmail | email (max 200) | Annullabile. |
priceCents | integer ≥ 0 | Annullabile (null = prezzo 'a definì). Dint'a PATCH 'o prezzo nun vene ricalcolato d' 'o listino: se sposte l'orario e vuo' 'o prezzo nuovo, addòralo tu. |
playersCount | integer 1–500 | Annullabile. Aggiurna sulo 'o dato: 'o prezzo nun vene ricalcolato d'ufficio — se 'o nummero 'e persone cagna 'o totale, manna pure 'o nuovo priceCents. |
notes | string (max 2000) | Annullabile. |
status | pending | confirmed | paid | cancelled | Qualsiasi transizione è ammessa. È pure 'o modo 'e rispunnere a 'na richiesta arrivata d' 'a app (status: "pending" cu source: "app"): puortala a confirmed pe' l'accettà o a cancelled pe' 'a rifiutà — 'o jucatore riceve 'a notifica. |
paymentMethod | cash | bank_transfer | paypal | stripe | other | Annullabile. |
'E cuntrolle 'e chiusura e sovrapposizione se fanno n'ata vota dint'a duje casi: quanno 'a richiesta sposta 'o slot (startsAt, endsAt o courtId) e quanno riattiva 'na prenotazione annullata (status da cancelled a qualsiasi ato stato) — da annullata nun occupava 'o campo, e intanto 'o slot putesse essere stato pigliato: in chillo caso 'a PATCH risponne 409 overlap o 409 venue_closed. 'Na PATCH ca cagna sulo ate campe (prezzo, note, incasso) nun 'e ripete.
Esempio 'e richiesta — spostamento e incasso
curl -s -X PATCH https://www.volleyfriends.com/api/manager-api/v1/bookings/9d51c7b4-0e28-4f3a-a6d9-72b48e105c3f -H "X-Api-Key: $VF_API_KEY" -H "Content-Type: application/json" -d '{
"startsAt": "2026-08-12T19:00:00+02:00",
"endsAt": "2026-08-12T20:30:00+02:00",
"status": "paid",
"paymentMethod": "cash",
"priceCents": 3000
}'
Esempio 'e richiesta — annullamento
curl -s -X PATCH https://www.volleyfriends.com/api/manager-api/v1/bookings/9d51c7b4-0e28-4f3a-a6d9-72b48e105c3f -H "X-Api-Key: $VF_API_KEY" -H "Content-Type: application/json" -d '{ "status": "cancelled" }'
Essempio 'e rispuosta — 200
'A prenotazione aggiurnata, dint'ô stesso formato d' 'a POST:
{
"booking": {
"id": "9d51c7b4-0e28-4f3a-a6d9-72b48e105c3f",
"venueId": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"courtId": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"courtName": "Campo 1",
"startsAt": "2026-08-12T17:00:00.000Z",
"endsAt": "2026-08-12T18:30:00.000Z",
"customerName": "Marta Bellini",
"customerPhone": "+39 340 1122334",
"customerEmail": "marta.bellini@example.com",
"priceCents": 3000,
"playersCount": null,
"status": "paid",
"paymentMethod": "cash",
"paymentLink": null,
"notes": "Prenotato dal sito della struttura",
"source": "api",
"recurrenceId": null,
"createdAt": "2026-07-28T09:14:02.517Z",
"updatedAt": "2026-07-28T11:02:47.883Z"
}
}
Errure specifiche
| Codice | error | Quanno |
|---|---|---|
| 400 | invalid_input | Cuorpo vuoto ("Nessun campo da aggiornare"), valore nun valide, o pure orario 'e fine nun successivo a chillo d'inizio ("L'orario di fine deve essere successivo a quello di inizio"). |
| 403 | subscription_required | Nisciuno abbonamento gestore in corso. |
| 404 | not_found | "Prenotazione non trovata" o pure "Campo non trovato" se 'o nuovo courtId nun è 'o tujo. |
| 409 | venue_closed | Spostamento dint'a 'na data 'e chiusura straordinaria. |
| 409 | overlap | 'O nuovo orario se sovrappone a n'ata prenotazione nun annullata d' 'o stesso campo. |
6.5 Disponibilità 'e 'nu campo dint'a 'nu juorno
/api/manager-api/v1/availabilityRestituisce, pe' 'nu campo e 'nu juorno, 'e slot occupati, 'e orari 'e apertura 'e chillo juorno d' 'a settimana e l'eventuale chiusura straordinaria. È l'endpoint da ausà pe' calcolà 'e slot libbere 'ncopp'a 'nu sito esterno senza duplicà 'e regole d' 'o gestionale: sottrai 'e prenotazione d' 'a finestra 'e apertura.
Ce stanno elencate tutte 'e slot ca occupano 'o campo, in qualunque stato tranne cancelled: quinn' pure 'e richieste 'e prenotazione online ancora pending. 'O juorno è chillo locale italiano e l'intervalli so' semiaperte: 'na prenotazione ca fernisce esattamente a mezanotte appartene ô juorno primma. 'Na prenotazione a cavallo d' 'a mezanotte compare dint'a tutt'e duje 'e juorne ca interseca, cu 'e mumente riale d' 'e suoje (ca ponno cadé fore d' 'o juorno richiesto).
Parametri (query string)
| Nomme | Tipo | Obbl. | Descrizione |
|---|---|---|---|
courtId | uuid | sì | Campo addò s'ha da legge 'a disponibilità. Adda essere 'o tujo. |
date | AAAA-MM-GG | sì | Juorno locale italiano. Formato diverso: 400 cu 'o messaggio "Data non valida (AAAA-MM-GG)". |
Essempio 'e richiesta
curl -s -G https://www.volleyfriends.com/api/manager-api/v1/availability -H "X-Api-Key: $VF_API_KEY" --data-urlencode "courtId=7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05" --data-urlencode "date=2026-08-12"
Essempio 'e rispuosta — 200
{
"courtId": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"venueId": "b3f8e5c1-2d47-4a90-8f31-6c0d9a7e4512",
"date": "2026-08-12",
"timezone": "Europe/Rome",
"hours": {
"weekday": 2,
"openMinute": 540,
"closeMinute": 1380,
"closed": false,
"configured": true
},
"closure": null,
"bookings": [
{
"startsAt": "2026-08-12T16:00:00.000Z",
"endsAt": "2026-08-12T17:30:00.000Z",
"status": "confirmed"
},
{
"startsAt": "2026-08-12T18:00:00.000Z",
"endsAt": "2026-08-12T19:00:00.000Z",
"status": "paid"
},
{
"startsAt": "2026-08-12T19:00:00.000Z",
"endsAt": "2026-08-12T20:30:00.000Z",
"status": "pending"
}
]
}
Campe d' 'a rispuosta
| Campo | Tipo | Descrizione |
|---|---|---|
courtId | uuid | Campo richiesto. |
venueId | uuid | Struttura d' 'o campo. |
date | AAAA-MM-GG | Juorno richiesto, ripetuto. |
timezone | string | Sempe "Europe/Rome": 'o fuso addò s'hanno da interpretà date e 'e minute d' 'e orari. |
hours.weekday | integer 0–6 | Juorno d' 'a settimana: 0 = lunedì … 6 = dummeneca. |
hours.openMinute | integer | null | Apertura in minute d' 'a mezanotte locale (540 = 09:00). null se 'o juorno è dichiarato chiuso. |
hours.closeMinute | integer | null | Chiusura in minute (1380 = 23:00). null se 'o juorno è dichiarato chiuso. |
hours.closed | boolean | true se 'o gestore ha dichiarato chillo juorno d' 'a settimana comme chiuso. |
hours.configured | boolean | false quanno 'o gestore nun ha impostato l'orari pe' chillo juorno: in chillo caso openMinute/closeMinute valgono 'a convenzione predefinita 480 (08:00) – 1380 (23:00), ca è 'nu ripiego 'e visualizzazione, nun 'nu orario dichiarato. |
closure | object | null | Chiusura straordinaria attiva dint'ô juorno richiesto, oppuro null. |
closure.from | AAAA-MM-GG | Primmo juorno 'e chiusura. |
closure.to | AAAA-MM-GG | Ultemo juorno 'e chiusura, ncluso. |
closure.reason | string | null | Mutivo, se nnicato d' 'o gestore. |
bookings[] | array | Slot occupate, urdenate pe' nizio. Solo startsAt, endsAt e status (pending, confirmed o paid): nisciuno dato d' 'o cliente, accussì 'a rispuosta se pô ausà pe' custruì 'nu calannario pubblico. |
Quanno closure nun è null 'o juorno è d' 'a cunziderà nun prenotabbele, a prescindere da hours: 'na POST dint'a chella data riceverria 409 venue_closed.
Errure specifiche
| Codice | error | Quanno |
|---|---|---|
| 400 | invalid_input | courtId mancante o nun UUID, date mancante o nun dint'ô formato AAAA-MM-GG. |
| 404 | not_found | "Campo non trovato" — 'o campo nun esiste o nun è 'o tujo. |
6.6 Listino 'e 'nu campo
/api/manager-api/v1/rates'O listino d' 'o campo in sola lettura: serve a mustrà 'e prezze a 'o cliente primma d' 'a prenotazzione, cu 'e stesse fasce ca 'o gestionale ausa pe' calculà 'o prezzo automatico. 'E fasce se modificano sulo d' 'o pannello. Songo urdenate pe' fromMinute crescente.
Parametri (query string)
| Nomme | Tipo | Obbl. | Descrizione |
|---|---|---|---|
courtId | uuid | sì | Campo d' 'o quale s'ha da leggere 'o listino. Adda essere 'o tujo. |
Essempio 'e richiesta
curl -s -G https://www.volleyfriends.com/api/manager-api/v1/rates -H "X-Api-Key: $VF_API_KEY" --data-urlencode "courtId=7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05"
Essempio 'e rispuosta — 200
{
"courtId": "7c94a0d2-58b1-4e6f-9a3c-1d20f8b47e05",
"rates": [
{
"id": "4a1e0b72-6d35-4c81-93af-0b7e2d5814c6",
"label": "Mattina infrasettimanale",
"daysMask": 31,
"fromMinute": 480,
"toMinute": 840,
"pricePerHourCents": 1500,
"pricingMode": "court",
"minPlayers": null
},
{
"id": "c07d9b31-8f42-4a05-b6e9-15d3c8017a2b",
"label": "Serale",
"daysMask": 127,
"fromMinute": 1080,
"toMinute": 1380,
"pricePerHourCents": 600,
"pricingMode": "person",
"minPlayers": 10
}
]
}
Campe d' 'a rispuosta
| Campo | Tipo | Descrizione |
|---|---|---|
courtId | uuid | Campo richiesto. |
rates[].id | uuid | Identificativo d' 'a fascia. |
rates[].label | string | Etichetta scigliuta d' 'o gestore (es. «Serale»). |
rates[].daysMask | integer 1–127 | Bitmask d' 'e juorne: lun 1, mar 2, mer 4, gio 8, ven 16, sab 32, dom 64. 127 = tutte 'e juorne, 31 = da lunnerì a vennerì. |
rates[].fromMinute | integer 0–1440 | Inizio d' 'a fascia in minute d' 'a mezanotte locale. |
rates[].toMinute | integer 0–1440 | Fine d' 'a fascia, sempe maggiore 'e fromMinute. |
rates[].pricePerHourCents | integer > 0 | Prezzo orario in centeseme (2000 = 20,00 €). Cu pricingMode: "person" è 'o prezzo orario a persona (600 = 6,00 €/persona all'ora). |
rates[].pricingMode | court | person | court = prezzo d' 'o campo (default). person = prezzo a persona: 'o totale scala cu 'o nummero 'e persone, maje a 'o ribasso. |
rates[].minPlayers | integer | null | Minimo garantito d''a fascia a persona: sotto a chillu nummero se pava comunque p''o minimo. null = nisciuno minimo. |
Se guarda l'istante 'e inizio: 'mmiez'ê fasce d''o campo se piglia 'a prima (in ordine 'e fromMinute) addò 'o juorno è attivo dint'â bitmask e ca cuntene 'o minuto 'e inizio (fromMinute ≤ inizio < toMinute). 'O prezzo è proporzionale ê minute effettivi: arrotonda(pricePerHourCents × minuti / 60) — 90 minute a 20,00 €/ora fanno 30,00 €. 'Na prenotazzione a cavallo 'e ddoje fasce resta valorizzata cu 'a tariffa d''a fascia 'e inizio. Nisciuna fascia currispunnente: priceCents risulta null (prezzo a definì), maje 0.
Cu 'na fascia a persona (pricingMode: "person") 'o resultato orario se murtipleca p''e persone fatturate: max(playersCount, minPlayers). Esempio cu 'a fascia d''a sera cca 'ncoppa (6,00 €/persona all'ora, minimo 10): 60 minute cu 12 persone → 72,00 €; cu 16 → 96,00 € ('o prezzo a persona nun cala); cu 8 → 60,00 € (scatta 'o minimo garantito). Senza playersCount 'o prezzo nun se pô calculà: null in lettura, 400 players_required dint'â POST ca se fida d''o listino.
Errure specifiche
| Codice | error | Quanno |
|---|---|---|
| 400 | invalid_input | courtId ca manca o nun è UUID. |
| 404 | not_found | "Campo non trovato" — 'o campo nun esiste o nun è 'o tujo. |
'Nu campo senza listino risponne 200 cu "rates": [].
7. Cunvenziune d''e date
7.1 Date e orare
- In ingresso l'istante songo stringhe ISO 8601 cu offset obbricatorio:
2026-08-12T18:00:00+02:00oppure2026-08-12T18:00:00Z. 'Na stringa senza offset (2026-08-12T18:00:00) vene refutata cu400: sarrìa ambigua, e pe' 'nu calannario è 'n'ambiguità ca se pava cu prenotazzione sbagliate 'e n'ora. - In uscita l'istante songo sempe nurmalizzate in UTC cu suffisso
Ze milliseconne:"2026-08-12T16:00:00.000Z". Cunvertile dint'ô fuso lucale primma 'e amustrà. - 'E date sicche (
date,closure.from,closure.to, efrom/toquanno l'use a forma 'e juorno) songoAAAA-MM-GGe se referiscono ô juorno lucale taliano. - L'intervalle songo semiaperte
[inizio, fine): 18:00–19:00 e 19:00–20:00 nun stanno in cunflitto.
7.2 Fuso orario
'E prenotazzione songo cunservate comme istante assolute, ma tutte 'e regule 'e calannario — juorno d''a semmana, fasce d''o listino, orare 'e apertura, date 'e chiusura, cunfine d''o juorno — songo valutate dint'ô fuso Europe/Rome, cu l'ora legale gestita automaticamende. 'O campo timezone d''a rispuosta 'e /availability 'o dichiara esplicitamende. Se 'o server tujo gira in UTC o dint'a n'ato fuso, nun cunvertì a mano 'e minute: songo ggià espresse in ora lucale taliana.
7.3 Minute d''a mezanotte
L'orare «da calannario» (openMinute, closeMinute, fromMinute, toMinute) songo nummere 'ntere da 0 a 1440 ca cuntano 'e minute d''a mezanotte lucale. Cunversione: ore = ⌊m / 60⌋, minuti = m mod 60.
| Minute | Ora lucale | Minute | Ora lucale |
|---|---|---|---|
| 0 | 00:00 | 1080 | 18:00 |
| 480 | 08:00 | 1320 | 22:00 |
| 540 | 09:00 | 1380 | 23:00 |
| 840 | 14:00 | 1440 | 24:00 (fine d''a jurnata) |
7.4 Importe
Tutte l'importe songo nummere 'ntere in centesime 'e euro (priceCents, pricePerHourCents): nisciuno valore cu 'a virgula, nisciuno simmolo 'e valuta. 2000 = 20,00 €. 'Ncoppa a 'na prenotazzione, priceCents: null significa «prezzo a definì» ed è deverzo da 0, ca significa «gratis».
7.5 State 'e 'na prenotazzione
| Stato | Significato | Occupa 'o slot? |
|---|---|---|
pending | Richiesta 'e prenotazzione online 'n attesa d' 'a decisione d' 'o gestore. Nasce sulo d' 'e richieste mannate d' 'e jucature d' 'all'app VolleyFriends (source: "app"): 'o gestore 'a accetta (confirmed) o 'a rifiuta (cancelled). | Sì — 'o slot è già bloccato, pe' evità doppie richieste 'ncopp'ô stesso orario |
confirmed | Prenotazione valida, nun ancora incassata. È 'o stato iniziale 'e ogne prenotazione creata da chest'API e d''o pannello. | Sì |
paid | Prenotazione valida e incassata. 'E norma accumpagnata da paymentMethod. | Sì |
cancelled | Prenotazione annullata (o richiesta rifiutata). Resta dint'ô storico ma libera 'o campo: nun genera overlap e nun comparisce dinto a /availability. | No |
- 'E truove dinto a GET /bookings e dint'e slot occupate 'e /availability: tratta 'o slot comme nun disponibile, tale e quale a 'na
confirmed. - Puo' risponnere a 'a richiesta d''o gestionale tujo cu 'na PATCH:
{"status": "confirmed"}pe' l'accettà,{"status": "cancelled"}pe' 'a rifiutà. 'O jucatore riceve 'na notifica cu l'esito. - Ricanuscile d''a coppia
status: "pending"+source: "app". 'E date d''o cliente arrivano d''o profilo VolleyFriends d''o jucatore (nomme ed email), quinnicustomerPhonepò esserenull. - Nun crià prenotazzione
pendingda chest'API: 'o valore è accettato d''a validazione, ma chillo stato descrive 'na richiesta 'n attesa 'e risposta da parte d''o gestore e nisciuno 'a decidarria d''o lato tujo. Se dint'ô flusso tujo ce sta 'nu carrello o 'nu pavamento da completà, tiene l'attesa dint'ô sistema tujo e chiamma 'a POST quanno 'a prenotazione è definitiva — o si no crialaconfirmede portala acancelledse 'o pavamento nun arriva.
7.6 Origgine e metodo 'e pavamento
| Campo | Valure | Significato |
|---|---|---|
source | manual | Inserita d''o gestore dint'ô pannello. |
api | Creata da 'nu gestionale esterno cu chest'API. Valore sempe 'mpustato d''a POST, nun modificabile. | |
app | Richiesta 'e prenotazione online mannata da 'nu jucatore d''all'app VolleyFriends: nasce pending e aspetta 'a decisione toja. | |
tournament | Generata d''all'organizzazione 'e 'nu torneo 'ncopp'e campe d''a struttura. | |
paymentMethod | cash, bank_transfer, paypal, stripe, other | Comme è stato incassato. null = nun incassato. |
Tutt'e duje songo domini testuali: nuove valure ponno essere aggiunte 'n futuro senza cagnà versione, quinni 'o codice tujo nun adda jì 'n errore 'ncopp'a 'nu valore ca nun canosce.
7.7 Date personale d''e cliente
Nomme, telefono ed email ca manne dint'e prenotazzione songo date personale d''e cliente tuoje: si' tu 'o titolare d''o trattamento, VolleyFriends 'e cunserva pe' cunto tujo comme responsabile ai sensi dell'art. 28 GDPR. Manna sulo chello ca serve a 'a gestione d''o campo e informa 'e cliente tuoje. 'O dettaglio sta dint'a privacy policy.
8. Errore generale
Ogni errore tene 'o stesso cuorpo: 'nu codice stabile dint'a error, pensato p' 'o codice tujo, e 'nu message in italiano, pensato p' 'e ggenti. Piglia 'e decisioni toje 'ncopp'a error e 'ncopp'ô stato HTTP, no 'ncopp'ô testo d' 'o messaggio, ca pô cagnà.
{
"error": "overlap",
"message": "Il campo è già prenotato in quell'orario."
}
'E ll'errore 'e validazione azzongono issues, 'a lista dettagliata d' 'e prubleme campo pe' campo:
{
"error": "invalid_input",
"message": "Dati non validi",
"issues": [
{
"code": "invalid_string",
"validation": "datetime",
"path": ["startsAt"],
"message": "Invalid datetime"
}
]
}
| HTTP | error | Significato | Che s'ha da fà |
|---|---|---|---|
| 400 | invalid_input | Parametre o cuorpo nun valide. 'O dettaglio sta dint'a issues. | Acconcia 'a richiesta. Nun ce pruvà n'ata vota tale e quale: 'o resultato nun cagna. |
| 401 | invalid_key | Header X-Api-Key assente, malformato, scanusciuto o revocato. | Verifica 'e mannà l'header e ca 'a chiave sia attiva dint'ô pannello. Si è stata revocata, generane una nova. |
| 403 | subscription_required | Nisciuno abbonamento «Gestore campi» in corso 'ncopp'all'account proprietario d' 'a chiave. | Riattiva l'abbonamento dall'app (Profilo → area gestore → Abbonamento). Nisciuna chiamata funziona nfino a chillu mumento. |
| 403 | feature_not_included | Abbonamento attivo, ma 'o piano nun cumprende «API per gestionali esterni». 'O messaggio nomina 'o piano in corso. | Passa a 'nu piano ca cumprende 'a funzione. Vale pe' tutta 'a v1, letture ncluse. |
| 404 | not_found | Risorsa ca nun esiste oppure ca appartene a n'ato gestore: 'e ddoje situazzione nun se spartono, pe' nun fà vedé 'e ddati 'e ll'ati ggenti. | Ligge n'ata vota 'e id da /venues e da /bookings: quase sempe è 'nu id viecchio o cupiato da n'ato account. |
| 409 | overlap | 'O campo è già occupato dint'all'intervallo richiesto da 'na prenotazzione nun scancellata. | Pruponi n'ato slot: ligge n'ata vota /availability. Nun ce pruvà n'ata vota senza cagnà orario. |
| 409 | venue_closed | Chiusura straordinaria d' 'a struttura dint'a data richiesta. | Pruponi n'ata data. 'E chiusure se leggono da /availability (closure). |
| 429 | rate_limited | Superate 'e 120 richieste ô minuto p' 'a chiave. | Aspetta e pruvace n'ata vota cu backoff esponenziale, rispettanno retry-after. |
| 4xx | error | Codice generico pe' ll'errore 'e richiesta ca nun cadono dint'ê casi 'e coppa (raro). | Ligge message e acconcia 'a richiesta. |
| 500 | internal | Errore ca nun s'aspettava d' 'a parte nosta. | Pruove n'ata vota cchiù tardi. Si cuntinua, scrivice specificanno l'ora, l'endpoint e 'o prefisso d' 'a chiave (nun 'a chiave). |
'Nu path ca nun esiste sotto 'a base risponne 404; 'a stessa cosa vale pe' 'nu metodo ca nun è previsto 'ncoppa a 'nu path ca esiste:
{
"error": "not_found",
"message": "Risorsa non trovata"
}
'E risposte 502, 503 e 504 arrivano d' 'o reverse proxy quanno l'API nun se pò raggiongere (riavvio o manutenzione): dint'a chillu caso 'o cuorpo nun è garantito in formato JSON. Trattale comme a errore temporanee e pruove n'ata vota cu 'o backoff, senza pruvà a sutterrà 'o cuntenuto.
9. Versioni e compatibilità
'A versione sta dint' 'o path: /manager-api/v1. Nun ce stanno header 'e versione né date 'e release da specificà: l'unica versione ca sta mo' pubblicata è v1.
Che cosa possiamo cambiare senza avvisarti
- Aggiungere campi alle risposte esistenti.
- Aggiungere parametri opzionali alle richieste, con un valore predefinito che conserva il comportamento attuale.
- Aggiungere nuovi endpoint sotto
/v1. - Aggiungere valori ai campi testuali aperti (
source,paymentMethod,surface). - Riformulare i
messagedegli errori, mantenendo invariati i codicierror.
Che cosa non cambia dentro la v1
- Nessun campo verrà rimosso o rinominato dalle risposte.
- Nessun campo cambierà tipo o significato.
- Nessun parametro oggi opzionale diventerà obbligatorio.
- I codici
errore gli stati HTTP documentati qui restano quelli.
Qualunque modifica che rompa queste garanzie arriverà su un nuovo prefisso (/v2), con la v1 mantenuta in servizio e un preavviso ai gestori che la stanno usando.
- Ignora i campi che non conosci invece di andare in errore su di essi (nessun parsing «strict» che rifiuta le proprietà inattese).
- Gestisci i valori sconosciuti dei campi testuali aperti con un ramo di ripiego.
- Non fare affidamento sull'ordine delle chiavi JSON né sul testo dei messaggi.
- Tratta
nulle campo assente come equivalenti in lettura.
Changelog
| Versione | Data | Note |
|---|---|---|
| v1 | lug 2026 | Aggiunte compatibbile: tariffe a persona dint'ô listino (pricingMode, minPlayers) e playersCount ncopp'ê prenotaziune (cu l'errore players_required); paginazzione limit/offset ncopp'â lista d'e prenotaziune; ricontrollo d'e cunflitte quanno se riattiva 'na prenotazzione annullata; recurrence mo rifiutato esplicitamente cu 400 recurrence_unsupported (primma s'ignorava senza dicere niente). |
| v1 | 2026 | Primma versione pubbleca: strutture e campe, prenotaziune (lista, criazzione, modifeca), disponibbelità d'a jurnata, listino. Autenticazzione cu X-Api-Key, 120 richieste/menuto pe' chiave. |
10. Supporto a l'integrazzione
Pe' dumande tecniche, cumportamente ca nun t'aspette o richieste 'e endpoint ca nun truove ccà, scrivice d'a paggena Contatte. Pe' ghjì deritto ô punto, scrive dint'ô messaggio:
- endpoint e metodo ca staje chiammanno;
- data e ora d'a chiamata (cu 'o fuso) e 'o codice HTTP arricivuto;
- codice
errore messaggio d'a risposta; - prefisso d'a chiave ausata (es.
vfk_9f2c).
Nun ce mannà 'a chiave API cumpleta pe' nisciuno canale, manco pe' ce fà verifecà 'nu prebblema: 'o prefisso ce basta pe' ll'identifecà. Si ll'haje già spartuta cu coccheduno, revocala e generane 'na nova.
Si haje bisogno 'e pruvà l'integrazzione senza tuccà 'o calannario reale, crija 'na struttura 'e prova cu 'nu campo dedicato e ausa chella: tutte 'e chiammate so' limitate a 'e strutture d'o pruprietario d'a chiave, accussì 'o riesto d'o cunto tujo nun è cuinvolto.