{"openapi":"3.1.0","info":{"title":"Riviera d'Ulisse — Open Data API","version":"1.0.0","description":"API pubbliche di dati turistici aperti del portale **Riviera d'Ulisse**\n(Latina Turismo), in formato JSON-LD basato su schema.org e interoperabili\ncon ITALIA.it e il Tourism Digital Hub.\n\n- **Formato**: `application/ld+json` (schema.org, W3C JSON-LD 1.1)\n- **Lingue**: parametro `lang` (`it` / `en`, default `it`)\n- **Paginazione**: parametri `page` e `pageSize` sugli endpoint lista\n- **Autenticazione**: nessuna (dati pubblici, sola lettura)\n- **CORS**: abilitato per tutte le origini\n","contact":{"name":"Riviera d'Ulisse","url":"https://latinaturismo.it/open-data"},"license":{"name":"Dati aperti (riuso libero con attribuzione)","url":"https://latinaturismo.it/open-data"}},"servers":[{"url":"https://latinaturismo.it","description":"Origine corrente (preview / produzione)"}],"tags":[{"name":"Discovery","description":"Catalogo machine-readable dei dataset disponibili."},{"name":"Esperienze","description":"Esperienze turistiche (schema.org TouristTrip)."},{"name":"POI","description":"Punti di interesse (schema.org Place / TouristAttraction)."},{"name":"Eventi","description":"Eventi (schema.org Event)."},{"name":"Risorsa singola","description":"Recupero di una singola risorsa per slug."}],"paths":{"/api/public/italia-it":{"get":{"tags":["Discovery"],"summary":"Catalogo dati (discovery)","description":"Punto di ingresso machine-readable (`schema.org/DataCatalog`) che\ndescrive tutti i dataset disponibili, gli endpoint, i parametri\nsupportati e gli schemi di riferimento.\n","responses":{"200":{"description":"Catalogo dati JSON-LD","content":{"application/ld+json":{"schema":{"$ref":"#/components/schemas/DataCatalog"},"example":{"@context":"https://schema.org","@type":"DataCatalog","name":"Riviera d'Ulisse — Open Tourism API","inLanguage":["it","en"],"encodingFormat":"application/ld+json","dataset":[{"@type":"Dataset","identifier":"poi","name":"Punti di interesse (TouristAttraction)","schemaType":"https://schema.org/TouristAttraction"}]}}}}}}},"/api/public/italia-it/esperienze":{"get":{"tags":["Esperienze"],"summary":"Elenco esperienze (schema.org TouristTrip)","parameters":[{"$ref":"#/components/parameters/Lang"},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PageSize"}],"responses":{"200":{"description":"Lista paginata di TouristTrip (envelope EsperienzeListResponse)","content":{"application/ld+json":{"schema":{"$ref":"#/components/schemas/EsperienzeListResponse"},"example":{"@context":"https://schema.org","kind":"esperienze","lang":"it","page":1,"pageSize":20,"total":12,"totalPages":1,"items":[{"@context":"https://schema.org","@type":"TouristTrip","@id":"esp-trekking-monte-orlando","name":[{"@value":"Trekking al Monte Orlando","@language":"it"},{"@value":"Monte Orlando trekking","@language":"en"}],"touristType":["natura"],"keywords":[{"@value":"natura, trekking","@language":"it"},{"@value":"nature, trekking","@language":"en"}],"about":{"@type":"Thing","name":[{"@value":"Natura","@language":"it"},{"@value":"Nature","@language":"en"}],"identifier":"urn:rdu:categoria:natura"}}]}}}},"400":{"$ref":"#/components/responses/InvalidQuery"},"404":{"$ref":"#/components/responses/InvalidKind"},"500":{"$ref":"#/components/responses/SchemaValidationFailed"}}}},"/api/public/italia-it/poi":{"get":{"tags":["POI"],"summary":"Elenco POI (schema.org Place / TouristAttraction)","description":"Unisce il dataset statico curato e i POI pubblicati dal CMS interno.\nSupporta richieste condizionali tramite header `If-None-Match` (ETag).\n","parameters":[{"$ref":"#/components/parameters/Lang"},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PageSize"},{"in":"header","name":"If-None-Match","required":false,"description":"ETag per richieste condizionali (risponde 304 se invariato).","schema":{"type":"string"}}],"responses":{"200":{"description":"Lista paginata di Place / TouristAttraction (envelope POIListResponse)","content":{"application/ld+json":{"schema":{"$ref":"#/components/schemas/POIListResponse"},"example":{"@context":"https://schema.org","kind":"poi","lang":"it","page":1,"pageSize":20,"total":34,"totalPages":2,"items":[{"@context":"https://schema.org","@type":"TouristAttraction","@id":"poi-abbazia-di-fossanova","inLanguage":["it","en"],"name":[{"@value":"Abbazia di Fossanova","@language":"it"},{"@value":"Fossanova Abbey","@language":"en"}],"description":[{"@value":"Capolavoro dell'architettura cistercense.","@language":"it"},{"@value":"A masterpiece of Cistercian architecture.","@language":"en"}],"image":"https://latinaturismo.it/img/fossanova.jpg","geo":{"@type":"GeoCoordinates","latitude":41.4061,"longitude":13.2628},"isAccessibleForFree":true,"containedInPlace":{"@type":"Place","identifier":"urn:rdu:dest:priverno"}}]}}}},"304":{"description":"Not Modified — l'ETag fornito corrisponde alla versione corrente."},"400":{"$ref":"#/components/responses/InvalidQuery"},"404":{"$ref":"#/components/responses/InvalidKind"},"500":{"$ref":"#/components/responses/SchemaValidationFailed"}}}},"/api/public/italia-it/eventi":{"get":{"tags":["Eventi"],"summary":"Elenco eventi (schema.org Event)","description":"Eventi ordinati cronologicamente, mappati a schema.org Event.","parameters":[{"$ref":"#/components/parameters/Lang"},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PageSize"}],"responses":{"200":{"description":"Lista paginata di Event (envelope EventiListResponse)","content":{"application/ld+json":{"schema":{"$ref":"#/components/schemas/EventiListResponse"},"example":{"@context":"https://schema.org","kind":"eventi","lang":"it","page":1,"pageSize":20,"total":8,"totalPages":1,"items":[{"@context":"https://schema.org","@type":"Event","@id":"evt-sagra-del-pesce-2026","inLanguage":["it","en"],"name":[{"@value":"Sagra del Pesce","@language":"it"},{"@value":"Seafood Festival","@language":"en"}],"description":[{"@value":"Degustazioni sul lungomare.","@language":"it"},{"@value":"Tastings on the seafront.","@language":"en"}],"image":"https://latinaturismo.it/img/sagra-pesce.jpg","startDate":"2026-07-18T18:00:00.000Z","endDate":"2026-07-18T23:00:00.000Z","eventStatus":"https://schema.org/EventScheduled","location":{"@type":"Place","name":[{"@value":"Lungomare di Gaeta","@language":"it"},{"@value":"Gaeta seafront","@language":"en"}],"identifier":"urn:rdu:dest:gaeta"},"about":[{"@value":"Food","@language":"it"},{"@value":"Food","@language":"en"}]}]}}}},"400":{"$ref":"#/components/responses/InvalidQuery"},"404":{"$ref":"#/components/responses/InvalidKind"},"500":{"$ref":"#/components/responses/SchemaValidationFailed"}}}},"/api/public/italia-it/{kind}/{slug}":{"get":{"tags":["Risorsa singola"],"summary":"Singola risorsa per slug (envelope { kind, lang, item })","description":"Restituisce una singola risorsa (esperienza, POI o evento) identificata\ndallo slug. Il payload è incapsulato in un envelope `{ kind, lang, item }`\ndove `item` è il documento schema.org corrispondente al `kind`.\n","parameters":[{"in":"path","name":"kind","required":true,"schema":{"type":"string","enum":["destinazioni","poi","eventi","itinerari"]}},{"in":"path","name":"slug","required":true,"description":"Slug kebab-case della risorsa.","schema":{"type":"string","pattern":"^[a-z0-9-]+$","maxLength":120}},{"$ref":"#/components/parameters/Lang"}],"responses":{"200":{"description":"Risorsa singola JSON-LD","content":{"application/ld+json":{"schema":{"$ref":"#/components/schemas/ItemResponse"},"example":{"kind":"poi","lang":"it","item":{"@context":"https://schema.org","@type":"TouristAttraction","@id":"poi-abbazia-di-fossanova","inLanguage":["it","en"],"name":[{"@value":"Abbazia di Fossanova","@language":"it"},{"@value":"Fossanova Abbey","@language":"en"}],"geo":{"@type":"GeoCoordinates","latitude":41.4061,"longitude":13.2628}}}}}},"400":{"$ref":"#/components/responses/InvalidQuery"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/public/jsonld/{kind}/{slug}":{"get":{"tags":["Risorsa singola"],"summary":"JSON-LD page-level (@graph) per una risorsa","description":"Espone lo stesso payload schema.org embedded nelle pagine HTML\n(TouristDestination / Event / TouristAttraction + BreadcrumbList) per\nconsumo API-first da parte di TDH/ITALIA.it e crawler interoperabili.\n","parameters":[{"in":"path","name":"kind","required":true,"schema":{"type":"string","enum":["destinazioni","eventi","poi"]}},{"in":"path","name":"slug","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]+$","maxLength":120}},{"$ref":"#/components/parameters/Lang"}],"responses":{"200":{"description":"Documento JSON-LD (@graph) coerente con la lingua richiesta","content":{"application/ld+json":{"schema":{"$ref":"#/components/schemas/JsonLdGraph"},"example":{"@context":"https://schema.org","@graph":[{"@type":"TouristAttraction","name":"Abbazia di Fossanova"},{"@type":"BreadcrumbList","itemListElement":[]}]}}}},"400":{"$ref":"#/components/responses/InvalidQuery"},"404":{"$ref":"#/components/responses/NotFound"}}}}},"components":{"parameters":{"Lang":{"in":"query","name":"lang","required":false,"description":"Lingua dei contenuti.","schema":{"type":"string","enum":["it","en"],"default":"it"}},"Page":{"in":"query","name":"page","required":false,"description":"Pagina richiesta (1-based).","schema":{"type":"integer","minimum":1,"maximum":10000,"default":1}},"PageSize":{"in":"query","name":"pageSize","required":false,"description":"Dimensione pagina.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}},"responses":{"InvalidQuery":{"description":"invalid_query — parametri lang/page/pageSize non validi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Invalid query parameters","code":"invalid_query"}}}},"InvalidKind":{"description":"invalid_kind — kind non riconosciuto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Invalid route parameter","code":"invalid_kind"}}}},"NotFound":{"description":"not_found — nessuna risorsa con lo slug indicato","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"No poi with slug \"xxx\"","code":"not_found"}}}},"SchemaValidationFailed":{"description":"schema_validation_failed — un item non rispetta il contratto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Response items did not pass schema validation","code":"schema_validation_failed"}}}}},"schemas":{"LangValue":{"type":"object","required":["@value","@language"],"properties":{"@value":{"type":"string","minLength":1},"@language":{"type":"string","enum":["it","en"]}}},"MultilingualString":{"description":"Stringa semplice OPPURE array language-tagged (1+ entry).","oneOf":[{"type":"string","minLength":1},{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/LangValue"}}]},"BilingualString":{"description":"Array language-tagged che DEVE contenere sia IT che EN.","type":"array","minItems":2,"items":{"$ref":"#/components/schemas/LangValue"}},"GeoCoordinates":{"type":"object","required":["@type","latitude","longitude"],"properties":{"@type":{"const":"GeoCoordinates"},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180}}},"ImageObject":{"type":"object","required":["@type","contentUrl","url","inLanguage"],"properties":{"@type":{"const":"ImageObject"},"contentUrl":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"inLanguage":{"type":"string","enum":["it","en"]},"name":{"type":"string"},"caption":{"type":"string"}}},"ListEnvelope":{"type":"object","description":"Campi comuni a tutte le risposte lista paginate.","required":["@context","kind","lang","page","pageSize","total","totalPages","items"],"properties":{"@context":{"const":"https://schema.org"},"lang":{"type":"string","enum":["it","en"]},"page":{"type":"integer","minimum":1},"pageSize":{"type":"integer","minimum":1,"maximum":100},"total":{"type":"integer","minimum":0},"totalPages":{"type":"integer","minimum":1,"description":"ceil(total / pageSize)"}}},"AboutThing":{"type":"object","required":["@type","name","identifier"],"properties":{"@type":{"const":"Thing"},"name":{"$ref":"#/components/schemas/BilingualString"},"identifier":{"type":"string","pattern":"^urn:rdu:categoria:(mare|cultura|natura|food)$"}}},"EsperienzaTrip":{"type":"object","required":["@context","@type","@id","touristType","keywords","about"],"additionalProperties":true,"properties":{"@context":{"const":"https://schema.org"},"@type":{"const":"TouristTrip"},"@id":{"type":"string","minLength":1},"name":{"$ref":"#/components/schemas/MultilingualString"},"description":{"$ref":"#/components/schemas/MultilingualString"},"touristType":{"type":"array","minItems":1,"items":{"type":"string","enum":["mare","cultura","natura","food"]}},"keywords":{"$ref":"#/components/schemas/BilingualString"},"about":{"$ref":"#/components/schemas/AboutThing"}}},"EsperienzeListResponse":{"allOf":[{"$ref":"#/components/schemas/ListEnvelope"},{"type":"object","properties":{"kind":{"const":"esperienze"},"items":{"type":"array","items":{"$ref":"#/components/schemas/EsperienzaTrip"}}}}]},"POIPlace":{"type":"object","required":["@context","@type","@id","inLanguage","name","description","geo"],"properties":{"@context":{"const":"https://schema.org"},"@type":{"type":"string","enum":["Place","TouristAttraction","TouristDestination"]},"@id":{"type":"string","minLength":1},"inLanguage":{"type":"array","minItems":1,"items":{"type":"string","enum":["it","en"]}},"name":{"$ref":"#/components/schemas/MultilingualString"},"description":{"$ref":"#/components/schemas/MultilingualString"},"image":{"oneOf":[{"type":"string","minLength":1},{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/ImageObject"}}]},"geo":{"$ref":"#/components/schemas/GeoCoordinates"},"isAccessibleForFree":{"type":"boolean"},"openingHours":{"$ref":"#/components/schemas/MultilingualString"},"additionalType":{"$ref":"#/components/schemas/MultilingualString"},"containedInPlace":{"type":"object","required":["@type","identifier"],"properties":{"@type":{"const":"Place"},"identifier":{"type":"string","pattern":"^urn:rdu:dest:[a-z0-9-]+$"}}}}},"POIListResponse":{"allOf":[{"$ref":"#/components/schemas/ListEnvelope"},{"type":"object","properties":{"kind":{"const":"poi"},"items":{"type":"array","items":{"$ref":"#/components/schemas/POIPlace"}}}}]},"EventDocument":{"type":"object","required":["@context","@type","@id","inLanguage","name","description","startDate","endDate","eventStatus","location"],"properties":{"@context":{"const":"https://schema.org"},"@type":{"const":"Event"},"@id":{"type":"string","minLength":1},"inLanguage":{"type":"array","minItems":1,"items":{"type":"string","enum":["it","en"]}},"name":{"$ref":"#/components/schemas/MultilingualString"},"description":{"$ref":"#/components/schemas/MultilingualString"},"image":{"type":"string"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"},"eventStatus":{"type":"string","example":"https://schema.org/EventScheduled"},"location":{"type":"object","required":["@type","name"],"properties":{"@type":{"const":"Place"},"name":{"$ref":"#/components/schemas/MultilingualString"},"identifier":{"type":"string","pattern":"^urn:rdu:dest:[a-z0-9-]+$"}}},"about":{"$ref":"#/components/schemas/MultilingualString"}}},"EventiListResponse":{"allOf":[{"$ref":"#/components/schemas/ListEnvelope"},{"type":"object","properties":{"kind":{"const":"eventi"},"items":{"type":"array","items":{"$ref":"#/components/schemas/EventDocument"}}}}]},"ItemResponse":{"type":"object","required":["kind","lang","item"],"properties":{"kind":{"type":"string","enum":["destinazioni","poi","eventi","itinerari"]},"lang":{"type":"string","enum":["it","en"]},"item":{"description":"Documento schema.org coerente con `kind`.","oneOf":[{"$ref":"#/components/schemas/POIPlace"},{"$ref":"#/components/schemas/EventDocument"},{"$ref":"#/components/schemas/EsperienzaTrip"}]}}},"JsonLdGraph":{"type":"object","required":["@context","@graph"],"properties":{"@context":{"const":"https://schema.org"},"@graph":{"type":"array","items":{"type":"object"}}}},"DataCatalog":{"type":"object","required":["@context","@type","name","dataset"],"properties":{"@context":{"const":"https://schema.org"},"@type":{"const":"DataCatalog"},"name":{"type":"string"},"description":{"type":"string"},"inLanguage":{"type":"array","items":{"type":"string","enum":["it","en"]}},"encodingFormat":{"type":"string"},"dataset":{"type":"array","items":{"type":"object","properties":{"@type":{"const":"Dataset"},"identifier":{"type":"string"},"name":{"type":"string"},"schemaType":{"type":"string"}}}}}},"ApiError":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Messaggio human-readable"},"code":{"type":"string","enum":["invalid_kind","invalid_params","invalid_query","not_found","schema_validation_failed"]},"details":{"description":"Dettagli specifici per codice (fieldErrors o issues Zod)"}}}}}}