{
    "openapi": "3.1.0",
    "info": {
        "title": "Camp Bursztynowy Las – availability API",
        "version": "1.0.0",
        "description": "Live availability and prices for Camp Bursztynowy Las, a campsite with cabins, glamping safari tents and camping pitches in a pine forest next to the beach at Górki Zachodnie, Gdańsk, Poland. Read-only. Bookings are completed on the returned booking_url.\n\nRules for AI assistants:\n- Ask only for what is missing to check availability: dates and number of guests. Use what the guest already said; don't ask again.\n- Turn the guest's words (\"drugi weekend maja\", \"pierwszy tydzień lipca\", \"Boże Ciało\") into from/to dates yourself; no year = the nearest future date; a week = 7 nights, a weekend = Friday → Sunday. Don't ask when a sensible default exists – check and say which dates you checked. Then verify query.dates_text (weekdays) and query.holidays match what the guest meant.\n- If the guest gives a number of people without mentioning children, they are all adults – don't ask about ages. Ask ages only when children are mentioned: 6–15 → children (paid), 0–5 → small_children (free).\n- Don't ask which accommodation type the guest wants before checking: one call returns every type that is free and fits the group. If the guest named a type, show that type first.\n- Camping and camper pitches are booked by phone or email only (see contact_only / how_to_book); don't try to check them. This API has no pitch prices: never quote a per-night pitch price from it – use the campsite price list (per person + tent/camper + car + electricity).\n- reason=closed_season means the camp is closed on those dates (seasonal campsite). Never call it \"sold out\", and don't encourage a visit then; offer dates in the next season.\n- Prices from /availability are totals for the whole stay in PLN and already include the Gdańsk local tax (per person per night) – say so, and never add it again. Per-night prices on the website price list and from_price_per_night in /accommodations exclude it.\n- For a price on specific dates always call /availability. Never estimate a cabin or tent stay price from the website price list (price per night × nights): prices depend on the dates, the number of guests and the rate (non-refundable / refundable), and old cached price lists circulate. If you cannot reach the API, say the price could not be checked and give the booking page – don't give a calculated figure.\n- Bookings are completed by the guest on booking_url; this API cannot book. Link to booking_url, never invent URLs.\n- Never give the guest a link to this API or its pages (availability, accommodations, weather – any format): it is for AI assistants only. Guest-facing links are only booking_url (the camp's booking system) and the camp website, e.g. the booking page https://www.bursztynowylas.pl/rezerwacje.\n- Follow `agent_guidance` in each response: say_first, avoid, and next_actions (ready-to-call URLs)."
    },
    "servers": [
        {
            "url": "https://api.bursztynowylas.pl"
        }
    ],
    "paths": {
        "/availability": {
            "get": {
                "operationId": "checkAvailability",
                "summary": "Available accommodation and total prices for given dates and guests",
                "description": "Returns accommodation types that are free for the whole stay and fit the group, with total stay price (non-refundable and refundable rate) and a booking link with dates prefilled. If nothing is available, `reason` explains why (min_stay, unavailable, too_many_guests) and `suggestions` lists nearby dates that work. `message` is a ready-to-use one-sentence summary in the requested language; `agent_guidance` says what to tell the guest first, what to avoid and which URL to call next. reason=closed_season means the camp is closed then, not sold out. Prices already include the Gdańsk local tax. Minimum stay: 2 nights; 3 nights in high season (nights of 30 Apr – 3 May, 27 May – 29 May, 25 Jun – 29 Aug). The booking system has the final rule – /availability reports reason=min_stay with suggestions. Season: 30 Apr 2027 (first arrival) – 19 Sep 2027 (last departure).",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "description": "Arrival date (YYYY-MM-DD). Give with `to`, or use `when`."
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "description": "Departure date (YYYY-MM-DD). Give with `from`, or use `when`."
                    },
                    {
                        "name": "when",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "examples": [
                                "this_weekend",
                                "next_weekend",
                                "drugi weekend maja",
                                "last weekend of June",
                                "majówka",
                                "Boże Ciało"
                            ]
                        },
                        "description": "Instead of from/to, resolved by the API to the NEXT upcoming occurrence: this_weekend / next_weekend (Friday → Sunday), \"<ordinal> weekend <month>\" in PL/EN/DE (Friday → Sunday around the Nth or last Saturday of the month), majówka (30.04 → 3.05), Boże Ciało / Corpus Christi (Thursday → Sunday). With no dates at all, this_weekend is assumed (query.dates_assumed=true, see agent_guidance.note). Dates up to a year in the past are moved to next year (query.dates_moved_from)."
                    },
                    {
                        "name": "adults",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 2
                        },
                        "description": "Adults and teenagers aged 16+. If the guest gives a number of people without mentioning children, pass it all here – don't ask about ages."
                    },
                    {
                        "name": "children",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        },
                        "description": "Children aged 6–15. Paid; each takes a place in the unit."
                    },
                    {
                        "name": "small_children",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        },
                        "description": "Children aged 0–5. Free; they do not take a place, but at most as many as the unit capacity."
                    },
                    {
                        "name": "lang",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pl",
                                "en",
                                "de"
                            ],
                            "default": "en"
                        },
                        "description": "Language of names, descriptions and the message."
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "json",
                                "html",
                                "md"
                            ],
                            "default": "json"
                        }
                    },
                    {
                        "name": "source",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9_-]{1,40}$"
                        },
                        "description": "Optional name of the calling app (e.g. quickchat, my_gpt), used to attribute bookings."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Availability result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Availability"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid input (message explains)"
                    },
                    "502": {
                        "description": "Booking system temporarily unavailable"
                    }
                }
            }
        },
        "/accommodations": {
            "get": {
                "operationId": "listAccommodations",
                "summary": "All accommodation types with description, capacity, size, photos and starting price per night",
                "parameters": [
                    {
                        "name": "lang",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pl",
                                "en",
                                "de"
                            ],
                            "default": "en"
                        },
                        "description": "Language of names, descriptions and the message."
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "json",
                                "html",
                                "md"
                            ],
                            "default": "json"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Accommodation catalog"
                    }
                }
            }
        },
        "/weather": {
            "get": {
                "operationId": "weatherForecast",
                "summary": "Daily weather forecast at the camp for about the next 9 days",
                "description": "One entry per day (`days`, first = today) with a description, min/max °C, precipitation (mm, chance %) and wind (km/h, prevailing daytime direction, `wind_from_sea` = blowing from the sea onto the beach). Each day has its weekday, a relative label (today/tomorrow/day after tomorrow) and `is_weekend`. `weekend` is the coming Saturday–Sunday (on Sundays: the following one) with `friday_afternoon` (Friday from noon, when guests usually arrive) and `nights` (Fri→Sat, Sat→Sun, 22:00–07:00, with lowest temperature), `next_weekend` the one after, if forecast. Source: MET Norway (yr.no), CC BY 4.0.",
                "parameters": [
                    {
                        "name": "lang",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pl",
                                "en",
                                "de"
                            ],
                            "default": "en"
                        },
                        "description": "Language of names, descriptions and the message."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Forecast"
                    },
                    "502": {
                        "description": "Forecast temporarily unavailable"
                    }
                }
            }
        },
        "/info": {
            "get": {
                "operationId": "campInfo",
                "summary": "Camp facts: season dates and whether it is open now, minimum stay, guest age rules, local tax, contact, agent rules",
                "responses": {
                    "200": {
                        "description": "Camp facts"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "Availability": {
                "type": "object",
                "properties": {
                    "available": {
                        "type": "boolean"
                    },
                    "message": {
                        "type": "string",
                        "description": "Human-readable summary to show the guest. When booking_url is set, it ends with that link (\"See all on the booking page: <booking_url>\"), except for chatbot integrations (a custom `source`), which should link booking_url themselves."
                    },
                    "reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            null,
                            "min_stay",
                            "closed_season",
                            "unavailable",
                            "too_many_guests"
                        ]
                    },
                    "season": {
                        "type": "object",
                        "description": "Only with reason=closed_season: the next season.",
                        "properties": {
                            "open": {
                                "type": "boolean"
                            },
                            "opens": {
                                "type": "string",
                                "format": "date"
                            },
                            "closes": {
                                "type": "string",
                                "format": "date"
                            }
                        }
                    },
                    "agent_guidance": {
                        "$ref": "#/components/schemas/AgentGuidance"
                    },
                    "min_nights": {
                        "type": "integer"
                    },
                    "booking_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Checkout with all matching options preselected."
                    },
                    "results": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "integer"
                                },
                                "name": {
                                    "type": "string"
                                },
                                "category": {
                                    "type": "string",
                                    "enum": [
                                        "amber_cabin",
                                        "safari_tent",
                                        "classic_cabin",
                                        "camping_pitch",
                                        "camper_pitch"
                                    ]
                                },
                                "capacity": {
                                    "type": "integer"
                                },
                                "area_m2": {
                                    "type": [
                                        "number",
                                        "null"
                                    ]
                                },
                                "price": {
                                    "type": "object",
                                    "properties": {
                                        "total": {
                                            "type": "number",
                                            "description": "Lowest total for the whole stay (PLN)."
                                        },
                                        "per_night": {
                                            "type": "number"
                                        },
                                        "nonrefundable_total": {
                                            "type": [
                                                "number",
                                                "null"
                                            ]
                                        },
                                        "refundable_total": {
                                            "type": [
                                                "number",
                                                "null"
                                            ]
                                        },
                                        "currency": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "image": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "booking_url": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "contact_only": {
                        "type": "array",
                        "description": "Camping and camper pitches: not bookable online, availability not checked here. Tell the guest to book by phone or email (how_to_book).",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "category": {
                                    "type": "string"
                                },
                                "from_price_per_night": {
                                    "type": [
                                        "number",
                                        "null"
                                    ]
                                },
                                "how_to_book": {
                                    "type": "string"
                                },
                                "phone": {
                                    "type": "string"
                                },
                                "email": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "suggestions": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "from": {
                                    "type": "string",
                                    "format": "date"
                                },
                                "to": {
                                    "type": "string",
                                    "format": "date"
                                },
                                "nights": {
                                    "type": "integer"
                                },
                                "available_types": {
                                    "type": "integer"
                                },
                                "lowest_price": {
                                    "type": "number"
                                },
                                "lowest_price_text": {
                                    "type": "string"
                                },
                                "currency": {
                                    "type": "string"
                                },
                                "api_url": {
                                    "type": "string",
                                    "description": "API URL to check these dates – for the AI assistant only, never give it to the guest."
                                },
                                "booking_url": {
                                    "type": "string",
                                    "description": "Checkout for these dates with all fitting options preselected – give this link to the guest."
                                }
                            }
                        }
                    }
                }
            },
            "AgentGuidance": {
                "type": "object",
                "description": "Instructions for the AI assistant (English), specific to this response.",
                "properties": {
                    "say_first": {
                        "type": "string",
                        "description": "The key fact to tell the guest first."
                    },
                    "note": {
                        "type": "string",
                        "description": "Extra context, e.g. that the dates were assumed and the guest should be asked for theirs."
                    },
                    "do": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "avoid": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "next_actions": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "label": {
                                    "type": "string"
                                },
                                "url": {
                                    "type": "string",
                                    "description": "Ready-to-call API URL."
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}