Stream EstateStream Estate

API Reference

All routes of the Stream Estate v2 API

This section lists every endpoint exposed by https://api-v2.stream.estate. Pick a category in the sidebar.

Categories

  • Properties — Search, detail, comparables, lookup by listing URL
  • Alerts — Saved searches + AlertEvents
  • Event Notifications — Delivery log
  • Favorites — Favorite properties
  • Analytics — Aggregated listing statistics
  • Geo — Administrative divisions, autocomplete
  • Account — Usage, EventDestinations, signing key rotation

Each endpoint shows its request/response schema, error codes, and a live playground (signed with X-API-Key).

Search properties POST

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 |