# PriveSauna.nl Read-Only API Guide > Use this guide to answer questions about PriveSauna.nl rooms, services, media, reviews, prices, and availability. The public website is client-rendered; for factual room data, use the JSON API directly. ## Request Basics Base URL: ```text https://api2.specialmoments.group ``` Required headers: ```http Accept: application/json X-SMG-Brand: 2 Accept-Language: nl-NL ``` Rules for assistants and agents: - Use only `GET` requests. - Use `X-SMG-Brand: 2` for PriveSauna.nl. - Use `Accept-Language: nl-NL` for Dutch content. - Fetch fresh data before answering questions about prices, offers, or availability. Example: ```bash curl -sS "https://api2.specialmoments.group/rooms?per_page=5&page=1" \ -H "Accept: application/json" \ -H "X-SMG-Brand: 2" \ -H "Accept-Language: nl-NL" ``` ## Public Website Links Room API responses contain `id` and `slug`. Public room pages use: ```text https://privesauna.nl/search/{slug}/{id} ``` For example, a room with `"slug": "veldhoven"` and `"id": 350` links to: ```text https://privesauna.nl/search/veldhoven/350 ``` ## Response Conventions - JSON fields use `snake_case`. - Some null or default fields may be omitted. - Coordinates are usually emitted as `[lng, lat]`. - Durations such as room length use ISO-like strings, for example `PT2H30M`. - Timestamps are UTC strings. Convert them to the user’s local timezone when presenting appointment times. - Rich text fields can be JSX-like arrays: `[tag_name, attributes, children]`. Extract readable text recursively when summarizing. - Service `icon` can also be JSX-like SVG JSON. - Room summary image values are usually store-relative paths. Expand them with: ```text https://smg-production.s3.eu-central-1.amazonaws.com/store/{path} ``` Do not invent full image URLs from bare hash/file fields unless you have verified the URL. ## Query Encoding - Dates use `YYYY-MM-DD`. - Arrays use comma-separated query values: `service_ids=8,16`. - Booleans use `true` or `false`. - Paginated endpoints return pagination headers: `x-page`, `x-per-page`, `x-total`, `x-total-pages`, `x-prev-page`, `x-next-page`. Common enum values: - `order`: `price`, `score`, `reviews`, `ratio`, `created`, `bookings`, `discount`. - `direction`: integer sort direction. Use the site’s current behavior if exact direction labels matter. - `standard`: `luxury`, `standard`, `outrageous`. ## Recommended Workflows Find matching rooms: 1. Call `GET /services/categories` and `GET /services` if the user asks for features such as sauna type, jacuzzi, pool, outdoor wellness, massages, privacy, or included items. 2. Call `GET /rooms` with filters such as `service_ids`, price, location, date, and occupants. 3. Use pagination headers if the first page is not enough. 4. Link results with `https://privesauna.nl/search/{slug}/{id}`. Answer a room-detail question: 1. Call `GET /rooms/{room}`. 2. Add `GET /rooms/{room}/images`, `/reviews`, `/options`, `/arrangements`, `/area`, or `/cancel_rules` only when needed. Answer an availability question: 1. Call `GET /rooms/{room}/plannings?start={date}&end={date}` to check date-level availability. 2. Call `GET /rooms/{room}/plannings/{date}` to inspect available start times, durations, prices, and planning IDs. 3. If the user asks about add-ons or capacity for a specific slot, pass the planning ID to `GET /rooms/{room}/arrangements?planning_id={planning_id}` and `GET /rooms/{room}/capacities?planning_id={planning_id}`. Answer a last-minute offer question: 1. Call `GET /rooms/last-minutes`. 2. Each `last_minutes` item contains a planning `id`, UTC `range`, discounted `price`, optional `original_price`, and `description`. ## Services ### `GET /services/categories` Lists service filter categories. Useful fields: - `id`: category ID. - `name`: localized category name. - `description`: optional category description. ### `GET /services` Lists room features/services that can be used as `service_ids` filters. Useful fields: - `id`: service ID. - `name`: localized service name. - `description`: optional description. - `category_ids`: matching service category IDs. - `is_parent`: whether this is a parent/grouping service. - `icon`: optional JSX-like SVG JSON. ## Rooms ### `GET /rooms` Searches rooms. Common query parameters: | Parameter | Purpose | |--------------------------------------------|---------------------------------------------------------| | `page`, `per_page` | Pagination. Defaults are page `1`, `10` items per page. | | `ids` | Comma-separated room IDs. | | `service_ids` | Include rooms that contain all listed service IDs. | | `service_ids!` | Exclude rooms that contain all listed service IDs. | | `min_price`, `max_price` | Base price filter. | | `lat`, `lng`, `radius` | Point search. Radius is in kilometers; default is `75`. | | `min_lat`, `min_lng`, `max_lat`, `max_lng` | Bounding-box search. | | `place_id` | Search around a known place ID. | | `date`, `end`, `growth`, `availability` | Availability filters. | | `last_minutes` | `true` to search rooms with last-minute offers. | | `adults`, `minors`, `kids`, `infants` | Occupant counts. | | `min_score`, `max_score` | Review score filters. | | `min_reviews`, `max_reviews` | Review count filters. | | `order`, `direction` | Sorting. | Useful response fields: - `id`, `name`, `slug`, `city`. - `price`, `hours`, `options`. - `point`: `[lng, lat]`. - `placeholder`, `images`. - `score`, `reviews`. - `standard`, `new`, `massage`. ### `GET /rooms/{room}` Returns detailed room data. Useful fields: - Base facts: `id`, `name`, `price`, `hours`, `city`, `slug`, `point`. - Text content: `excerpt`, `description`, `anonymous_info`, `important_info`. - Services: `service_ids`. - Availability/payment facts: `availability_mask`, `pay_down`, `cash_accepted`, `cash_limit`. - Capacity text: `capacity_text`, `overnight_text`. - SEO/content: `meta_title`, `meta_description`. - Media references: `virtual_tour`, `video`. - Reviews: `scores`, `reviewable`. - Age rules: `adults_age`, `minors_age`, `kids_age`, `infants_age`. Text content can be JSX-like JSON. Extract readable text before summarizing. ### `GET /rooms/{room}/related` Returns related rooms, usually from attached or nearby venues. Response shape is similar to `GET /rooms`. ### `GET /rooms/{room}/arrangements` Returns bookable arrangements or add-ons for a room. Query parameters: - `adults`, `minors`, `kids`, `infants`. - `planning_id`: use for slot-specific add-ons. - `booking_id`: only relevant for an existing booking context. Useful fields: - `id`, `name`, `price`, `count`, `description`, `category_id`. - `required`, `limit`, `occupants_flags`, `per_request`. - `attachment`: image path for the arrangement. - `options`: option groups with nested selectable values. Nested option groups include `id`, `name`, `type`, and `options`. Nested selectable options include `id`, `name`, `description`, `count`, and `price`. ### `GET /rooms/{room}/reviews` Returns paginated room reviews. Query parameters: - `page`, `per_page`. Useful fields: - Reviewer/content: `name`, `positive`, `answer`, `reaction`, `source`. - Scores: `services`, `hygiene`, `hospitality`, `value`, `overall`, `recommends`. - Metadata: `id`, `brand_name`, `reaction_brand_id`, `created_at`. ### `GET /rooms/{room}/images` Returns standard room image variants. Useful fields: `id`, `placeholder`, `default`, `thumb`, `small`, `large`, `alt`. These fields may be bare file names rather than full store-relative paths. ### `GET /rooms/{room}/rules` Returns localized house rules as JSX-like JSON. Can return `204 No Content` when no rules are available. ### `GET /rooms/{room}/options` Returns selectable room options. Useful fields: - `id`, `name`, `price`, `description`, `type`, `default`, `required`. - `children`: child options with `id`, `name`, `price`. ### `GET /rooms/{room}/capacities` Returns capacity and occupant-count price/adjustment tables. Query parameters: - `planning_id`: optional slot-specific planning ID. Useful fields: - `max`: maximum occupants. - `single_adult_allowed`. - `adults`, `minors`, `kids`, `infants`: numeric arrays by occupant count. ### `GET /rooms/{room}/area` Returns nearby places ordered by distance. Useful fields: `code`, `name`, `km`, `point`. ### `GET /rooms/{room}/cancel_rules` Returns cancellation and rebooking rules. Useful fields: - `time_before_check_in`: optional duration string such as `"14.00:00:00"`. - `cancel_percentage`. - `rebook_percentage`, `rebook_price`. - `description`. - `can_rebook`. ### `GET /rooms/last-minutes` Returns rooms with last-minute offers. Room fields are similar to `GET /rooms`. Each `last_minutes` item includes: - `id`: planning ID. - `range`: `[start, end]` UTC timestamps. - `price`. - `original_price`. - `description`. ## RoomsPlannings ### `GET /rooms/{room}/plannings` Returns date-level availability flags for a room. Query parameters: - `start`: start date, `YYYY-MM-DD`. - `end`: end date, `YYYY-MM-DD`. Response shape: ```json { "2026-06-15": 61, "2026-06-16": 61 } ``` An empty range can return `{}`. Values are numeric availability flags. Use `GET /rooms/{room}/plannings/{date}` for exact times and prices. ### `GET /rooms/{room}/plannings/{date}` Returns time-specific planning data for one date. Path parameters: - `date`: `YYYY-MM-DD`. Top-level fields: - `block`: concrete planning blocks/offers. - `free`: available start times grouped by duration and price. `block` item fields: - `ranges`: object keyed by planning ID. - Each range value has `range`, `price`, `flags`, and optional `original_price`. - `description`. - `subtypes`. `free` item fields: - `ranges`: object keyed by planning ID. Values are UTC start timestamps. - `price`. - `hours`. Example shape: ```json { "block": [ { "ranges": { "2733302500126cab": { "range": [ "2026-06-15T09:45:00Z", "2026-06-15T12:45:00Z" ], "price": 123.25, "flags": 9, "original_price": 145.0 } }, "description": "Last minute actie", "subtypes": 4 } ], "free": [ { "ranges": { "aa32307000126cab": "2026-06-15T10:30:00Z" }, "price": 124.0, "hours": "PT2H" } ] } ``` ### `GET /rooms/{room}/plannings/{planning}` Returns block-plan details around a known planning ID. Use this when a previous response already provided a planning ID and you need related block details. Response fields match the `block` item structure from `GET /rooms/{room}/plannings/{date}`. ## Answering Guidance - Prefer API data over client-rendered page text for room facts. - Convert UTC planning times to the user’s timezone before presenting them. - Include public room links using `https://privesauna.nl/search/{slug}/{id}`. - Mention when availability or prices were checked live. - If a field is absent, say the API did not provide it; do not guess. - For image URLs, use store-relative paths when available and avoid fabricating URLs from bare hashes.