REST API

The REST API

Your systems read Realton's catalog and your CRM, and write clients, notes, tasks and deal stages, as the person who made the key.

Business plan

Quick start

  1. In Realton, an owner or an admin opens Settings › API and MCP, ticks REST API and chooses Make a key. Copy it right away: it is shown once.
  2. Keep it on your server, in an environment variable:
    export REALTON_API_KEY="rtk_live_…"
  3. Make your first call:
    curl "https://realton.ai/api/v1/projects?place=Dubai&beds=2&limit=5" \
      -H "Authorization: Bearer $REALTON_API_KEY"

Building it with an AI

Most integrations are written by an AI today. Give it these two addresses and the task in a few words; it reads the rest by itself.

A prompt to copy, with the brackets filled in:
I want to connect [my website / my CRM / my system] to Realton's REST API.
Read the brief first: https://realton.ai/docs/api.md
The full OpenAPI document: https://realton.ai/docs/openapi.json
My stack: [for example, Next.js on Vercel].
What I want: [for example, show Realton's projects in Dubai on my site, refreshed once a day].
The API key is in the environment variable REALTON_API_KEY. Never ask me for the key and never write it into the code.

Never paste the key into a chat. Set REALTON_API_KEY on the server yourself, and tell the AI only its name.

The rules

The key

Every call sends the key in the Authorization header. A key opens the REST API only if REST API was ticked when it was made, and only while the workspace is on Business.

Authorization: Bearer rtk_live_…

Who a call acts as

A call acts as the member who made the key, with what they can see: an agent their own clients, an owner or an admin the agency's. When that member leaves the workspace, the key stops.

Limits

Up to 120 calls a minute per key. Over that, the answer is 429 with RATE_LIMITED and retryAfterSec: wait that many seconds and call again.

Pages

GET /projects returns up to 100 projects at a time: limit says how many, offset where to start, and total how many there are in all.

Ids

A project key comes from GET /projects, a client id from GET /clients, and a deal id from the client's card, GET /clients/{id}, in deals[].id.

Nothing goes to a client

No call sends anything to a client: POST /brochures returns a link for the agent to send. Prices are the developer's own, in the developer's currency.

Refusals

A refusal is JSON with a stable code. Switch on the code, never on the message.

{ "code": "plan_required" }
StatusCodeWhat it means
401key_requiredNo Authorization header with a key.
401key_invalidThe key is unknown or was revoked.
403key_scopeThe key does not open the REST API. Make one with REST API ticked.
403plan_requiredThe workspace is no longer on Business.
403key_member_goneThe person who made the key left the workspace. Make a new key.
404not_foundNot found, or not this member's to see.
429RATE_LIMITEDToo many calls this minute. Wait retryAfterSec seconds.
400place_unknown, whatsapp_invalid, …A field out of range or a value that is not one. The code names it.

Reference

Every call with its fields and an example, as in the OpenAPI document.

Base address
https://realton.ai/api/v1

Catalog

GET/projectsSearch the catalog

Projects that fit, newest first, with their price from. Up to 100 a page.

Parameters

NameTypeWhat it is
q
in the query
string ≤ 120Words of a project's or a developer's name.
place
in the query
string ≤ 80A city or an emirate, by name or slug: Dubai, Batumi, Limassol.
area
in the query
string ≤ 80An area, by name or slug: Dubai Islands, JVC.
beds
in the query
integer 0–9Bedrooms: 0 is a studio, 4 is four and more.
maxPrice
in the query
numberThe most the client would pay, in currency.
currency
in the query
stringThe currency of maxPrice.
handoverBy
in the query
integer 2025–2045The latest handover year.
lang
in the query
en | heThe language of place and area names.
limit
in the query
integer 1–100How many projects in this page.
offset
in the query
integerHow many to skip: the next page starts at offset + limit.

Answer 200

NameTypeWhat it is
totalrequiredintegerHow many projects fit, across all pages.
offsetrequiredintegerThe offset of this page.
catalogDaterequiredstringThe day the catalog was last built, YYYY-MM-DD.
projectsrequiredarray

Each of them

NameTypeWhat it is
keystringThe project key, for GET /projects/{key} and POST /brochures.
namestringThe project's name.
developerstring | nullThe developer's name.
marketae | cy | ge | om | saae, cy, ge, om or sa.
placestring | nullThe city or emirate.
areastring | nullThe area.
stageOFF_PLAN | UNDER_CONSTRUCTION | READYOFF_PLAN, UNDER_CONSTRUCTION or READY.
handoverstring | nullWhen it is handed over, as the developer says it: Q4 2028.
priceFromnumber | nullThe lowest price, in currency.
currencystringThe developer's currency: AED, EUR, USD, OMR, SAR.
bedroomsarrayThe bedroom counts it has; 0 is a studio.
commissionPctnumber | nullThe agent's commission, in percent.
photostring | nullA photo of it.
Example
{
  "total": 312,
  "offset": 0,
  "catalogDate": "2026-10-24",
  "projects": [
    {
      "key": "studio:soma-residences",
      "name": "Soma Residences",
      "developer": "Origami Properties",
      "market": "ae",
      "place": "Dubai",
      "area": "Dubai Islands",
      "stage": "OFF_PLAN",
      "handover": "Q4 2028",
      "priceFrom": 1670000,
      "currency": "AED",
      "bedrooms": [
        1,
        2,
        3
      ],
      "commissionPct": 5,
      "photo": "https://…/soma-residences.avif"
    }
  ]
}
curl
curl -X GET "https://realton.ai/api/v1/projects" \
  -H "Authorization: Bearer $REALTON_API_KEY"
GET/projects/{key}One project in full

Unit types with sizes and prices, payment plans, amenities, the gallery and what is nearby.

Parameters

NameTypeWhat it is
keyrequired
in the path
stringThe project key from GET /projects.
lang
in the query
en | heThe language of names, plans and amenities.

Answer 200

NameTypeWhat it is
entryobjectIts catalog line: the same figures as GET /projects, with title for the name and slugs for place and area.
placeNamestring | nullThe city or emirate.
areaNamestring | nullThe area.
unitTypesarrayEach unit type: label, beds, available (from the inventory), sizeSqft, sizeSqm, priceFrom, currency, pricePerArea, areaUnit.
plansarrayPayment plans: each with its steps (label, timing, percent, phase) and its share before and after handover.
dldPctnumber | nullDubai's registration fee on booking, in percent; null elsewhere.
amenitiesarrayWhat the project offers.
galleryobjectcount, and images with their url.
nearbyarrayPlaces near it: category, name, km.
curl
curl -X GET "https://realton.ai/api/v1/projects/{key}" \
  -H "Authorization: Bearer $REALTON_API_KEY"

Clients

GET/clientsYour clients

An agent's own clients; an owner's or an admin's, the agency's. Last active first.

Parameters

NameTypeWhat it is
q
in the query
string ≤ 80A name, a number or an email to look for.

Answer 200

NameTypeWhat it is
clientsrequiredarray

Each of them

NameTypeWhat it is
idstringThe client id.
namestring | nullTheir name.
whatsappstring | nullTheir number.
emailstring | nullTheir email.
languagestring | nullThe language they speak.
sourcestringWhere they came from.
stageNEW | CONTACTED | VIEWING | EOI | BOOKED | WON | LOSTThe stage of their most advanced open deal.
projectstring | nullThe project of that deal.
lastActivityAtstringThe last thing that happened with them, ISO date-time.
ownerUserIdstringThe member they belong to.
openTasksintegerTheir open tasks.
curl
curl -X GET "https://realton.ai/api/v1/clients" \
  -H "Authorization: Bearer $REALTON_API_KEY"
POST/clientsA new client

A name and at least one way to reach them is the usual; a name alone is accepted.

Body

NameTypeWhat it is
namerequiredstring ≤ 120Their full name.
whatsappstring ≤ 30A number with its country code, +971 50 555 0147.
emailstring ≤ 200An email address.
languagestring ≤ 5The language they speak, a two-letter code: en, ar, he, ru…
Example
{
  "name": "Elena Petrova",
  "whatsapp": "+971505550147",
  "language": "ru"
}

Answer 201

NameTypeWhat it is
idstringThe client id.
namestring | nullTheir name.
languagestring | nullThe language they speak.
whatsappstring | nullTheir number, E.164.
emailstring | nullTheir email.
ownerUserIdstringThe member they belong to.
updatedAtstringISO date-time.
curl
curl -X POST "https://realton.ai/api/v1/clients" \
  -H "Authorization: Bearer $REALTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Elena Petrova","whatsapp":"+971505550147","language":"ru"}'
GET/clients/{id}A client's card

Their details, what they are looking for, and their deals with each deal's id for PATCH /deals/{id}.

Parameters

NameTypeWhat it is
idrequired
in the path
stringThe client id from GET /clients.
lang
in the query
en | heThe language of place names.

Answer 200

NameTypeWhat it is
idstringThe client id.
namestring | nullTheir name.
whatsappstring | nullTheir number.
emailstring | nullTheir email.
languagestring | nullThe language they speak.
requirementsobjectWhat they are looking for: places, bedrooms, budget, handover.
ownerNamestring | nullThe member they belong to.
dealsarrayTheir deals: id, stage, projectKey, projectTitle, beds, unitLabel, price, currency, commissionPct, commission, lostReason.
curl
curl -X GET "https://realton.ai/api/v1/clients/{id}" \
  -H "Authorization: Bearer $REALTON_API_KEY"
POST/clients/{id}/notesA note on a client's card

Free text on the client's timeline, as the member.

Parameters

NameTypeWhat it is
idrequired
in the path
stringThe client id.

Body

NameTypeWhat it is
textrequiredstring ≤ 4000The note.
Example
{
  "text": "Wants a sea view, budget AED 2M, moving in 2028."
}

Answer 201

NameTypeWhat it is
idrequiredstringThe note id.
curl
curl -X POST "https://realton.ai/api/v1/clients/{id}/notes" \
  -H "Authorization: Bearer $REALTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Wants a sea view, budget AED 2M, moving in 2028."}'

Tasks

GET/tasksYour tasks

The member's own tasks, with how many there are in each scope.

Parameters

NameTypeWhat it is
scope
in the query
open | overdue | today | upcoming | someday | doneopen is every task not done.

Answer 200

NameTypeWhat it is
tasksrequiredarray
countsrequiredobjectHow many tasks in overdue, today, upcoming, someday and done.

Each of them

NameTypeWhat it is
idstringThe task id.
titlestringWhat to do.
notestring | nullMore words about it.
dueAtstring | nullWhen, ISO date-time.
dueKindAT | DAY | NONEAT, DAY or NONE.
doneAtstring | nullWhen it was done.
scopeoverdue | today | upcoming | someday | doneWhere it stands now, in the member's time zone.
contactobject | nullThe client it is for: id and name.
dealIdstring | nullThe deal it belongs to.
curl
curl -X GET "https://realton.ai/api/v1/tasks" \
  -H "Authorization: Bearer $REALTON_API_KEY"
POST/tasksA new task

A task at a time, on a day, or with no date; for a client when clientId is given.

Body

NameTypeWhat it is
titlerequiredstring ≤ 200What to do.
notestring ≤ 2000More words about it.
dueAtstring ≤ 40When: an ISO date-time with its offset, 2026-10-25T11:00:00+04:00. With dueKind DAY, any time on that day.
dueKindAT | DAY | NONEAT for a time, DAY for a whole day, NONE for no date.
clientIdstringThe client the task is for.
Example
{
  "title": "Call Elena about Soma Residences",
  "dueAt": "2026-10-25T11:00:00+04:00",
  "dueKind": "AT",
  "clientId": "cm2x8k1qz0001abcdeffghijk"
}

Answer 201

NameTypeWhat it is
idstringThe task id.
titlestringWhat to do.
notestring | nullMore words about it.
dueAtstring | nullWhen, ISO date-time.
dueKindAT | DAY | NONEAT, DAY or NONE.
doneAtstring | nullWhen it was done.
scopeoverdue | today | upcoming | someday | doneWhere it stands now, in the member's time zone.
contactobject | nullThe client it is for: id and name.
dealIdstring | nullThe deal it belongs to.
curl
curl -X POST "https://realton.ai/api/v1/tasks" \
  -H "Authorization: Bearer $REALTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Call Elena about Soma Residences","dueAt":"2026-10-25T11:00:00+04:00","dueKind":"AT","clientId":"cm2x8k1qz0001abcdeffghijk"}'

Deals

PATCH/deals/{id}Move a deal's stage

A deal's id is on its client's card (GET /clients/{id}, deals[].id).

Parameters

NameTypeWhat it is
idrequired
in the path
stringThe deal id.

Body

NameTypeWhat it is
stagerequiredNEW | CONTACTED | VIEWING | EOI | BOOKED | WON | LOSTThe new stage.
lostReasonstring ≤ 200Why it was lost; read only with LOST.
Example
{
  "stage": "VIEWING"
}

Answer 200

NameTypeWhat it is
okrequiredboolean
curl
curl -X PATCH "https://realton.ai/api/v1/deals/{id}" \
  -H "Authorization: Bearer $REALTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"stage":"VIEWING"}'

Brochures

POST/brochuresA brochure link

A brochure of a project in your brand, with open tracking, for the agent to send. Realton does not send it.

Body

NameTypeWhat it is
projectrequiredstringThe project key.
clientIdstringThe client it is for: their opens show on their card.
langrequireden | heThe language of the brochure.
Example
{
  "project": "studio:soma-residences",
  "clientId": "cm2x8k1qz0001abcdeffghijk",
  "lang": "en"
}

Answer 201

NameTypeWhat it is
idrequiredstringThe link id.
urlrequiredstringThe address to send: it opens the brochure in the agency's brand.
projectrequiredstringThe project name.
langrequiredstringThe language of the brochure.
clientrequiredstring | nullThe client's name, when it is for one.
Example
{
  "id": "cm2x9p0aa0002abcdeffghijk",
  "url": "https://realton.ai/b/Hk3…",
  "project": "Soma Residences",
  "lang": "en",
  "client": "Elena Petrova"
}
curl
curl -X POST "https://realton.ai/api/v1/brochures" \
  -H "Authorization: Bearer $REALTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project":"studio:soma-residences","clientId":"cm2x8k1qz0001abcdeffghijk","lang":"en"}'