Search properties by combining a **search mode** (how filters are expressed) with a **pagination mode** (how pages are navigated). Both choices are made in the request body — no extra endpoints or query parameters needed.
---
## Search Modes
Use the `searchMode` field as the discriminator.
### `classic` (default)
Flat key-value filters at the root level, all combined with an implicit AND.
Best for simple, well-known filter sets (the majority of use cases).
```json
{
"searchMode": "classic",
"paginationType": "page",
"page": 1,
"size": 10,
"transactionType": "SELL",
"propertyTypes": ["FLAT", "HOUSE"],
"cityIds": [1001, 1002],
"price": { "gte": 100000, "lte": 500000 },
"area": { "gte": 50 },
"rooms": { "gte": 2 },
"bedrooms": { "gte": 1 }
}
```
### `advanced`
A recursive `criteria` tree allowing arbitrarily nested AND / OR logic.
Use this when you need complex boolean queries (e.g. "flats in Paris OR houses in Lyon with price under 300k").
**Simple leaf** (equivalent to a classic request):
```json
{
"searchMode": "advanced",
"paginationType": "page",
"page": 1,
"size": 10,
"criteria": {
"transactionType": { "value": "SELL" },
"price": { "min": 100000, "max": 500000 },
"location": {
"included": [{ "cityId": 1001 }, { "cityId": 1002 }]
}
}
}
```
**Nested OR branch** (flats under 200k OR houses with 4+ rooms):
```json
{
"searchMode": "advanced",
"paginationType": "page",
"page": 1,
"size": 10,
"criteria": {
"operator": "OR",
"branches": [
{
"propertyType": { "included": ["FLAT"] },
"price": { "max": 200000 }
},
{
"propertyType": { "included": ["HOUSE"] },
"rooms": { "min": 4 }
}
]
}
}
```
---
## Pagination Modes
Use the `paginationType` field as the discriminator.
### `page` (default)
Offset-based pagination. Use `page` (1-indexed) and `size`.
`totalItems` is accurate up to 10,000, then capped. Supports both next and previous navigation.
**First page:**
```json
{ "searchMode": "classic", "paginationType": "page", "page": 1, "size": 20, "transactionType": "RENT" }
```
**Navigate using `meta.pagination.nextRequestBody` from the response (page 2):**
```json
{ "searchMode": "classic", "paginationType": "page", "page": 2, "size": 20, "transactionType": "RENT" }
```
### `cursor`
Stable cursor-based pagination. Pass the opaque `cursor` value from the previous response.
`totalItems` reflects the true count (no cap). Forward-only — no `prevRequestBody`.
**Web users** are capped at 100 visible results; Partner API users have no limit.
**First page:**
```json
{ "searchMode": "classic", "paginationType": "cursor", "size": 20, "transactionType": "SELL" }
```
**Next page — copy `meta.pagination.nextRequestBody` from the response:**
```json
{
"searchMode": "classic",
"paginationType": "cursor",
"size": 20,
"transactionType": "SELL",
"cursor": "<opaque cursor from previous response>"
}
```
---
## Response Structure
```json
{
"data": [
{
"id": "/properties/018e1f9a-…",
"type": "PropertySearch",
"attributes": {
"uuid": "018e1f9a-…",
"listings": [ { "title": "Beautiful flat", "price": 250000, … } ],
"minPrice": 250000,
"maxPrice": 250000,
"createdAt": "2025-01-01T00:00:00+00:00",
"updatedAt": "2025-06-15T12:00:00+00:00"
}
}
],
"meta": {
"totalItems": 1843,
"hasNextPage": true,
"cursor": "eyJzb3J0IjpbMTczNjk1MjYwMDAwMCwxMjM0NV19",
"pagination": {
"type": "cursor",
"size": 20,
"nextRequestBody": { "paginationType": "cursor", "size": 20, "cursor": "eyJzb3J0IjpbMTczNjk1MjYwMDAwMCwxMjM0NV19" },
"prevRequestBody": null,
"supportsPreviousPage": false,
"usage": "Send a new POST /properties request using meta.pagination.nextRequestBody."
}
},
"links": { "self": "/properties" }
}
```
> `cursor` only appears in `meta` when `paginationType` is `cursor` and `hasNextPage` is `true`.
> `links.self` identifies the endpoint — pagination is request-body driven, not URL-driven.
---
## Pagination Mode Comparison
| Feature | `page` | `cursor` |
|---|---|---|
| Parameters | `page`, `size` | `size`, `cursor` |
| `totalItems` | Capped at 10,000 | True count |
| Max depth | 10,000 results | Unlimited |
| SAAS_USER cap | — | 100 results |
| Prev-page support | ✅ | ❌ |
| Default | ✅ (when `paginationType` omitted) | — |
---
## Role Restrictions
| Role | Classic | Advanced | Page | Cursor |
|---|---|---|---|---|
| `ROLE_API_CLIENT` | ✅ Full access | ✅ Full access | ✅ Unlimited | ✅ Unlimited |
| `ROLE_SAAS_USER` | ✅ Full access | ✅ Full access | ✅ Unlimited | ⚠️ Max 100 results |