{
  "openapi": "3.1.1",
  "info": {
    "title": "Sunshine Bay Rentals Public Property API",
    "version": "1.0.0",
    "description": "Free, read-only access to the public property catalogue and owner contact information. No API key, account or payment required. This catalogue does not provide live availability, prices, quotes or reservations. Check the linked Airbnb listing for current dates and terms, or use /book to select dates and prepare an email enquiry to the owner. An enquiry is not a confirmed booking.",
    "contact": {
      "name": "Sunshine Bay Rentals",
      "email": "hello@sunshinebayrentals.com",
      "url": "https://sunshinebayrentals.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://sunshinebayrentals.com"
    }
  ],
  "security": [],
  "externalDocs": {
    "description": "Sunshine Bay Rentals developer documentation",
    "url": "https://sunshinebayrentals.com/docs"
  },
  "paths": {
    "/api/v1/properties": {
      "get": {
        "operationId": "listProperties",
        "summary": "List the public vacation rental catalogue, optionally filtering by region and guest capacity.",
        "description": "List the public vacation rental catalogue, optionally filtering by region and guest capacity.",
        "security": [],
        "parameters": [
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Exact region name; omit for both destinations.",
            "schema": {
              "type": "string",
              "enum": [
                "Ontario",
                "Florida"
              ]
            }
          },
          {
            "name": "minGuests",
            "in": "query",
            "required": false,
            "description": "Return properties with capacity at least this integer. This does not check availability.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public information; no live rates or availability.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PropertyList"
                }
              }
            }
          },
          "400": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/properties/{slug}": {
      "get": {
        "operationId": "getProperty",
        "summary": "Get a single rental by its stable slug, including its Airbnb booking link and selected photos.",
        "description": "Get a single rental by its stable slug, including its Airbnb booking link and selected photos.",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Property slug returned by listProperties.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public information; no live rates or availability.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Property"
                }
              }
            }
          },
          "400": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/site": {
      "get": {
        "operationId": "getSiteInfo",
        "summary": "Get Sunshine Bay Rentals identity, owner contact details and booking limitations.",
        "description": "Get Sunshine Bay Rentals identity, owner contact details and booking limitations.",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Public information; no live rates or availability.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Site"
                }
              }
            }
          },
          "400": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "RFC 9457 problem details with a stable code and resolution hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Property": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Stable property identifier.",
            "pattern": "^[a-z0-9-]+$"
          },
          "name": {
            "type": "string",
            "description": "Property name."
          },
          "location": {
            "type": "string",
            "description": "Public destination; not a street address."
          },
          "region": {
            "type": "string",
            "enum": [
              "Ontario",
              "Florida"
            ],
            "description": "Province or state."
          },
          "maxGuests": {
            "type": "integer",
            "minimum": 1,
            "description": "Advertised maximum guest count."
          },
          "bedrooms": {
            "type": "integer",
            "minimum": 1,
            "description": "Advertised bedroom count."
          },
          "bathrooms": {
            "type": "number",
            "minimum": 0,
            "description": "Advertised bathroom count."
          },
          "description": {
            "type": "string",
            "description": "Description of the property."
          },
          "amenities": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Amenity description."
            },
            "description": "Selected amenities; consult the listing for full details."
          },
          "notes": {
            "type": "string",
            "description": "Important layout or stay restrictions; empty if none stated."
          },
          "bookingUrl": {
            "type": "string",
            "description": "Airbnb listing for current availability, prices and booking terms.",
            "format": "uri"
          },
          "pageUrl": {
            "type": "string",
            "description": "Property card on the Sunshine Bay Rentals website.",
            "format": "uri"
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string",
                  "description": "Public photo URL.",
                  "format": "uri"
                },
                "description": {
                  "type": "string",
                  "description": "Photo description."
                }
              },
              "required": [
                "url",
                "description"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "slug",
          "name",
          "location",
          "region",
          "maxGuests",
          "bedrooms",
          "bathrooms",
          "description",
          "amenities",
          "notes",
          "bookingUrl",
          "pageUrl",
          "images"
        ],
        "additionalProperties": false
      },
      "Contact": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "phones": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "description": "Contact country."
                },
                "number": {
                  "type": "string",
                  "description": "International phone number."
                },
                "uri": {
                  "type": "string",
                  "description": "Click-to-call URI.",
                  "format": "uri"
                }
              },
              "required": [
                "label",
                "number",
                "uri"
              ],
              "additionalProperties": false
            }
          },
          "url": {
            "type": "string",
            "description": "Owner contact page.",
            "format": "uri"
          }
        },
        "required": [
          "email",
          "phones",
          "url"
        ],
        "additionalProperties": false
      },
      "Problem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Problem type; about:blank uses the HTTP status meaning.",
            "format": "uri"
          },
          "title": {
            "type": "string",
            "description": "Short error title."
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "detail": {
            "type": "string",
            "description": "Explanation of this failure."
          },
          "instance": {
            "type": "string",
            "description": "Requested path."
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code."
          },
          "hint": {
            "type": "string",
            "description": "How to resolve the error."
          },
          "docs": {
            "type": "string",
            "description": "API documentation.",
            "format": "uri"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code",
          "hint",
          "docs"
        ],
        "additionalProperties": false
      },
      "PropertyList": {
        "type": "object",
        "properties": {
          "properties": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Property"
            }
          },
          "bookingNotice": {
            "type": "string",
            "description": "This catalogue does not provide live availability, prices, quotes or reservations. Check the linked Airbnb listing for current dates and terms, or use /book to select dates and prepare an email enquiry to the owner. An enquiry is not a confirmed booking."
          },
          "lastUpdated": {
            "type": "string",
            "format": "date"
          }
        },
        "required": [
          "properties",
          "bookingNotice",
          "lastUpdated"
        ],
        "additionalProperties": false
      },
      "Site": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Brand name."
          },
          "url": {
            "type": "string",
            "description": "Canonical website.",
            "format": "uri"
          },
          "description": {
            "type": "string",
            "description": "Brand description."
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "bookingNotice": {
            "type": "string",
            "description": "This catalogue does not provide live availability, prices, quotes or reservations. Check the linked Airbnb listing for current dates and terms, or use /book to select dates and prepare an email enquiry to the owner. An enquiry is not a confirmed booking."
          },
          "lastUpdated": {
            "type": "string",
            "format": "date"
          },
          "docsUrl": {
            "type": "string",
            "description": "Documentation.",
            "format": "uri"
          },
          "openapiUrl": {
            "type": "string",
            "description": "OpenAPI specification.",
            "format": "uri"
          },
          "mcpUrl": {
            "type": "string",
            "description": "Streamable HTTP MCP endpoint.",
            "format": "uri"
          }
        },
        "required": [
          "name",
          "url",
          "description",
          "contact",
          "bookingNotice",
          "lastUpdated",
          "docsUrl",
          "openapiUrl",
          "mcpUrl"
        ],
        "additionalProperties": false
      }
    }
  }
}