{
  "openapi": "3.1.0",
  "info": {
    "title": "All'ombra del Vesuvio Rooms API",
    "version": "1.0.0",
    "description": "Public read-only API with the apartments, travel guides, experiences and tour discount codes of All'ombra del Vesuvio Rooms (Naples, Italy). No authentication. Rate limit: 60 requests per 60 seconds per client IP, reported with the IETF RateLimit-Policy and RateLimit headers. Errors use application/problem+json (RFC 9457).",
    "contact": {
      "name": "All'ombra del Vesuvio Rooms",
      "email": "allombradelvesuviorooms@gmail.com",
      "url": "https://allombradelvesuviorooms.com/contact"
    }
  },
  "externalDocs": {
    "description": "Developer docs",
    "url": "https://allombradelvesuviorooms.com/docs"
  },
  "servers": [
    {
      "url": "https://allombradelvesuviorooms.com"
    }
  ],
  "tags": [
    {
      "name": "Business",
      "description": "Business identity and contacts."
    },
    {
      "name": "Apartments",
      "description": "Bookable apartments."
    },
    {
      "name": "Content",
      "description": "Travel guides and experiences."
    },
    {
      "name": "Discounts",
      "description": "Partner discount codes for tours."
    }
  ],
  "paths": {
    "/api/v1/info": {
      "get": {
        "operationId": "getBusinessInfo",
        "summary": "Get business info",
        "description": "Returns the name, address, contacts, check-in times, price range and resource counts of the business.",
        "tags": [
          "Business"
        ],
        "responses": {
          "200": {
            "description": "Business info.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessInfo"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          }
        }
      }
    },
    "/api/v1/apartments": {
      "get": {
        "operationId": "listApartments",
        "summary": "List apartments",
        "description": "Returns every apartment currently offered, with capacity, starting price per night and booking link.",
        "tags": [
          "Apartments"
        ],
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Content language. Defaults to en.",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "it"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Apartment list.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApartmentList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          }
        }
      }
    },
    "/api/v1/apartments/{id}": {
      "get": {
        "operationId": "getApartment",
        "summary": "Get one apartment",
        "description": "Returns the full description, amenities, nearby places and transport options of one apartment.",
        "tags": [
          "Apartments"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Apartment id, as returned by listApartments.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,64}$",
              "examples": [
                "vomero"
              ]
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Content language. Defaults to en.",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "it"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Apartment detail.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApartmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "No active apartment with this id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          }
        }
      }
    },
    "/api/v1/guides": {
      "get": {
        "operationId": "listGuides",
        "summary": "List travel guides",
        "description": "Returns the travel guides for Naples and the Campania region, optionally filtered by category.",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Content language. Defaults to en.",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "it"
              ],
              "default": "en"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Case-insensitive category filter, for example 'History' or 'Food & Dining'.",
            "schema": {
              "type": "string",
              "maxLength": 64
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Guide list.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuideList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          }
        }
      }
    },
    "/api/v1/experiences": {
      "get": {
        "operationId": "listExperiences",
        "summary": "List experiences",
        "description": "Returns the tours and local experiences recommended to guests.",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Content language. Defaults to en.",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "it"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Experience list.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExperienceList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          }
        }
      }
    },
    "/api/v1/discounts": {
      "get": {
        "operationId": "listDiscountCodes",
        "summary": "List tour discount codes",
        "description": "Returns the active partner discount codes for boat tours in Naples, Capri and the Amalfi Coast: code, percentage, partner, how to use it and the partner booking link. The code is entered when booking on the partner's website.",
        "tags": [
          "Discounts"
        ],
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Content language. Defaults to en.",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "it"
              ],
              "default": "en"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Discount code list.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscountList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimitPolicy": {
        "description": "IETF RateLimit-Policy header, for example \"default\";q=60;w=60.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimit": {
        "description": "IETF RateLimit header with remaining requests (r) and seconds to reset (t).",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "resolution": {
            "type": "string"
          }
        }
      },
      "PostalAddress": {
        "type": "object",
        "properties": {
          "streetAddress": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          },
          "addressLocality": {
            "type": "string"
          },
          "addressRegion": {
            "type": "string"
          },
          "addressCountry": {
            "type": "string"
          }
        }
      },
      "BusinessInfo": {
        "type": "object",
        "required": [
          "name",
          "url",
          "email",
          "address"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "telephone": {
            "type": "string"
          },
          "address": {
            "$ref": "#/components/schemas/PostalAddress"
          },
          "geo": {
            "type": "object",
            "properties": {
              "latitude": {
                "type": "number"
              },
              "longitude": {
                "type": "number"
              }
            }
          },
          "checkinTime": {
            "type": "string"
          },
          "checkoutTime": {
            "type": "string"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "logo": {
            "type": "string",
            "format": "uri"
          },
          "image": {
            "type": "string",
            "format": "uri"
          },
          "sameAs": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "priceRange": {
            "type": "string"
          },
          "counts": {
            "type": "object",
            "properties": {
              "apartments": {
                "type": "integer"
              },
              "guides": {
                "type": "integer"
              },
              "experiences": {
                "type": "integer"
              }
            }
          },
          "links": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          }
        }
      },
      "ApartmentSummary": {
        "type": "object",
        "required": [
          "id",
          "name",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "location": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "capacity": {
            "type": [
              "string",
              "null"
            ]
          },
          "bedrooms": {
            "type": [
              "number",
              "null"
            ]
          },
          "beds": {
            "type": [
              "number",
              "null"
            ]
          },
          "baths": {
            "type": [
              "number",
              "null"
            ]
          },
          "priceFromPerNightEur": {
            "type": [
              "number",
              "null"
            ]
          },
          "rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "reviewsCount": {
            "type": [
              "number",
              "null"
            ]
          },
          "bookingUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "bookingRequestOnSite": {
            "type": "boolean"
          }
        }
      },
      "ApartmentDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApartmentSummary"
          },
          {
            "type": "object",
            "properties": {
              "longDescription": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "features": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "amenities": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "guestAccess": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "locationDescription": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "nearby": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "distance": {
                      "type": "string"
                    }
                  }
                }
              },
              "transportOptions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "details": {
                      "type": "string"
                    }
                  }
                }
              },
              "checkinTime": {
                "type": "string"
              },
              "checkoutTime": {
                "type": "string"
              }
            }
          }
        ]
      },
      "ApartmentList": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string"
          },
          "apartments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApartmentSummary"
            }
          }
        }
      },
      "ApartmentResponse": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string"
          },
          "apartment": {
            "$ref": "#/components/schemas/ApartmentDetail"
          }
        }
      },
      "Guide": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "visitDuration": {
            "type": [
              "string",
              "null"
            ]
          },
          "bestTimeToVisit": {
            "type": [
              "string",
              "null"
            ]
          },
          "tips": {
            "type": [
              "string",
              "null"
            ]
          },
          "mapLink": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "GuideList": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "guides": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Guide"
            }
          }
        }
      },
      "Experience": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "providerUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "ticketInfo": {
            "type": [
              "string",
              "null"
            ]
          },
          "openingHours": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Discount": {
        "type": "object",
        "required": [
          "code",
          "percentOff",
          "partner",
          "pageUrl",
          "bookingUrl"
        ],
        "properties": {
          "code": {
            "type": "string",
            "examples": [
              "VOMERO26"
            ]
          },
          "percentOff": {
            "type": "number",
            "examples": [
              5
            ]
          },
          "partner": {
            "type": "string"
          },
          "experienceId": {
            "type": "string"
          },
          "experienceName": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "howToUse": {
            "type": [
              "string",
              "null"
            ]
          },
          "pageUrl": {
            "type": "string",
            "format": "uri"
          },
          "bookingUrl": {
            "type": "string",
            "format": "uri"
          },
          "tours": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "duration": {
                  "type": "string"
                },
                "price": {
                  "type": "string"
                }
              }
            }
          },
          "priceInfo": {
            "type": [
              "string",
              "null"
            ]
          },
          "validFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "lastVerified": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          }
        }
      },
      "DiscountList": {
        "type": "object",
        "required": [
          "lang",
          "discounts"
        ],
        "properties": {
          "lang": {
            "type": "string"
          },
          "pageUrl": {
            "type": "string",
            "format": "uri"
          },
          "lastVerified": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "discounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Discount"
            }
          }
        }
      },
      "ExperienceList": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string"
          },
          "experiences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Experience"
            }
          }
        }
      }
    }
  }
}