{
  "openapi": "3.1.0",
  "info": {
    "title": "Realitní Pes API",
    "version": "1.0.0",
    "description": "Search Czech property listings, deduplicated across portals.\n\n## Authentication\n\nEvery request needs a token from your account page, sent as `Authorization: Bearer <token>`.\nA client that cannot set that header — Claude's custom connectors reserve it for their own sign-in —\nmay send the token on its own as `X-Api-Key: <token>` instead.\n\nAs a last resort, for hosts that offer only a URL and no headers at all, the token may be passed as\n`?token=<token>`. Avoid it where you have any alternative: a query string is not a secret. It is recorded\nin server access logs and by any proxy in front of the API, so treat a token sent this way as one to rotate.\n\nWhen more than one arrives, `X-Api-Key` wins, then `?token=`, then `Authorization` — the header last,\nbecause it may hold your client's own sign-in token rather than ours.\nRevoking a token, or changing your plan, takes effect within 60 seconds.\n\n## Plans\n\n| Plan | Requests / month | History |\n| --- | --- | --- |\n| Čmuchal (`free`) | 10 | live only |\n| Hlídač (`basicV2`) | 100 | live only |\n| Stopař (`proV2`) | 500 | 3 months |\n| Smečka (`investor`) | 1000 | 6 months |\n| Na míru (`customV2`) | 1000 | 6 months |\n\nThe quota counts every authenticated request, is shared by all of your tokens, and resets\nat midnight UTC on the first of each month. `GET /v1/me` reports what you have left, and every\nresponse carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`.\n\n## Pagination\n\nResults are cursor paged. Pass the `pagination.nextCursor` from a response back as `cursor`\nto get the next page, and stop when `pagination.hasMore` is false. Cursors are opaque —\nround trip them unchanged.\n\n## Errors\n\nEvery error is JSON: `{ \"error\": { \"code\", \"message\", \"details\"? }, \"requestId\" }`. `code` is one of\n`unauthorized`, `forbidden`, `plan-limit-exceeded`, `not-found`, `invalid-request`, `payload-too-large`, `quota-exceeded`, `query-timeout`, `internal-error`. `message` always says what went wrong and\nwhat to do about it; on a 400, `details` lists every offending query parameter with what it accepts.\nUnknown parameters are rejected rather than ignored. The API has exactly these endpoints:\n`GET /v1/offers`, `GET /v1/offers/{offerId}`, `GET /v1/me`; the machine-readable spec is `GET /openapi.json`."
  },
  "servers": [
    {
      "url": "https://api.realitni-pes.cz",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    },
    {
      "queryTokenAuth": []
    }
  ],
  "paths": {
    "/v1/offers": {
      "get": {
        "summary": "Search listings",
        "description": "Returns deduplicated listings matching the given filters, newest change first. Live listings only unless `includeInactive` is set. Only the parameters listed here are accepted: an unknown or misspelled parameter is rejected with a 400 that names it, so a typo can never come back as an unfiltered result.",
        "parameters": [
          {
            "in": "query",
            "name": "offerType",
            "description": "Sale, rent, exchange or auction.",
            "schema": {
              "type": "string",
              "enum": [
                "sale",
                "rent",
                "exchange",
                "auction"
              ]
            }
          },
          {
            "in": "query",
            "name": "type",
            "description": "Broad property category.",
            "schema": {
              "type": "string",
              "enum": [
                "apartment",
                "house",
                "commercial",
                "other",
                "land"
              ]
            }
          },
          {
            "in": "query",
            "name": "subtype",
            "description": "Finer category within `type`.",
            "schema": {
              "type": "string",
              "enum": [
                "family",
                "villa",
                "cottage",
                "holiday",
                "planned",
                "farm",
                "historical",
                "office",
                "warehouse",
                "production",
                "shopping_space",
                "accommodation",
                "restaurant",
                "agricultural",
                "building",
                "garage_full",
                "garage_space",
                "mobile_home",
                "wine_cellar",
                "attic",
                "housing",
                "commercial",
                "meadow",
                "forest",
                "fishpond",
                "orchard",
                "garden",
                "other"
              ]
            }
          },
          {
            "in": "query",
            "name": "arrangement",
            "description": "Room layout, e.g. `3+kk`.",
            "schema": {
              "type": "string",
              "enum": [
                "1+0",
                "1+1",
                "1+kk",
                "2+0",
                "2+1",
                "2+kk",
                "3+0",
                "3+1",
                "3+kk",
                "4+0",
                "4+1",
                "4+kk",
                "5+0",
                "5+1",
                "5+kk",
                "6+0",
                "6+1",
                "6+kk",
                "7+0",
                "7+1",
                "7+kk",
                "6++",
                "other"
              ]
            }
          },
          {
            "in": "query",
            "name": "equipment",
            "description": "How furnished the property is.",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "none",
                "partial"
              ]
            }
          },
          {
            "in": "query",
            "name": "ownership",
            "description": "Ownership form.",
            "schema": {
              "type": "string",
              "enum": [
                "private",
                "communal",
                "local",
                "state",
                "other"
              ]
            }
          },
          {
            "in": "query",
            "name": "propertyState",
            "description": "Condition of the property.",
            "schema": {
              "type": "string",
              "enum": [
                "very_good",
                "good",
                "bad",
                "in_construction",
                "in_planning",
                "newly_constructed",
                "development_project",
                "before_renovation",
                "after_renovation",
                "for_demolition"
              ]
            }
          },
          {
            "in": "query",
            "name": "buildingType",
            "description": "Construction type.",
            "schema": {
              "type": "string",
              "enum": [
                "brick",
                "panel",
                "wood",
                "eco",
                "skeleton",
                "mix",
                "assemble",
                "stone"
              ]
            }
          },
          {
            "in": "query",
            "name": "district",
            "description": "Exact district name, e.g. `Praha 5`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "neighborhood",
            "description": "Exact neighbourhood name, e.g. `Smíchov`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "priceMin",
            "description": "Minimum total price in CZK, inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "priceMax",
            "description": "Maximum total price in CZK, inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "livingAreaMin",
            "description": "Minimum living area in m², inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "livingAreaMax",
            "description": "Maximum living area in m², inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "landAreaMin",
            "description": "Minimum land area in m², inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "landAreaMax",
            "description": "Maximum land area in m², inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "floorMin",
            "description": "Minimum floor, inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "floorMax",
            "description": "Maximum floor, inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "floorCountMin",
            "description": "Minimum number of floors in the building, inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "floorCountMax",
            "description": "Maximum number of floors in the building, inclusive.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "lat",
            "description": "Latitude of the search centre. Must be sent with `lng`.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "lng",
            "description": "Longitude of the search centre. Must be sent with `lat`.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "address",
            "description": "Free-text address to search around, geocoded for you. Use instead of `lat`/`lng`, not alongside.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "radiusMeters",
            "description": "Search radius around the centre point. Defaults to 2000 m.",
            "schema": {
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "includeInactive",
            "description": "Include listings that are no longer live. Requires a plan with history; how far back you can reach depends on the plan.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "in": "query",
            "name": "limit",
            "description": "Results per page. Max 50.",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 50,
              "minimum": 1
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `pagination.nextCursor` from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of listings.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OfferSummary"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "limit": {
                          "type": "number"
                        },
                        "count": {
                          "type": "number"
                        },
                        "hasMore": {
                          "type": "boolean"
                        },
                        "nextCursor": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "limit",
                        "count",
                        "hasMore",
                        "nextCursor"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "A query parameter was invalid or unknown; `details` names each offending parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The request needs a higher plan — for example historic data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Monthly request quota exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "The search ran longer than 10 seconds and was stopped; the message says how to narrow it. Not counted against the quota.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/offers/{offerId}": {
      "get": {
        "summary": "Get one listing",
        "description": "Full detail for a single listing, including every portal advertising it and how its price has moved.",
        "parameters": [
          {
            "in": "path",
            "name": "offerId",
            "required": true,
            "description": "The `id` from a search result.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The listing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OfferDetail"
                }
              }
            }
          },
          "400": {
            "description": "The endpoint takes no query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such listing, or it expired outside your plan's history window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Monthly request quota exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "summary": "Token, plan and quota",
        "description": "What this token is, which plan it draws on, and how much of this month's quota is left.",
        "responses": {
          "200": {
            "description": "Token and quota status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "400": {
            "description": "The endpoint takes no query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Service health",
        "description": "Unauthenticated liveness probe. Does not count against your quota.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    }
                  },
                  "required": [
                    "status"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "A backing database is unreachable."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "OfferSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable id of the deduplicated listing; use it with `GET /v1/offers/{offerId}`."
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
            "description": "When the property was first seen on any portal."
          },
          "lastChangedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
            "description": "When any portal listing of it last changed; results are sorted by this, newest first."
          },
          "isLive": {
            "type": "boolean",
            "description": "Whether at least one portal still advertises it. Only `includeInactive` searches and detail lookups return false."
          },
          "location": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "lat": {
                    "type": "number"
                  },
                  "lng": {
                    "type": "number"
                  }
                },
                "required": [
                  "lat",
                  "lng"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Geocoded position, or null when no portal gave one."
          },
          "title": {
            "type": "string",
            "description": "Listing title as written by the portal, in Czech."
          },
          "description": {
            "type": "string",
            "description": "Full listing text as written by the portal, in Czech."
          },
          "city": {
            "type": "string",
            "description": "Municipality, e.g. `Praha`, `Brno`."
          },
          "street": {
            "type": "string",
            "description": "Street name without the house number."
          },
          "region": {
            "type": "string",
            "description": "Region (kraj), e.g. `Moravskoslezský`."
          },
          "neighborhood": {
            "type": "string",
            "description": "City part or quarter, e.g. `Praha 3`, `Vinohrady`."
          },
          "district": {
            "type": "string",
            "description": "District (okres), e.g. `Hlavní město Praha`, `Brno-město`."
          },
          "postalCode": {
            "type": "string",
            "description": "Czech postal code, usually with the space, e.g. `708 00`."
          },
          "address": {
            "type": "string",
            "description": "Address line as published, e.g. `Bořivojova, Praha 3`. Portals differ in how precise it is."
          },
          "unitNumber": {
            "type": "string",
            "description": "Apartment or unit number, when the portal publishes it (rare)."
          },
          "type": {
            "type": "string",
            "enum": [
              "apartment",
              "house",
              "commercial",
              "other",
              "land"
            ],
            "description": "Property type."
          },
          "subtype": {
            "type": "string",
            "enum": [
              "family",
              "villa",
              "cottage",
              "holiday",
              "planned",
              "farm",
              "historical",
              "office",
              "warehouse",
              "production",
              "shopping_space",
              "accommodation",
              "restaurant",
              "agricultural",
              "building",
              "garage_full",
              "garage_space",
              "mobile_home",
              "wine_cellar",
              "attic",
              "housing",
              "commercial",
              "meadow",
              "forest",
              "fishpond",
              "orchard",
              "garden",
              "other"
            ],
            "description": "Finer property type, e.g. `family` house or `office` space."
          },
          "offerType": {
            "type": "string",
            "enum": [
              "sale",
              "rent",
              "exchange",
              "auction"
            ],
            "description": "Sale, rent, exchange or auction."
          },
          "arrangement": {
            "type": "string",
            "enum": [
              "1+0",
              "1+1",
              "1+kk",
              "2+0",
              "2+1",
              "2+kk",
              "3+0",
              "3+1",
              "3+kk",
              "4+0",
              "4+1",
              "4+kk",
              "5+0",
              "5+1",
              "5+kk",
              "6+0",
              "6+1",
              "6+kk",
              "7+0",
              "7+1",
              "7+kk",
              "6++",
              "other"
            ],
            "description": "Czech room layout: `2+kk` is two rooms with a kitchenette, `3+1` three rooms plus a separate kitchen."
          },
          "propertyState": {
            "type": "string",
            "enum": [
              "very_good",
              "good",
              "bad",
              "in_construction",
              "in_planning",
              "newly_constructed",
              "development_project",
              "before_renovation",
              "after_renovation",
              "for_demolition"
            ],
            "description": "Condition of the property."
          },
          "ownership": {
            "type": "string",
            "enum": [
              "private",
              "communal",
              "local",
              "state",
              "other"
            ],
            "description": "Ownership form: `private` (osobní), `communal` (družstevní), `local` (obecní), `state` or `other`."
          },
          "buildingType": {
            "type": "string",
            "enum": [
              "brick",
              "panel",
              "wood",
              "eco",
              "skeleton",
              "mix",
              "assemble",
              "stone"
            ],
            "description": "Construction type of the building."
          },
          "priceTotal": {
            "type": "number",
            "description": "Asking price in CZK: the total for a sale, the monthly amount for a rent."
          },
          "livingArea": {
            "type": "number",
            "description": "Living (usable) floor area in square metres."
          },
          "landArea": {
            "type": "number",
            "description": "Plot area in square metres."
          },
          "floor": {
            "type": "number",
            "description": "Floor the unit is on; 0 is the ground floor, negative is below ground."
          },
          "floorCount": {
            "type": "number",
            "description": "Number of floors in the building."
          },
          "equipment": {
            "type": "string",
            "enum": [
              "full",
              "none",
              "partial"
            ],
            "description": "How furnished the property is."
          },
          "garden": {
            "type": "boolean",
            "description": "Whether the property has a garden. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "gardenArea": {
            "type": "number",
            "description": "Garden area in square metres."
          },
          "storage": {
            "type": "boolean",
            "description": "Whether the property has a storage room or cellar. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "storageArea": {
            "type": "number",
            "description": "Storage area in square metres."
          },
          "balcony": {
            "type": "boolean",
            "description": "Whether the property has a balcony. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "balconyArea": {
            "type": "number",
            "description": "Balcony area in square metres."
          },
          "loggia": {
            "type": "boolean",
            "description": "Whether the property has a loggia. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "loggiaArea": {
            "type": "number",
            "description": "Loggia area in square metres."
          },
          "terrace": {
            "type": "boolean",
            "description": "Whether the property has a terrace. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "terraceArea": {
            "type": "number",
            "description": "Terrace area in square metres."
          },
          "garage": {
            "type": "boolean",
            "description": "Whether the property has a garage. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "garageArea": {
            "type": "number",
            "description": "Garage area in square metres."
          },
          "energyClass": {
            "type": "string",
            "description": "Energy performance class as published: usually the letter `A` to `G`, sometimes followed by the Czech label, e.g. `B - velmi úsporná`."
          },
          "heatingSource": {
            "type": "string",
            "description": "Heating fuel or source. Known values: `gas`, `electric`, `solid`, `solid-fuel`, `combined`, `heat-pump`, `other`."
          },
          "heatingType": {
            "type": "string",
            "description": "Heating system. Known values: `communal` (central) and `local`."
          },
          "sewerage": {
            "type": "string",
            "description": "Sewage disposal. Known values: `communal` (public sewer) and `septic-tank`."
          },
          "elevator": {
            "type": "boolean",
            "description": "Whether the property has an elevator. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "parking": {
            "type": "boolean",
            "description": "Whether the property has parking. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "barrierFree": {
            "type": "boolean",
            "description": "Whether the property has barrier-free (wheelchair) access. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "swimmingPool": {
            "type": "boolean",
            "description": "Whether the property has a swimming pool. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "housePosition": {
            "type": "string",
            "description": "How a house sits relative to its neighbours. Known values: `free_standing`, `terraced`, `semi_detached`."
          }
        },
        "required": [
          "id",
          "firstSeenAt",
          "lastChangedAt",
          "isLive",
          "location"
        ],
        "additionalProperties": false,
        "description": "A deduplicated listing: one property, merged from every portal advertising it. Every attribute after `location` is optional and omitted when no portal published it."
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthorized",
                  "forbidden",
                  "plan-limit-exceeded",
                  "not-found",
                  "invalid-request",
                  "payload-too-large",
                  "quota-exceeded",
                  "query-timeout",
                  "internal-error"
                ],
                "description": "Machine-readable category; branch on this, not on the message."
              },
              "message": {
                "type": "string",
                "description": "What went wrong and how to fix it, in plain English. Safe to show to a user or feed to an agent."
              },
              "details": {
                "description": "Only on 400: one entry per offending query parameter.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string",
                      "description": "The offending query parameter."
                    },
                    "message": {
                      "type": "string",
                      "description": "What that parameter accepts, or that it is unknown and which names are."
                    }
                  },
                  "required": [
                    "path",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          },
          "requestId": {
            "description": "Also sent as the X-Request-Id header; quote it when reporting a problem.",
            "type": "string"
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "OfferDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable id of the deduplicated listing; use it with `GET /v1/offers/{offerId}`."
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
            "description": "When the property was first seen on any portal."
          },
          "lastChangedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
            "description": "When any portal listing of it last changed; results are sorted by this, newest first."
          },
          "isLive": {
            "type": "boolean",
            "description": "Whether at least one portal still advertises it. Only `includeInactive` searches and detail lookups return false."
          },
          "location": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "lat": {
                    "type": "number"
                  },
                  "lng": {
                    "type": "number"
                  }
                },
                "required": [
                  "lat",
                  "lng"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Geocoded position, or null when no portal gave one."
          },
          "title": {
            "type": "string",
            "description": "Listing title as written by the portal, in Czech."
          },
          "description": {
            "type": "string",
            "description": "Full listing text as written by the portal, in Czech."
          },
          "city": {
            "type": "string",
            "description": "Municipality, e.g. `Praha`, `Brno`."
          },
          "street": {
            "type": "string",
            "description": "Street name without the house number."
          },
          "region": {
            "type": "string",
            "description": "Region (kraj), e.g. `Moravskoslezský`."
          },
          "neighborhood": {
            "type": "string",
            "description": "City part or quarter, e.g. `Praha 3`, `Vinohrady`."
          },
          "district": {
            "type": "string",
            "description": "District (okres), e.g. `Hlavní město Praha`, `Brno-město`."
          },
          "postalCode": {
            "type": "string",
            "description": "Czech postal code, usually with the space, e.g. `708 00`."
          },
          "address": {
            "type": "string",
            "description": "Address line as published, e.g. `Bořivojova, Praha 3`. Portals differ in how precise it is."
          },
          "unitNumber": {
            "type": "string",
            "description": "Apartment or unit number, when the portal publishes it (rare)."
          },
          "type": {
            "type": "string",
            "enum": [
              "apartment",
              "house",
              "commercial",
              "other",
              "land"
            ],
            "description": "Property type."
          },
          "subtype": {
            "type": "string",
            "enum": [
              "family",
              "villa",
              "cottage",
              "holiday",
              "planned",
              "farm",
              "historical",
              "office",
              "warehouse",
              "production",
              "shopping_space",
              "accommodation",
              "restaurant",
              "agricultural",
              "building",
              "garage_full",
              "garage_space",
              "mobile_home",
              "wine_cellar",
              "attic",
              "housing",
              "commercial",
              "meadow",
              "forest",
              "fishpond",
              "orchard",
              "garden",
              "other"
            ],
            "description": "Finer property type, e.g. `family` house or `office` space."
          },
          "offerType": {
            "type": "string",
            "enum": [
              "sale",
              "rent",
              "exchange",
              "auction"
            ],
            "description": "Sale, rent, exchange or auction."
          },
          "arrangement": {
            "type": "string",
            "enum": [
              "1+0",
              "1+1",
              "1+kk",
              "2+0",
              "2+1",
              "2+kk",
              "3+0",
              "3+1",
              "3+kk",
              "4+0",
              "4+1",
              "4+kk",
              "5+0",
              "5+1",
              "5+kk",
              "6+0",
              "6+1",
              "6+kk",
              "7+0",
              "7+1",
              "7+kk",
              "6++",
              "other"
            ],
            "description": "Czech room layout: `2+kk` is two rooms with a kitchenette, `3+1` three rooms plus a separate kitchen."
          },
          "propertyState": {
            "type": "string",
            "enum": [
              "very_good",
              "good",
              "bad",
              "in_construction",
              "in_planning",
              "newly_constructed",
              "development_project",
              "before_renovation",
              "after_renovation",
              "for_demolition"
            ],
            "description": "Condition of the property."
          },
          "ownership": {
            "type": "string",
            "enum": [
              "private",
              "communal",
              "local",
              "state",
              "other"
            ],
            "description": "Ownership form: `private` (osobní), `communal` (družstevní), `local` (obecní), `state` or `other`."
          },
          "buildingType": {
            "type": "string",
            "enum": [
              "brick",
              "panel",
              "wood",
              "eco",
              "skeleton",
              "mix",
              "assemble",
              "stone"
            ],
            "description": "Construction type of the building."
          },
          "priceTotal": {
            "type": "number",
            "description": "Asking price in CZK: the total for a sale, the monthly amount for a rent."
          },
          "livingArea": {
            "type": "number",
            "description": "Living (usable) floor area in square metres."
          },
          "landArea": {
            "type": "number",
            "description": "Plot area in square metres."
          },
          "floor": {
            "type": "number",
            "description": "Floor the unit is on; 0 is the ground floor, negative is below ground."
          },
          "floorCount": {
            "type": "number",
            "description": "Number of floors in the building."
          },
          "equipment": {
            "type": "string",
            "enum": [
              "full",
              "none",
              "partial"
            ],
            "description": "How furnished the property is."
          },
          "garden": {
            "type": "boolean",
            "description": "Whether the property has a garden. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "gardenArea": {
            "type": "number",
            "description": "Garden area in square metres."
          },
          "storage": {
            "type": "boolean",
            "description": "Whether the property has a storage room or cellar. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "storageArea": {
            "type": "number",
            "description": "Storage area in square metres."
          },
          "balcony": {
            "type": "boolean",
            "description": "Whether the property has a balcony. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "balconyArea": {
            "type": "number",
            "description": "Balcony area in square metres."
          },
          "loggia": {
            "type": "boolean",
            "description": "Whether the property has a loggia. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "loggiaArea": {
            "type": "number",
            "description": "Loggia area in square metres."
          },
          "terrace": {
            "type": "boolean",
            "description": "Whether the property has a terrace. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "terraceArea": {
            "type": "number",
            "description": "Terrace area in square metres."
          },
          "garage": {
            "type": "boolean",
            "description": "Whether the property has a garage. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "garageArea": {
            "type": "number",
            "description": "Garage area in square metres."
          },
          "energyClass": {
            "type": "string",
            "description": "Energy performance class as published: usually the letter `A` to `G`, sometimes followed by the Czech label, e.g. `B - velmi úsporná`."
          },
          "heatingSource": {
            "type": "string",
            "description": "Heating fuel or source. Known values: `gas`, `electric`, `solid`, `solid-fuel`, `combined`, `heat-pump`, `other`."
          },
          "heatingType": {
            "type": "string",
            "description": "Heating system. Known values: `communal` (central) and `local`."
          },
          "sewerage": {
            "type": "string",
            "description": "Sewage disposal. Known values: `communal` (public sewer) and `septic-tank`."
          },
          "elevator": {
            "type": "boolean",
            "description": "Whether the property has an elevator. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "parking": {
            "type": "boolean",
            "description": "Whether the property has parking. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "barrierFree": {
            "type": "boolean",
            "description": "Whether the property has barrier-free (wheelchair) access. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "swimmingPool": {
            "type": "boolean",
            "description": "Whether the property has a swimming pool. Always true/false; portal values such as \"Ano\" are normalised."
          },
          "housePosition": {
            "type": "string",
            "description": "How a house sits relative to its neighbours. Known values: `free_standing`, `terraced`, `semi_detached`."
          },
          "portalLinks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "offerId": {
                  "type": "string"
                },
                "siteId": {
                  "type": "string"
                },
                "url": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "isLive": {
                  "type": "boolean"
                },
                "firstSeenAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                }
              },
              "required": [
                "offerId",
                "siteId",
                "url",
                "isLive",
                "firstSeenAt"
              ],
              "additionalProperties": false
            },
            "description": "Every portal listing behind this property."
          },
          "priceHistory": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "offerId": {
                  "type": "string"
                },
                "siteId": {
                  "type": "string"
                },
                "points": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "at": {
                        "type": "string",
                        "format": "date-time",
                        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                      },
                      "priceTotal": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "at",
                      "priceTotal"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "offerId",
                "siteId",
                "points"
              ],
              "additionalProperties": false
            },
            "description": "Price changes over time, one series per portal, oldest point first. Portals often disagree on price, so the series are kept separate rather than merged."
          }
        },
        "required": [
          "id",
          "firstSeenAt",
          "lastChangedAt",
          "isLive",
          "location",
          "portalLinks",
          "priceHistory"
        ],
        "additionalProperties": false
      },
      "Me": {
        "type": "object",
        "properties": {
          "token": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "prefix": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "prefix"
            ],
            "additionalProperties": false
          },
          "plan": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "requestsPerMonth": {
                "type": "number"
              },
              "historyMonths": {
                "type": "number"
              }
            },
            "required": [
              "id",
              "name",
              "requestsPerMonth",
              "historyMonths"
            ],
            "additionalProperties": false
          },
          "usage": {
            "type": "object",
            "properties": {
              "month": {
                "type": "string"
              },
              "requestsUsed": {
                "type": "number"
              },
              "requestsRemaining": {
                "type": "number"
              },
              "resetsAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
              }
            },
            "required": [
              "month",
              "requestsUsed",
              "requestsRemaining",
              "resetsAt"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "token",
          "plan",
          "usage"
        ],
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API token from your Realitní Pes account."
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "The same API token, for clients that cannot set the Authorization header."
      },
      "queryTokenAuth": {
        "type": "apiKey",
        "in": "query",
        "name": "token",
        "description": "The same API token in the URL. Last resort for hosts that cannot send headers at all: a query string reaches access logs and proxies, so prefer either header wherever you can."
      }
    }
  }
}