PropertyIndex Locations API
All published Dubai location nodes as a flat lookup of opaque identifiers and names. Names may repeat; identifiers scope sales and rentals to a node and its descendants.
All published Dubai location nodes as a flat lookup of opaque identifiers and names. Names may repeat; identifiers scope sales and rentals to a node and its descendants.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/propertyindex-ae:propertyindex-ae-locations-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: PIX Locations API
version: 1.0.0
description: 'The PIX API gives licensed organisations direct, programmatic access to the
Dubai Land Department records that PropertyIndex models: every registered
sale, every registered tenancy period, its location labels and floor,
and the PIX market index, as flat rows you can pull into your
own systems. Each record carries its registered figures and our per-record
calculations (price and rent per square foot, normalised property type and
bedrooms). Location and floor labels are not identifiers or proof of a
unique physical structure. Unit numbers, persistent property identities and cross-record histories are
not part of the API. ## Location labels
Sales and rentals carry the record''s assigned location as labels:
- `location_path` is the full published path, an ordered list of labels
from Dubai to the assigned location. - `highest_location_level` is the first node after Dubai, regardless of
its kind. - `lowest_location_level` is the final assigned location node, which
may be an area, community, subcommunity, tower or the city itself. For a sale in Beach Vista Tower 1:
```json
{
"location_path": ["Dubai", "Dubai Harbour", "Emaar Beachfront", "Beach Vista", "Beach Vista Tower 1"],
"highest_location_level": "Dubai Harbour",
"lowest_location_level": "Beach Vista Tower 1"
}
```
When only one node follows Dubai, both level fields contain that node''s
label. For a city-only assignment, the path is `["Dubai"]`, the highest
value is null and the lowest is `Dubai`. All three are null when the
location is unresolved; a path is never partial. Labels are names, not identifiers, and names can repeat across the tree. `location_path` is returned by default and can be requested with
`fields`, but it is not a filter, sort or cursor field. To scope a query
to a place, use `location_id`. ## Base URL
All endpoints are served from `https://api.propertyindex.ae`. Only `GET`
requests are accepted. Responses are JSON. ## Authentication
Send your key as a bearer token on every request:
```
Authorization: Bearer pix_api_XXXXXXXXXX_... ```
Keys are issued to your organisation, not to a person. Keep them server-side. A key can be revoked and reissued at any time on request. ## Allowance and rate limits
Authenticated responses carry your meter in headers: `PIX-Usage-Used`,
`PIX-Usage-Allowance`, `PIX-Usage-Remaining`, `PIX-Usage-Period` and,
where the period has an end, `PIX-Usage-Period-End`. `PIX-Usage-Unit: records` identifies the unit. `PIX-Usage-Remaining`
means included records remaining, excluding optional overage capacity. `GET /v1/usage` returns these figures and the effective
`recordsRemaining`, including any enabled overage capacity, without
consuming records. The paid plan is AED 5,000 per month and includes 1,000,000 sales and rental
records per billing period, shared across the organisation''s API keys. Each actual row returned by a sales or rentals
list counts as one record; a successful single-record response counts as
one. Repeated retrievals count again. Query and validation failures and
empty responses consume no records. Locations, market index, documentation
and usage are unmetered. Optional overage costs AED 2 per 1,000 records, prorated to the nearest fils
on the billing period total: `overageCostMinor = round(overageRecords / 5)`. Overage is off by default. An organisation owner or admin must opt in and
set a finite monthly overage spending cap, excluding the subscription and
any applicable taxes. `overageCapMinor` is that cap
in fils; when enabled, each fils adds five records to `recordLimit` above
the included allowance. `remaining` counts only unused included records;
`recordsRemaining` counts capacity up to the effective `recordLimit`. Demo grants have a fixed record allowance with no overage. Both demo and paid keys enforce a hard limit. If the actual response would
exceed `recordsRemaining`, the whole response is rejected with
`429 allowance_exhausted` and no records are charged.'
contact:
name: PropertyIndex
email: info@propertyindex.ae
url: https://www.propertyindex.ae
termsOfService: https://www.propertyindex.ae/terms-of-service
license:
name: PIX API licence (proprietary)
url: https://www.propertyindex.ae/terms-of-service
servers:
- url: https://api.propertyindex.ae
security:
- bearerAuth: []
tags:
- name: Locations
description: All published Dubai location nodes as a flat lookup of opaque identifiers and names. Names may repeat; identifiers scope sales and rentals to a node and its descendants.
paths:
/v1/locations:
get:
tags:
- Locations
operationId: listLocations
summary: List locations
description: 'All published Dubai location nodes, as a flat lookup of public identifiers and names. All published location nodes: Dubai itself, areas, communities, subcommunities and towers. Each row contains only an opaque location_id and name, with no hierarchy fields. Names may repeat. Use the identifier to retrieve a single lookup entry or filter sales and rentals to that node and its descendants. Unmetered: consumes no records. The burst rate limit still applies.'
parameters:
- name: q
in: query
description: Case-insensitive location name search. Names may repeat.
required: false
schema:
type: string
example: Beach Vista
- name: sort
in: query
description: Field to sort by. Default name.
required: false
schema:
type: string
enum:
- name
- name: order
in: query
description: Sort direction. Default asc.
required: false
schema:
type: string
enum:
- asc
- desc
- name: limit
in: query
description: Rows per page, 1 to 1,000. Default 100.
required: false
schema:
type: integer
minimum: 1
maximum: 1000
- name: page
in: query
description: Numbered page, starting at 1. Send one positive integer. Uses limit (default 100, maximum 1000). Cannot be combined with cursor. Omit both to start at the first page. The computed offset (page - 1) * limit must also be a safe integer. Large page numbers may be slower because earlier rows must be skipped; prefer cursors for sequential bulk walks.
required: false
schema:
type: integer
minimum: 1
maximum: 9007199254740991
- name: cursor
in: query
description: Opaque cursor from a previous response's next_cursor. Send the same sort, order and filters, including location_id and location_search where supported. Cannot be combined with page. To continue a numbered page using next_cursor, remove page.
required: false
schema:
type: string
- name: fields
in: query
description: Comma-separated list of fields to return. Default all.
required: false
schema:
type: string
example: location_id,name
responses:
'200':
description: One page of rows.
headers:
PIX-Usage-Kind:
description: paid or demo.
schema:
type: string
enum:
- paid
- demo
PIX-Usage-Unit:
description: The usage unit is records.
schema:
type: string
const: records
PIX-Usage-Used:
description: Sales and rental records used in the current period, including this response.
schema:
type: integer
minimum: 0
PIX-Usage-Allowance:
description: Records included in the current period, before optional overage.
schema:
type: integer
minimum: 0
PIX-Usage-Remaining:
description: Included records remaining, excluding overage capacity. GET /v1/usage returns recordsRemaining for effective capacity.
schema:
type: integer
minimum: 0
PIX-Usage-Period:
description: Identifier of the current period.
schema:
type: string
PIX-Usage-Period-End:
description: When the current period ends, if it does.
schema:
type: string
format: date-time
content:
application/json:
schema:
$ref: '#/components/schemas/LocationList'
'400':
description: The request is not valid. The message names the parameter.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or unrecognised API key.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The key is not active, or the organisation holds no licence or demo allowance.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit reached, or the response exceeds recordsRemaining (allowance_exhausted). The whole response is rejected without consuming records; request a smaller limit if capacity remains.
headers:
PIX-Usage-Kind:
description: paid or demo.
schema:
type: string
enum:
- paid
- demo
PIX-Usage-Unit:
description: The usage unit is records.
schema:
type: string
const: records
PIX-Usage-Used:
description: Sales and rental records used in the current period, including this response.
schema:
type: integer
minimum: 0
PIX-Usage-Allowance:
description: Records included in the current period, before optional overage.
schema:
type: integer
minimum: 0
PIX-Usage-Remaining:
description: Included records remaining, excluding overage capacity. GET /v1/usage returns recordsRemaining for effective capacity.
schema:
type: integer
minimum: 0
PIX-Usage-Period:
description: Identifier of the current period.
schema:
type: string
PIX-Usage-Period-End:
description: When the current period ends, if it does.
schema:
type: string
format: date-time
Retry-After:
description: Seconds to wait before retrying (rate limit only).
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v1/locations/{id}:
get:
tags:
- Locations
operationId: getLocation
summary: Get one location
description: 'Unmetered: consumes no records. The burst rate limit still applies.'
parameters:
- name: id
in: path
required: true
schema:
type: string
example: loc_0123456789abcdef
responses:
'200':
description: The location.
headers:
PIX-Usage-Kind:
description: paid or demo.
schema:
type: string
enum:
- paid
- demo
PIX-Usage-Unit:
description: The usage unit is records.
schema:
type: string
const: records
PIX-Usage-Used:
description: Sales and rental records used in the current period, including this response.
schema:
type: integer
minimum: 0
PIX-Usage-Allowance:
description: Records included in the current period, before optional overage.
schema:
type: integer
minimum: 0
PIX-Usage-Remaining:
description: Included records remaining, excluding overage capacity. GET /v1/usage returns recordsRemaining for effective capacity.
schema:
type: integer
minimum: 0
PIX-Usage-Period:
description: Identifier of the current period.
schema:
type: string
PIX-Usage-Period-End:
description: When the current period ends, if it does.
schema:
type: string
format: date-time
content:
application/json:
schema:
$ref: '#/components/schemas/LocationSingle'
'400':
description: The request is not valid. The message names the parameter.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or unrecognised API key.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The key is not active, or the organisation holds no licence or demo allowance.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: No location with that id.
headers: {}
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit reached, or the response exceeds recordsRemaining (allowance_exhausted). The whole response is rejected without consuming records; request a smaller limit if capacity remains.
headers:
PIX-Usage-Kind:
description: paid or demo.
schema:
type: string
enum:
- paid
- demo
PIX-Usage-Unit:
description: The usage unit is records.
schema:
type: string
const: records
PIX-Usage-Used:
description: Sales and rental records used in the current period, including this response.
schema:
type: integer
minimum: 0
PIX-Usage-Allowance:
description: Records included in the current period, before optional overage.
schema:
type: integer
minimum: 0
PIX-Usage-Remaining:
description: Included records remaining, excluding overage capacity. GET /v1/usage returns recordsRemaining for effective capacity.
schema:
type: integer
minimum: 0
PIX-Usage-Period:
description: Identifier of the current period.
schema:
type: string
PIX-Usage-Period-End:
description: When the current period ends, if it does.
schema:
type: string
format: date-time
Retry-After:
description: Seconds to wait before retrying (rate limit only).
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
LocationList:
type: object
required:
- data
- next_cursor
- as_of
- total
- page
- limit
properties:
data:
type: array
items:
$ref: '#/components/schemas/Location'
next_cursor:
type:
- string
- 'null'
description: Returned for cursor and numbered pages when more data exists. Pass as cursor to fetch the next page, removing page and preserving sort, order and filters. null on the last page.
as_of:
type:
- string
- 'null'
format: date
description: The DLD delivery date the data was built from.
total:
type: integer
minimum: 0
description: 'Exact number of records matching all filters, including q, location_search and location scopes where supported. Ignores page, limit and cursor. Always included, even on empty pages. Not a snapshot: can change after a data refresh.'
page:
type:
- integer
- 'null'
minimum: 1
maximum: 9007199254740991
description: Requested numbered page, or 1 when neither page nor cursor was supplied. null for cursor requests because a cursor position is not a numbered page.
limit:
type: integer
minimum: 1
maximum: 1000
description: Requested page size, or 100 when omitted. This is the maximum rows requested, not the actual number returned; data can contain fewer rows.
Location:
type: object
description: 'All published location nodes: Dubai itself, areas, communities, subcommunities and towers. Each row contains only an opaque location_id and name, with no hierarchy fields. Names may repeat. Use the identifier to retrieve a single lookup entry or filter sales and rentals to that node and its descendants.'
properties:
location_id:
type:
- string
- 'null'
pattern: ^loc_[0-9a-f]{16}$
description: Opaque public location identifier. Use it to retrieve this lookup entry or filter sales and rentals to this location and its descendants.
name:
type:
- string
- 'null'
description: Location display name. Names are not unique.
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
example: invalid_parameter
message:
type: string
LocationSingle:
type: object
required:
- data
- as_of
properties:
data:
$ref: '#/components/schemas/Location'
as_of:
type:
- string
- 'null'
format: date
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'Your PIX API key, sent as `Authorization: Bearer pix_api_...`.'