Endpoint pubbliciDEV
Riferimento di tutti gli endpoint REST V1 read-only del menu.
Tutti gli endpoint pubblici sono read-only e funzionano senza token. Base URL: https://<tenant>.menufacile.it/api/v1.
In caso di successo restituiscono il consueto envelope {success, data, meta}. Per la forma dei body di errore vedi Codici di errore.
GET /menu/{locale?}
Restituisce il menu completo strutturato (settings + tema + sezioni + piatti). È l'endpoint principale per integrare il menu in un sito.
Parametri path
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
locale |
string | default_locale del ristorante |
Codice lingua: it, en, fr, de, es. Locale non supportati ricevono comunque 200 con i contenuti in fallback IT. |
Esempio
curl https://ducatarocco.menufacile.it/api/v1/menu/it
Response
{
"success": true,
"data": {
"settings": {
"id": 1,
"name": "Duca Tarocco",
"slug": "ducatarocco",
"logo_url": "https://ducatarocco.menufacile.it/storage/logos/duca-tarocco.svg",
"cover_image_url": null,
"cover_charge_text": "Coperto € 2",
"allergen_info": "I piatti potrebbero contenere tracce di altri allergeni per contaminazione crociata.",
"review_url": "https://g.page/r/...",
"recommended_label": "Più Venduto",
"business_name": "Ristorante Duca Tarocco S.r.l.",
"vat_number": "IT01234567890",
"address": "Via Roma 42, Ragusa",
"phone": "+39 0932 123456",
"email": "info@ducatarocco.it",
"default_locale": "it",
"supported_locales": ["it", "en"],
"is_active": true
},
"theme": {
"id": 1,
"primary_color": "#C0AD8A",
"secondary_color": "#8A7A5C",
"accent_color": "#D4A574",
"background_color": "#2B3C37",
"text_color": "#F5F5F0",
"font_family": "Playfair Display",
"font_url": "/fonts/playfair-display.css",
"border_radius": "8px",
"layout_variant": "standard",
"header_style": "centered",
"footer_text": "Cucina aperta 19:30 — 23:00"
},
"sections": [
{
"id": 12,
"parent_id": null,
"menu_type": "standard",
"name": "Antipasti",
"name_translations": { "it": "Antipasti", "en": "Starters" },
"notes": "Da condividere a tavola.",
"display_order": 0,
"is_active": true,
"show_subcategories": false,
"time_visibility_enabled": false,
"time_start": null,
"time_end": null,
"items": [
{
"id": 87,
"category_id": 12,
"type_id": null,
"winery_id": null,
"name": "Caponata della casa",
"name_translations": { "it": "Caponata della casa", "en": "House caponata" },
"description": "Melanzane, sedano, capperi, olive",
"description_translations": { "it": "Melanzane, sedano, capperi, olive", "en": "Eggplant, celery, capers, olives" },
"price": 9.0,
"allergens": ["sedano", "solfiti"],
"is_active": true,
"is_recommended": true,
"display_order": 0,
"winery": null
}
],
"types": []
},
{
"id": 30,
"parent_id": null,
"menu_type": "wine",
"name": "Carta dei Vini",
"items": [],
"types": []
}
]
},
"meta": {
"generated_at": "2026-05-14T11:42:18+00:00",
"locale": "it"
}
}
💡
menu_type: solo 2 valori —standardowine. Le sezioniwinesono sempre in coda al menu (ordine forzato lato API).
💡 Solo sezioni e piatti attivi (
is_active: true) sono inclusi nella response: il filtro è applicato server-side, non devi rifarlo nel client.
GET /categories
Lista delle sezioni top-level, ordinate per display_order.
Esempio
curl https://ducatarocco.menufacile.it/api/v1/categories
Response
{
"success": true,
"data": [
{
"id": 12,
"parent_id": null,
"menu_type": "standard",
"name": "Antipasti",
"name_translations": { "it": "Antipasti", "en": "Starters" },
"notes": "Da condividere a tavola.",
"display_order": 0,
"is_active": true,
"show_subcategories": false,
"time_visibility_enabled": false,
"time_start": null,
"time_end": null,
"items": [ "..." ],
"types": [ "..." ],
"children": [ "..." ]
}
],
"meta": { "generated_at": "..." }
}
Stesso shape sezione del /menu, con in più children[] (eventuali sotto-sezioni) e relazioni items[] / types[] eager-loaded.
GET /categories/{id}
Dettaglio sezione con piatti e sottocategorie incluse.
curl https://ducatarocco.menufacile.it/api/v1/categories/12
Risposta: oggetto Category con stesso shape di sopra (15 campi + items, types, children eager-loaded).
ID inesistente → 404 HTML branded (non JSON), vedi Codici di errore.
GET /items
Lista piatti, supporta filtri e paginazione.
Query parameters
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
category_id |
int | — | Filtra per sezione |
type_id |
int | — | Filtra per sottocategoria |
is_recommended |
bool (0/1) |
— | Solo piatti consigliati (oppure solo non consigliati con 0) |
search |
string | — | Ricerca testuale su nome/descrizione |
per_page |
int | 50 |
Numero di item per pagina |
locale |
string | default_locale |
Lingua delle traduzioni |
Esempio
curl "https://ducatarocco.menufacile.it/api/v1/items?is_recommended=1&locale=en"
Response
{
"success": true,
"data": [
{
"id": 87,
"category_id": 12,
"type_id": null,
"winery_id": null,
"name": "House caponata",
"name_translations": { "it": "Caponata della casa", "en": "House caponata" },
"description": "Eggplant, celery, capers, olives",
"description_translations": { "it": "Melanzane, ...", "en": "Eggplant, ..." },
"price": 9.0,
"allergens": ["sedano", "solfiti"],
"is_active": true,
"is_recommended": true,
"display_order": 0,
"winery": null
}
],
"meta": {
"generated_at": "2026-05-14T11:42:18+00:00",
"locale": "en",
"total": 141,
"page": 1,
"per_page": 10,
"last_page": 15
}
}
Per il widget "piatti consigliati" usa direttamente ?is_recommended=1 — vedi la ricetta dedicata.
GET /items/{id}
Dettaglio singolo piatto.
curl https://ducatarocco.menufacile.it/api/v1/items/87
Response: oggetto MenuItem completo (14 campi). Per piatti di tipo vino, winery è eager-loaded con i dati della cantina.
ID inesistente → 404 HTML branded.
GET /restaurant
Dati anagrafici e impostazioni del ristorante (lo stesso oggetto settings esposto da /menu).
curl https://ducatarocco.menufacile.it/api/v1/restaurant
Response
{
"success": true,
"data": {
"id": 1,
"name": "Duca Tarocco",
"slug": "ducatarocco",
"logo_url": "https://ducatarocco.menufacile.it/storage/logos/duca-tarocco.svg",
"cover_image_url": null,
"cover_charge_text": "Coperto € 2",
"allergen_info": "I piatti potrebbero contenere tracce...",
"review_url": "https://g.page/r/...",
"recommended_label": "Più Venduto",
"business_name": "Ristorante Duca Tarocco S.r.l.",
"vat_number": "IT01234567890",
"address": "Via Roma 42, Ragusa",
"phone": "+39 0932 123456",
"email": "info@ducatarocco.it",
"default_locale": "it",
"supported_locales": ["it", "en"],
"is_active": true
},
"meta": { "generated_at": "..." }
}
GET /theme
Configurazione visuale del menu (colori, font, logo, layout).
Response
{
"success": true,
"data": {
"id": 1,
"primary_color": "#C0AD8A",
"secondary_color": "#8A7A5C",
"accent_color": "#D4A574",
"background_color": "#2B3C37",
"text_color": "#F5F5F0",
"font_family": "Playfair Display",
"font_url": "/fonts/playfair-display.css",
"border_radius": "8px",
"layout_variant": "standard",
"header_style": "centered",
"footer_text": "Cucina aperta 19:30 — 23:00"
},
"meta": { "generated_at": "..." }
}
GET /allergens
Dizionario dei 14 allergeni regolamentati (Reg. UE 1169/2011), tradotti.
Query parameters
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
locale |
string | it |
Lingua delle etichette |
Esempio
curl "https://ducatarocco.menufacile.it/api/v1/allergens?locale=en"
Response
{
"success": true,
"data": [
{ "key": "cereali_glutine", "name": "Cereals containing gluten" },
{ "key": "crostacei", "name": "Crustaceans" },
{ "key": "uova", "name": "Eggs" },
{ "key": "pesce", "name": "Fish" },
{ "key": "arachidi", "name": "Peanuts" },
{ "key": "soia", "name": "Soy" },
{ "key": "latte", "name": "Milk" },
{ "key": "frutta_guscio", "name": "Tree nuts" },
{ "key": "sedano", "name": "Celery" },
{ "key": "senape", "name": "Mustard" },
{ "key": "sesamo", "name": "Sesame" },
{ "key": "solfiti", "name": "Sulfites" },
{ "key": "lupini", "name": "Lupins" },
{ "key": "molluschi", "name": "Mollusks" }
],
"meta": { "generated_at": "..." }
}
I key sono stabili (mai cambiano): usali per matchare gli allergeni nei piatti — item.allergens è un array di queste stesse key (es. ["sedano", "solfiti"]). Le key contengono underscore (cereali_glutine, frutta_guscio), non hyphen.
Endpoint admin (autenticati)
Le route POST/PUT/DELETE /api/v1/admin/* esistono e richiedono un token Sanctum con lo scope appropriato:
| Gruppo | Scope richiesto | Endpoint |
|---|---|---|
| Scrittura menu | menu:write |
POST/PUT/DELETE /admin/{categories,items,types,wineries}, PUT /admin/settings, PUT /admin/theme |
| Analytics | analytics:read |
GET /admin/analytics/{overview,items,sections,allergens,insights} |
Senza lo scope corretto la risposta è 403 Forbidden con {"message":"Invalid ability provided."}. Tutti gli admin sono limitati a 30 req/min/tenant+IP (vedi Rate limit). Vedi Autenticazione per come generare e usare un token.
ℹ️ La documentazione dettagliata di ogni endpoint admin (payload, response, validazione) è in arrivo. Per il momento questi endpoint sono usati principalmente dal pannello del ristorante; se devi automatizzarli scrivi a info@menufacile.it.
Hai bisogno di aiuto?
Scrivi a info@menufacile.it.