Skip to Content
API per SviluppatoriEndpoint Reference

Endpoint Reference — /api/v1/

Tutti gli endpoint richiedono autenticazione tramite chiave API (header X-Api-Key o Authorization: Bearer). L’organizationId non è mai un parametro — viene sempre derivato dalla chiave.

I parametri areaId, dayId e menuItemIds devono appartenere all’evento richiesto. In caso contrario la risposta è 404 Not Found.


Envelope di risposta

Tutte le risposte usano lo stesso wrapper:

{ "data": { ... }, "meta": { "generatedAt": "2026-06-11T20:00:00Z", "eventId": "3fa85f64-...", "dayId": 42 } }

meta.dayId è omesso quando non pertinente. Gli errori usano RFC 7807 (application/problem+json).

I valori monetari sono sempre numerici in EUR: "totalSales": 1234.50 — mai stringhe formattate.


Events

GET /api/v1/events

Scope richiesto: events:read

Restituisce tutti gli eventi dell’organizzazione. Se la chiave è vincolata a un evento specifico, restituisce un array con il solo evento vincolato.

Risposta 200:

{ "data": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "Sagra del Borgo 2026", "startDate": "2026-06-11T18:00:00Z", "isOpen": true, "currentDay": { "id": 42, "date": "2026-06-11", "openedAt": "2026-06-11T17:30:00Z" } } ], "meta": { "generatedAt": "2026-06-11T20:00:00Z", "eventId": "00000000-..." } }

currentDay è null se nessun giorno evento è attualmente aperto.


GET /api/v1/events/{eventId}

Scope richiesto: events:read

Restituisce il dettaglio di un singolo evento, incluso il giorno attualmente aperto.

Parametri path:

ParametroTipoDescrizione
eventIduuidID dell’evento

Risposta 200: stessa struttura del singolo oggetto in GET /api/v1/events.

Errori:

  • 404 — evento inesistente o appartenente a un’altra organizzazione
  • 404 — chiave vincolata a un evento diverso

Analytics

GET /api/v1/events/{eventId}/analytics/kpis

Scope richiesto: analytics:read

KPI aggregati per il giorno o l’area specificati.

Query parameters:

ParametroTipoDescrizione
dayIdint(opzionale) ID del giorno evento. Default: giorno attualmente aperto, o ultimo chiuso.
areaIdint(opzionale) Filtra per area. Default: tutti i dati dell’evento.

Risposta 200:

{ "data": { "totalOrders": 312, "totalSales": 4875.50, "currency": "EUR", "averageOrderValue": 15.63, "totalItemsSold": 894 }, "meta": { "generatedAt": "...", "eventId": "...", "dayId": 42 } }

GET /api/v1/events/{eventId}/analytics/sales-trend

Scope richiesto: analytics:read

Andamento delle vendite giornaliero negli ultimi N giorni.

Query parameters:

ParametroTipoDescrizione
daysint(opzionale) Numero di giorni da includere. Default: 7.
areaIdint(opzionale) Filtra per area.

Risposta 200:

{ "data": [ { "date": "2026-06-09", "totalSales": 3200.00, "orderCount": 210, "currency": "EUR" }, { "date": "2026-06-10", "totalSales": 4100.00, "orderCount": 275, "currency": "EUR" }, { "date": "2026-06-11", "totalSales": 4875.50, "orderCount": 312, "currency": "EUR" } ], "meta": { "generatedAt": "...", "eventId": "..." } }

GET /api/v1/events/{eventId}/analytics/orders/by-hour

Scope richiesto: analytics:read

Distribuzione degli ordini per ora del giorno.

Query parameters:

ParametroTipoDescrizione
dayIdint(opzionale) ID del giorno evento. Default: giorno corrente o ultimo chiuso.
areaIdint(opzionale) Filtra per area.

Risposta 200:

{ "data": [ { "hour": 18, "orderCount": 45, "revenue": 702.00, "currency": "EUR" }, { "hour": 19, "orderCount": 112, "revenue": 1748.50, "currency": "EUR" }, { "hour": 20, "orderCount": 98, "revenue": 1530.00, "currency": "EUR" } ], "meta": { "generatedAt": "...", "eventId": "...", "dayId": 42 } }

GET /api/v1/events/{eventId}/analytics/orders/top-items

Scope richiesto: analytics:read

Prodotti più venduti, ordinati per quantità decrescente.

Query parameters:

ParametroTipoDescrizione
dayIdint(opzionale) ID del giorno evento. Default: giorno corrente o ultimo chiuso.
areaIdint(opzionale) Filtra per area.
limitint(opzionale) Numero massimo di prodotti da restituire. Default: 10.

Risposta 200:

{ "data": [ { "menuItemId": 12, "itemName": "Birra alla spina", "categoryName": "Bevande", "quantity": 134, "revenue": 536.00, "currency": "EUR" }, { "menuItemId": 5, "itemName": "Porchetta", "categoryName": "Panini", "quantity": 89, "revenue": 712.00, "currency": "EUR" } ], "meta": { "generatedAt": "...", "eventId": "...", "dayId": 42 } }

GET /api/v1/events/{eventId}/live/item-counts

Scope richiesto: analytics:read

Quantità vendute per prodotto in tempo reale. Conta solo gli ordini confermati — esclude PreOrder, Pending e Cancelled. Progettato per polling frequente da dispositivi IoT.

Query parameters:

ParametroTipoDescrizione
dayIdint(opzionale) ID del giorno evento. Default: giorno corrente o ultimo chiuso.
menuItemIdsint,int,...(opzionale) Filtra per ID prodotto. Se uno degli ID non appartiene all’evento: 404.

Risposta 200:

{ "data": [ { "menuItemId": 12, "itemName": "Birra alla spina", "quantitySold": 134 }, { "menuItemId": 13, "itemName": "Birra in bottiglia", "quantitySold": 57 } ], "meta": { "generatedAt": "...", "eventId": "...", "dayId": 42 } }

Se menuItemIds non è specificato, restituisce tutti i prodotti dell’evento con almeno un ordine confermato nel giorno selezionato.


Codici di errore

CodiceSituazione
401 UnauthorizedToken assente, malformato, scaduto o revocato
403 ForbiddenToken valido ma senza lo scope richiesto dall’endpoint
404 Not FoundEvento inesistente, appartenente a un’altra organizzazione, chiave vincolata a un altro evento, oppure areaId/dayId/menuItemIds non appartenenti all’evento richiesto
429 Too Many RequestsRate limit superato — attendere Retry-After secondi

SagraFacile non restituisce mai 403 per un evento che non appartiene all’organizzazione: usa sempre 404 per non rivelare l’esistenza della risorsa.

Last updated on