Available Units
Request
GET /api/v2/clients/projects/{project_id}/units
Description
Note that access to unit-level endpoints is available only with an Enterprise subscription.
This endpoint returns the complete list of units belonging to a specific project, including all available configurations, inventory details, and pricing information. It is designed for client applications that need precise, real-time unit-level data to support search, comparison, and purchasing workflows.
Each unit record provides:
- Pricing data — the full unit price (
price) and price per area unit (price_per_area), automatically adjusted according to thepreferred_currencyandpreferred_area_unitparameters when used. - Size and configuration — including total size (
size), number of bedrooms (bedrooms), unit type (unit_type), floor number (floor), and layout type (layout_type). - Inventory visibility — the current availability status (
status), allowing clients to differentiate available, reserved, and sold units. - Layout information — when available, each unit includes a
layoutobject with layout ID, name, and a collection of layout images with full metadata (URL, MIME type, size, width, height). - Building context —
building_idlinks each unit to its building within the project, enabling UI components such as building selectors and tower breakdowns. - Update tracking — the
modifiedtimestamp reflects the most recent update to that specific unit, which is useful for synchronization and cache invalidation.
This endpoint is typically used to power:
- Unit availability pages for each project
- Price, floor, and bedroom filters within a project
- Unit comparison tools
- Dynamic inventory tables and grids
- Unit detail pages that require layout previews and pricing granularity
The response uses standard pagination (limit, offset) and maintains consistent ordering unless explicitly changed via the ordering parameter. All filtering is evaluated strictly within the context of the selected project ({id}).
Query Parameters
The Units endpoint provides a set of optional query parameters that allow clients to refine, sort, and format the returned unit list within a specific project. These parameters enable filtering by price, size, number of bedrooms, building, floor, and output preferences such as currency and area units.
All filters apply only to units belonging to the project identified by {id}.
If a parameter is omitted, the API returns the full unit inventory for the project.
Filtering and formatting behaviors include:
- Numeric filtering — minimum/maximum values for price and size allow UI components to build sliders and range pickers.
- Attribute-based filtering — such as filtering by number of bedrooms, floor, or building.
- Unit formatting options — currency and area-unit conversion is performed automatically when
preferred_currencyorpreferred_area_unitis provided. - Pagination —
limitandoffsetcontrol how many units are returned in one response, allowing efficient loading of large inventories. - Sorting — the
orderingparameter enables ordering by price, size, bedrooms, or other supported fields.
Each parameter is described individually below using the official Reelly documentation template.
If no filters are applied, the endpoint returns all units for the project, sorted by the API’s default ordering.
bedrooms
Description
Filters units by the number of bedrooms.
The parameter accepts a single numeric value (e.g., 2) or multiple comma-separated values (e.g., 0,1.5,3).
Filtering is applied only within the selected project, and units are returned only if their bedrooms value exactly matches one of the values in the query.
Bedroom values follow the Reelly data model:
- 0 — studio unit (no bedrooms)
- Integer values (1, 2, 3, … up to 11 or more) — number of full bedrooms
- Fractional values (e.g., 0.5, 1.5) — the unit has an additional technical room (storage, maid’s room, study) counted as a partial bedroom
The API does not normalize or interpret the values; matching is direct and numeric.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| bedrooms | string (CSV list) | No | None | Accepts comma-separated numeric values; supports 0, integers, and decimals. |
Request and Response Examples
Filter studios only:
GET /api/v2/clients/projects/1127/units?bedrooms=0
Filter 1- and 2-bedroom units:
GET /api/v2/clients/projects/1127/units?bedrooms=1,2
Filter units with an extra technical room:
GET /api/v2/clients/projects/1127/units?bedrooms=1.5
Filter multiple precise values including fractional:
GET /api/v2/clients/projects/1127/units?bedrooms=0,1.5,3
Response fragment:
{ "count": 6, "results": [ { "id": 455457, "name": "1101", "bedrooms": 2.0, "price": 18365583, "size": 4940.0, "status": "available" } ]}
Notes
- Supports three value types: studio (0), integer bedrooms, fractional bedrooms.
- Fractional values reflect units with technical rooms, not half-bedrooms.
- Matching is numeric and exact.
- If no unit contains the specified bedroom count, the API returns an empty result set.
building
Description
Filters units by building ID within the selected project.
Many projects contain multiple buildings (towers or blocks), and this parameter allows clients to request units belonging to a specific building.
If the provided building ID does not exist in the project, the API returns an empty result set.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| building | integer | No | None | Must match a valid building_id from units in the project. |
Request and Response Examples
Filter units belonging to building 1281:
GET /api/v2/clients/projects/1127/units?building=1281
Example response fragment:
{ "count": 8, "results": [ { "id": 455453, "name": "503", "building_id": 1281, "floor": 5, "price": 12576212 } ]}
Notes
- Only units with the specified
building_idare included. - Useful for interfaces where users select a tower/block before viewing units.
floor
Description
Filters units by their floor level.
The parameter accepts a single numeric value or a comma-separated list of values.
The API performs exact numeric matching against the stored floor value of each unit.
The Reelly platform supports both standard and special floor designations, encoded numerically:
| Encoded value | Meaning |
|---|---|
| -0.5 | Basement level |
| 0 | Ground Floor |
| 0.5 | Mezzanine level |
| 1, 2, 3, … | Standard residential floors |
These values appear directly in unit records and are used consistently across the Units API. The API does not translate or map floor values; filtering must use the numeric representation.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| floor | string (CSV numeric list) | No | None | Accepts negative, zero, fractional, and integer values. Matching is exact and numeric. |
Request and Response Examples
Filter units on the Ground Floor:
GET /api/v2/clients/projects/1127/units?floor=0
Filter basement and mezzanine levels:
GET /api/v2/clients/projects/1127/units?floor=-0.5,0.5
Filter specific residential floors:
GET /api/v2/clients/projects/1127/units?floor=5,12,17
Response (fragment):
{ "count": 3, "results": [ { "id": 455457, "name": "1101", "floor": 11.0, "price": 18365583, "size": 4940.0 } ]}
Notes
- Supports all numeric formats returned by the API: negative, zero, fractional, and integer.
- Use the numeric encoding when filtering (e.g.,
0.5rather than “Mezzanine”). - If multiple values are provided, the filter behaves as an OR condition.
- Values must match exactly what is stored in the unit data.
language
Description
Specifies the language used for localized text fields in the units list response.
When this parameter is provided, the API returns all supported translatable text fields in the requested language. Fields without available translations fall back to English (en-us).
Translatable text fields
For this endpoint, the following fields are translated:
layout.namelayout_type
The following fields are not translated and always return in English or as system values:
name— unit code/identifierunit_type— always returns snake_case value (e.g.,apartments,villas)status— always returns snake_case value (e.g.,available,reserved,sold)
Supported Languages
Available language codes:
GET /api/v2/clients/projects/languages
Confirmed languages with translated content: en-us (default), ar, de, fr, he, hi, it, pl, ru, tr, zh.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| language | string | No | en-us | Defines the language used for translatable text fields. Supported values should be obtained from /api/v2/clients/projects/languages. |
Request and Response Examples
Request with French language:
GET /api/v2/clients/projects/2927/units?language=fr
Response (excerpt):
json
{ "id": 663014, "name": "DDA/2/216", "status": "available", "unit_type": "apartments", "layout": { "id": 88915, "name": "1 chambre Type A" }, "layout_type": "1 chambre Type A"}
Request with English (default):
GET /api/v2/clients/projects/2927/units?language=en-us
Response (excerpt):
json
{ "id": 663014, "name": "DDA/2/216", "status": "available", "unit_type": "apartments", "layout": { "id": 88915, "name": "1 BR Type A" }, "layout_type": "1 BR Type A"}
Notes
- The
languageparameter affects layout names and layout type labels only. - Unit names, statuses, and unit types remain as system values regardless of the language parameter.
- If a translation is not available for a field, English is returned as a fallback.
- The parameter does not affect filtering, sorting, or pagination — only the representation of text values.
layout
Description
Filters units by layout ID.
The parameter performs an exact match against the layout.id field of each unit. When a numeric layout ID is provided, only units whose layout object has that id are returned.
The parameter also supports a special null value to select units without any layout assigned ("layout": null in the response).
Only a single value is allowed:
- a numeric layout ID (e.g.
layout=7754), or - the literal keyword
null(e.g.layout=null).
Comma-separated lists are not supported and result in a validation error.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| layout | string | No | None | Accepts a single numeric layout ID (e.g. 7754) or the literal null. Lists are not supported. |
Request and Response Examples
Filter units by a specific layout ID:
GET /api/v2/clients/projects/1147/units?layout=7754
Example response fragment:
{ "count": 3, "results": [ { "id": 365944, "name": "106", "layout": { "id": 7754, "name": "1 BR Type B" }, "bedrooms": 1.0, "price": 1268491 } ]}
Filter units without a layout:
GET /api/v2/clients/projects/1147/units?layout=null
Example response fragment:
{ "count": 1, "results": [ { "id": 108082, "name": "2605", "layout": null, "bedrooms": 2.0, "price": 2249857 } ]}
Request with a non-existing layout ID:
GET /api/v2/clients/projects/1147/units?layout=9999999
Example response:
{ "count": 0, "next": null, "previous": null, "results": []}
Request with multiple values (not supported):
GET /api/v2/clients/projects/1147/units?layout=7750,7754
Example response:
{ "layout": [ "Enter a number." ]}
Notes
layoutfilters strictly bylayout.idin the unit’slayoutobject.- The special value
layout=nullselects only units wherelayoutisnull. - Passing more than one value (e.g.
layout=7750,7754) is not supported and returns a validation error. - If the layout ID is valid but no units in the project use it, the response is empty (
count: 0).
max_price
Description
Defines the upper bound for the unit price in the selected project.
The value is interpreted in the currency specified by preferred_currency.
If preferred_currency is omitted, filtering is performed in AED.
Filtering logic:
- For each unit, convert its stored price to the effective currency (AED or USD).
- Include the unit only if price ≤ max_price.
This parameter is typically used together with min_price to create a price range.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| max_price | number | No | None | Upper limit for unit price, in the effective currency. |
Request Examples
Units up to 2,000,000 AED:
GET /api/v2/clients/projects/1127/units?max_price=2000000
Units up to 600,000 USD:
GET /api/v2/clients/projects/1127/units?preferred_currency=USD&max_price=600000
Example response fragment:
{ "count": 3, "results": [ { "id": 365944, "name": "106", "price": 1268491, "price_per_area": 1497, "size": 847.0 } ]}
Notes
- Filtering always respects the currency selected via
preferred_currency. - If the value is too restrictive, the response may legitimately return
count: 0. - Works correctly with any combination of unit types and bedroom counts.
max_size
Description
Defines the upper limit for the unit size.
The value is interpreted in the area unit specified by preferred_area_unit.
If preferred_area_unit is not specified, the unit is assumed to be sqft.
Filtering logic:
- Convert each unit’s stored size to the effective unit (sqft or m2).
- Include only units where size ≤ max_size.
This parameter is typically combined with min_size to apply a bounding range.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| max_size | number | No | None | Upper limit for the unit size, interpreted in the selected area unit. |
Request Examples
Units up to 4000 sqft:
GET /api/v2/clients/projects/1127/units?max_size=4000
Units up to 350 m²:
GET /api/v2/clients/projects/1127/units?preferred_area_unit=m2&max_size=350
Example response:
{ "count": 4, "results": [ { "id": 455455, "size": 356.7, "price_per_area": 4827 } ]}
Notes
- If the value is very restrictive, the API may legitimately return
count: 0. - Filtering occurs after unit conversion when
preferred_area_unit=m2is used. - Works consistently across all unit types and layouts.
min_price
Description
Defines the lower bound for the unit price in the selected project.
The value is interpreted in the currency specified by preferred_currency.
If preferred_currency is not provided, the filter is evaluated in AED.
Filtering logic:
- Convert each unit’s price to the effective currency.
- Include only units where price ≥ min_price.
Used together with max_price, this forms a closed price interval.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| min_price | number | No | None | Lower limit for unit price, in the effective currency. |
Request Examples
Units priced from 10,000,000 AED:
GET /api/v2/clients/projects/1127/units?min_price=10000000
Units priced from 300,000 USD:
GET /api/v2/clients/projects/791/units?preferred_currency=USD&min_price=300000
Example response:
{ "count": 7, "results": [ { "id": 455457, "name": "1101", "price": 18365583, "size": 4940.0, "bedrooms": 2.0 } ]}
Notes
- Values below realistic ranges can return the full set of units.
- Currency selection directly influences which units satisfy the threshold.
- The filter is applied after currency conversion, not before.
min_size
Description
Defines the lower limit for the unit size.
The value is interpreted in the unit specified by preferred_area_unit.
If preferred_area_unit is omitted, the API assumes sqft.
Filtering logic:
- Convert stored size from sqft to the requested unit.
- Include units where size ≥ min_size.
Used with max_size to define a complete size interval.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| min_size | number | No | None | Lower limit for unit size, interpreted in the selected area unit. |
Request Examples
Units from 3000 sqft and larger:
GET /api/v2/clients/projects/1127/units?min_size=3000
Units from 250 m² and larger:
GET /api/v2/clients/projects/1127/units?preferred_area_unit=m2&min_size=250
Example response fragment:
{ "results": [ { "id": 455457, "size": 459.95, "bedrooms": 2.0 } ]}
Notes
- Works identically for both sqft and m2 depending on the selected area unit.
- Large values can sufficiently reduce the result set, especially for high-rise developments with smaller typical units.
- Filtering is inclusive: units equal to
min_sizeare included.
referred_area_unit
Description
Defines the measurement unit used for interpreting size filters (min_size, max_size) and for formatting the size and price_per_area values in the unit response.
Two units are supported:
- sqft — square feet (native storage format in the database),
- m2 — square meters (converted from sqft).
If preferred_area_unit is omitted, the API behaves as if preferred_area_unit=sqft.
This parameter affects:
- how the API interprets min/max size filters;
- how the
sizefield is displayed; - how the
price_per_areafield is calculated; - the units shown throughout the response.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| preferred_area_unit | string (enum) | No | sqft | Allowed values: sqft, m2. Controls filtering and formatting of all area-related fields. |
Request and Response Examples
Retrieve units where the size is expressed in square meters:
GET /api/v2/clients/projects/1127/units?preferred_area_unit=m2
Filter units by size range in square meters:
GET /api/v2/clients/projects/1127/units?preferred_area_unit=m2&min_size=200&max_size=450
Example response fragment (note the converted size):
{ "results": [ { "id": 455457, "size": 459.95, "price_per_area": 401.2 } ]}
Notes
- All sizes are stored internally in sqft, and converted to m2 only when requested.
- Filtering always uses the measurement unit defined by
preferred_area_unit. - Conversion does not affect ranking or ordering — only the numeric representation of size.
preferred_currency
Description
Defines which currency is used when applying price-based filters (min_price, max_price) and when interpreting the price field in unit responses.
The Units API supports two currencies:
- AED — native currency used in the database;
- USD — converted from AED using internal exchange rates.
If preferred_currency is omitted, the API behaves as if preferred_currency=AED were selected.
This affects:
- how
min_priceandmax_pricefilters are evaluated; - the numeric value returned in each unit’s
price; - the derived field
price_per_area.
The conversion is applied uniformly across all units in the response.
Meta
| Field name | Type | Required | Default | Notes |
|---|---|---|---|---|
| preferred_currency | string (enum) | No | AED | Allowed: AED, USD. Controls which currency is used for price filtering and output formatting. |
Request and Response Examples
Filter units using USD pricing:
GET /api/v2/clients/projects/791/units?preferred_currency=USD&min_price=300000
Same filter, but interpreted in AED:
GET /api/v2/clients/projects/791/units?preferred_currency=AED&min_price=1100000
Example response fragment:
{ "results": [ { "id": 365944, "name": "106", "price": 315588.84, "price_per_area": 372.2, "size": 847.0, "status": "available" } ]}
Notes
- Pricing is always stored internally in AED; the API converts it for the client only if
preferred_currency=USD. - All price fields (
price,price_per_area) are consistently converted. - Conversion affects both filtering and returned values—incorrect currency selection may produce unexpected results.
Unit Layouts
Description
Unit layouts represent predefined floorplan configurations that can be shared across multiple units within a project.
Each unit returned by GET /projects/{project_id}/units may include a layout block that describes:
- a layout identifier shared by many units (e.g. “1 BR Type B”),
- a human-readable name for the layout,
- one or more layout plan images (floorplan drawings),
- metadata about when the layout was created and last modified.
If a unit does not have an assigned layout, the layout field is set to null.
This structure is useful for:
- reusing the same floorplan for multiple units (different floors, different prices),
- showing consistent plan images across listings,
- building UI components like “Select layout type”, “View floorplan”, or “Compare layouts”.
Layout Object Structure
When present, the layout object inside a unit has the following structure:
"layout": { "id": 7754, "name": "1 BR Type B", "images": [ { "id": 7998, "image": { "url": "https://reelly-backend.s3.amazonaws.com/unit_layouts/a_1_1_44c07e9b8a544fb1acb1be4c72d0eb7c.webp", "metadata": { "mime": "image/webp", "size": 64968, "width": 1058, "height": 1102 } }, "name": "a 1 (1).png", "description": null, "order": 1 } ], "created": "2025-09-11T12:23:35.821245Z", "modified": "2025-09-11T12:23:35.821245Z"}
If no layout is assigned:
"layout": null
Fields
Top-level layout fields
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Unique identifier of the layout. Used to reference the layout in filters (for example, ?layout=7754). |
name | string | Yes | Human-readable layout name, typically reflecting bedroom count and variation (for example, 1 BR Type B, 3 BR Type A). |
images | array | Yes | List of layout images (floorplan visuals). May contain one or multiple entries. |
created | string (datetime, ISO 8601) | Yes | Timestamp when the layout was created in the system. |
modified | string (datetime, ISO 8601) | Yes | Timestamp of the latest layout update in the system. |
Note
The same
layout.idcan be reused by many units within the same project (and potentially across related data), which allows grouping units by layout.
Layout images array
Each element in the images array has the following structure:
{ "id": 7998, "image": { "url": "https://reelly-backend.s3.amazonaws.com/unit_layouts/a_1_1_44c07e9b8a544fb1acb1be4c72d0eb7c.webp", "metadata": { "mime": "image/webp", "size": 64968, "width": 1058, "height": 1102 } }, "name": "a 1 (1).png", "description": null, "order": 1}
Image-level fields
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Unique identifier of the layout image record. |
image | object | Yes | Nested object describing the image asset (URL and metadata). |
name | string or null | No | Optional file or display name of the layout image. May be null. |
description | string or null | No | Optional textual description for the image. May be null. |
order | integer | Yes | Display order of this image within the layout. Lower values are shown first. |
Image asset (image) and metadata
image) and metadataThe image object matches the standard media structure used across the API:
"image": { "url": "https://reelly-backend.s3.amazonaws.com/unit_layouts/2br_c489abe0....webp", "metadata": { "mime": "image/webp", "size": 10566, "width": 800, "height": 800 }}
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Direct URL to the image file, accessible for embedding in web and mobile clients. |
metadata | object | Yes | Technical metadata about the image. |
metadata fields:
metadata fields:| Field | Type | Required | Description |
|---|---|---|---|
mime | string | Yes | MIME type of the image (for example, image/jpeg, image/png, image/webp). |
size | integer | Yes | File size in bytes. |
width | integer | Yes | Image width in pixels. |
height | integer | Yes | Image height in pixels. |
Usage in Units API
-
The
layoutblock appears in each unit returned by:GET /api/v2/clients/projects/{project_id}/units -
Units without a defined layout return
"layout": null. -
layout.idis used by thelayoutquery parameter on the Units endpoint for exact filtering.Examples (for filtering units within a project):
GET /api/v2/clients/projects/1147/units?layout=7754GET /api/v2/clients/projects/1147/units?layout=null
Typical Use Cases
- Show a floorplan tab or section on the unit details page, using
layout.imagesas source. - Group units by layout (
layout.id) to build “choose your layout” selection flows. - Display thumbnail floorplans in unit lists for quick visual comparison.
- Use
orderto control the sequence of images (e.g. main plan first, secondary variations next).
Updated 21 days ago