Public API

Availability, prices and apartment data as JSON — free, no API key required.

All endpoints are read-only, require no signup and return JSON with open CORS. The entry point for AI assistants and integrations is /api/v1/apartments: a single request answers which apartments are available in a given period — including prices, size, address and a link to the detail page. Machine-readable site overview: /llms.txt.

Endpoints

Endpoint Description
GET /api/v1/apartments?from&to Combined period search: available apartments between from and to (YYYY-MM-DD), including prices, size, rooms, address and detail-page link. The recommended entry point.
GET /api/v1/apartments Without parameters: the same apartment data with the next free time windows per apartment.
GET /api/availability-search?from&to Only slugs and names of available apartments in the period (lean response).
GET /api/availability-windows Free time windows per apartment (without prices and metadata).
GET /api/availability/<icalSlug>?days=240 Day-by-day free/occupied grid for one apartment (icalSlug from the /api/v1/apartments response).
GET /api/prices Nightly, monthly and long-term prices plus cleaning fee (CHF).
GET /api/apartment-facts Apartment sizes in m².

Response: period search

GET /api/v1/apartments?from=2026-08-01&to=2026-08-15 — abbreviated example:

{
  "provider": "apartments.zuerich",
  "from": "2026-08-01",
  "to": "2026-08-15",
  "nights": 14,
  "mode": "short_term",
  "count": 5,
  "apartments": [
    {
      "slug": "badenerstrasse-4101",
      "icalSlug": "4101",
      "name": "Business Apartment 4101",
      "description": "Business-Studio im 1. Stock an der Badenerstrasse 414 …",
      "type": "studio",
      "typeName": "Studio",
      "quartier": "kreis-4",
      "quartierName": "Kreis 4, Badenerstrasse",
      "address": { "street": "Badenerstrasse 414", "zip": "8004", "city": "Zürich" },
      "coordinates": { "lat": 47.3775, "lng": 8.4892 },
      "sizeM2": 38,
      "rooms": 1,
      "maxGuests": 2,
      "floor": 1,
      "features": ["Voll ausgestattete Küche", "Smart TV", "Highspeed WLAN"],
      "prices": {
        "currency": "CHF",
        "night": 95,
        "month": 2190,
        "longTerm": 2090,
        "cleaningFee": 50
      },
      "url": {
        "de": "https://www.apartments.zuerich/de/wohnungen/badenerstrasse-4101/",
        "en": "https://www.apartments.zuerich/en/apartments/badenerstrasse-4101/"
      },
      "image": "https://www.apartments.zuerich/_astro/wohnzimmer.CVxq6Kk3.jpg"
    }
  ],
  "unavailable": [
    { "slug": "algier-15-studio", "name": "Studio AL15-1", "url": { "de": "…", "en": "…" } }
  ],
  "incomplete": [],
  "combinations": [
    {
      "switches": 1,
      "switchDate": "2026-08-08",
      "segments": [
        { "slug": "badenerstrasse-4404", "icalSlug": "4404", "name": "Business Apartment 4404",
          "from": "2026-08-01", "to": "2026-08-08", "nights": 7, "url": { "de": "…", "en": "…" } },
        { "slug": "badenerstrasse-4101", "icalSlug": "4101", "name": "Business Apartment 4101",
          "from": "2026-08-08", "to": "2026-08-15", "nights": 7, "url": { "de": "…", "en": "…" } }
      ]
    }
  ],
  "warnings": []
}
Field Type Description
from / to / nights / mode string / number Requested period; mode is short_term below 28 nights, otherwise mid_or_long_term.
count number Number of available apartments in the period.
apartments[] array Available apartments with all metadata, prices and links.
apartments[].slug string Public apartment ID, identical to the detail-page slug.
apartments[].icalSlug string Join key for the low-level endpoints (/api/prices, /api/availability/…).
apartments[].prices object | null Prices in CHF; null if the price source is temporarily unreachable (see warnings).
apartments[].url object Absolute links to the detail page (German and English).
unavailable[] array Apartments not available in the period (slug, name and link only).
incomplete[] array Apartments whose availability sources were incomplete — no reliable statement possible.
combinations[] array Bookable combinations with exactly one apartment switch (max. 3) when the period is not free in one piece – each segment is subject to the 60-day booking window, JSON format only.
warnings[] array Hints about failed secondary sources, e.g. prices_unavailable.

Response: free time windows (no parameters)

Without from/to each apartment additionally carries an availability object with its next free windows (end is exclusive; null = open until the data horizon):

"availability": {
  "offered": { "shortTerm": true, "midTerm": true, "longTerm": false },
  "windows": [{ "start": "2026-08-03", "end": "2026-09-01", "days": 29 }],
  "shortTermFreeDays": 12,
  "midTermAvailableFrom": "2026-08-03",
  "longTermFreeFrom": null
}

CSV export (?format=csv)

With ?format=csv, /api/v1/apartments returns a flat CSV table instead of JSON — one row per apartment, made for spreadsheets. Both modes (period search and time windows) support the parameter. Base columns in stable order:

slug, name, description, type, type_name, quartier, quartier_name,
street, zip, city, lat, lng, size_m2, rooms, max_guests, floor, features,
price_night, price_month, price_long_term, cleaning_fee, listing_status,
url_de, url_en
  • Period mode (with from/to): additionally the column status (available, unavailable or incomplete) — all apartments appear in a single table.
  • Windows mode (no parameters): additionally incomplete plus next_window_from and next_window_to (only the next free window; open end = empty to), short_term_free_days, mid_term_available_from and long_term_free_from.
  • Nested data is flattened: features joined with ;, prices as individual columns in CHF; warnings are omitted in the CSV.

Google Sheets (IMPORTDATA)

Paste the formula into any cell — Google Sheets loads the table directly and refreshes it periodically on its own:

=IMPORTDATA("https://www.apartments.zuerich/api/v1/apartments?from=2026-08-01&to=2026-08-15&format=csv")

Interpreting prices correctly

  • Short stay (mode short_term, below 28 nights): guide price = night × nights + cleaningFee.
  • Temporary living (28 nights and more): monthly price month, from 3 months the reduced long-term price longTerm.
  • All prices in CHF and non-binding — the quote via the booking request on the detail page is authoritative.

Freshness & caching

  • Availability comes live from the booking system; responses are cached for up to 60 seconds (browser) and 300 seconds (edge CDN).
  • Error responses are never cached.

Examples

curl

curl -s 'https://www.apartments.zuerich/api/v1/apartments?from=2026-08-01&to=2026-08-15' | jq '.apartments[].name'

JavaScript

const res = await fetch(
  "https://www.apartments.zuerich/api/v1/apartments?from=2026-08-01&to=2026-08-15"
);
const data = await res.json();
for (const apartment of data.apartments) {
  console.log(apartment.name, apartment.prices?.night, "CHF/Nacht", apartment.url.de);
}

CORS

All endpoints send Access-Control-Allow-Origin: * — the API can be queried directly from browsers, scripts and AI agents.

Versioning

Endpoints under /api/v1/ are stable: fields may be added, existing fields do not change or disappear without a new version.

Usage

The API is free to use for AI assistants, relocation services and private integrations. If you publish the data, we appreciate attribution with a link to apartments.zuerich.

Questions or higher-volume needs? info@datenpfleger.ch · llms.txt