Send your key in the Authorization header on every request. All requests use HTTPS and return JSON.
curl -H "Authorization: Bearer YOUR_API_KEY" "https://realty.rilt.ai/api/v1/projects?per_page=10&city=Dubai"
Base URL: https://realty.rilt.ai/api/v1. Keys can be revoked or rotated at any time; the old key stops working immediately.
| Path | What it does | Parameters | |
|---|---|---|---|
| GET | /api/v1/projects | List projects (paginated). | page, per_page (max 100), q*, city, community, developer†, type†, status†, min_price†, max_price†, bedrooms†, updated_since†, bbox† (south,west,north,east, needs maps), sort (newest|updated|name|price_asc†|price_desc†) |
| GET | /api/v1/projects/{id} | One project with description, amenities, payment plan, units and media your plan includes. | |
| GET | /api/v1/projects/{id}/media | Image, brochure and floor-plan links the plan includes. | |
| GET | /api/v1/units | List unit types (property configurations) across projects. | page, per_page, project_id, bedrooms†, min_price†, max_price†, min_area† |
| GET | /api/v1/units/{id} | One unit type. | |
| GET | /api/v1/developers | Developers with project counts (needs advanced filters). | |
| GET | /api/v1/locations | Cities and communities with project counts. | |
| GET | /api/v1/changes | Records created or changed after a cursor; removed records come back as {deleted:true}. | cursor (version of the last record you processed; start at 0), limit (max 500), since (ISO time, alternative start) |
| GET | /api/v1/status | When the data last changed and was last synced from the source. | |
| GET | /api/v1/usage | Your own quota, limits and plan features. Does not use quota. |
* needs the Search feature · † needs Advanced filters. Lists return { data: [...], meta: { page, per_page, total, has_more } }.
const res = await fetch("https://realty.rilt.ai/api/v1/projects?per_page=10", {
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();import requests
r = requests.get("https://realty.rilt.ai/api/v1/projects", params={"per_page": 10},
headers={"Authorization": "Bearer YOUR_API_KEY"}, timeout=30)
r.raise_for_status()
projects = r.json()["data"]Every record has a version that only goes up. Ask for everything after the last version you saw; deleted or archived records come back as { "id": "...", "deleted": true }. Start with cursor=0 for a full copy.
// Keep your own copy up to date: run this every few minutes (or as often as your plan allows)
let cursor = Number(loadCursor() ?? 0);
for (;;) {
const r = await fetch(`https://realty.rilt.ai/api/v1/changes?cursor=${cursor}&limit=200`, { headers: { Authorization: "Bearer YOUR_API_KEY" } });
const { data, meta } = await r.json();
for (const p of data) p.deleted ? removeLocal(p.id) : saveLocal(p);
cursor = meta.next_cursor; saveCursor(cursor);
if (!meta.has_more) break;
}GET /api/v1/projects/{id}
{
"data": {
"id": "…", "external_id": "5785", "version": 12345, "updated_at": "2026-10-11T09:09:21.000Z",
"name": "…", "developer": { "id": "…", "name": "…" }, "city": "Dubai", "community": "…",
"latitude": 25.2, "longitude": 55.3, "status": "Announced",
"completion": { "date": "2029-12-31", "text": "31-12-2029" },
"price_min": 599000, "price_max": 599000, "currency": "AED",
"units": [ { "type": "1Bedrooms", "bedrooms": 1, "area_min": 645, "price_min": 999000 } ],
"media": [ { "kind": "cover", "url": "https://…" } ]
}
}Fields appear only if your plan includes them. Prices shown by the source are rounded (e.g. “AED 1.2M”) and are returned as such.
name – Project namedeveloper – Developerdescription – DescriptionpropertyTypes – Property typescity – Citycommunity – Community / districtaddress – Addresslatitude – Latitudelongitude – LongitudesaleStatus – Sale / construction statuscompletionDate – Completion datepriceMin – Minimum pricepriceMax – Maximum pricecurrency – Currencyamenities – AmenitiespaymentPlan – Payment plansourceUrl – Source linkimages – Image URLs and galleriesbrochures – Brochures and documentsfloorPlans – Floor plansmaps – Coordinates, map bounding-box searchsearch – Free-text searchadvancedFilters – Advanced filters (price, bedrooms, developer, type)units – Unit / property endpointschangeFeed – Change feed (records changed since a time)syncStatus – Data update and sync status endpointwebhooks – Webhooks (we notify your system when data changes)export – CSV / JSON export from the portalInstead of polling, register an HTTPS endpoint in the portal. We send data.updated when new data is ready (only counts and versions, never property data), plus quota.warning and subscription.changed. Each request is signed: X-Rilt-Signature: t=<time>,v1=HMAC-SHA256(secret, t + "." + body). Reply with a 2xx within 8 seconds; failures retry after 1 min, 5 min, 30 min, 2 h and 6 h. On data.updated, call /api/v1/changes with your stored cursor.
Every response carries X-RateLimit-Limit/Remaining/Reset (per minute) and X-Quota-Limit/Remaining (per month, UTC calendar month). The change feed may also be limited to one call every N seconds on smaller plans.
Errors use a consistent shape: { "error": { "code": "…", "message": "…", "status": 429, "request_id": "req_…" } }
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_parameter | A query parameter is malformed or out of range. |
| 400 | history_limit | `since` is older than your plan's change-history window. |
| 401 | missing_credentials | No API key was sent. |
| 401 | invalid_api_key | The key does not exist or is malformed. |
| 401 | key_revoked | The key was revoked. |
| 401 | key_expired | The key passed its expiry date. |
| 402 | no_subscription / subscription_expired / subscription_paused / subscription_pending | The company has no active subscription. |
| 403 | feature_not_in_plan | The endpoint, filter or field needs a feature your plan does not include. |
| 403 | scope_not_allowed | The key was restricted and may not use this endpoint. |
| 403 | tenant_suspended / tenant_pending / tenant_closed | The company account is not active. |
| 404 | not_found | No such record, or it is outside your plan. |
| 429 | rate_limited | Per-minute limit hit. Wait for `Retry-After` seconds. |
| 429 | quota_exceeded | Monthly request quota used up. |
| 429 | too_frequent | Change-feed called more often than your plan allows. |
| 500 | internal_error | Our side. Retry later and quote `request_id`. |
Images, brochures and floor plans are returned as links to the original files and only when the platform has confirmed it may redistribute them and your plan includes them. Respect the source's terms when you display them. A machine-readable description is at https://realty.rilt.ai/api/v1/openapi.json.