# Realton REST API: a brief for the AI writing the integration

An agency's catalog and CRM in Realton, for its own systems: projects in five markets with their prices and payment plans, clients, notes, tasks, a deal's stage and brochure links. Every call acts as the member who made the key, with what that member can see in Realton. Nothing here sends anything to a client.

## The rules

- Base address: `https://realton.ai/api/v1`. JSON in and out.
- Every call sends `Authorization: Bearer <key>`. The key starts with `rtk_live_`; an owner or an admin makes it in Realton, Settings, API and MCP, with "REST API" ticked (the Business plan). Read it from an environment variable such as `REALTON_API_KEY`. Never write it into code, a web page, an app, or a chat.
- A call acts as the member who made the key: an agent sees their own clients, an owner or an admin the agency's.
- Up to 120 calls a minute per key. Over that: 429 with `{"code":"RATE_LIMITED","retryAfterSec":N}`; wait N seconds.
- A refusal is JSON with a stable `code`; switch on it, never on `message`. 401: `key_required`, `key_invalid`. 403: `key_scope`, `plan_required`, `key_member_gone`. 404: `not_found`, `project_not_found`. 400: the field codes listed under each call.
- `GET /projects` pages with `limit` (up to 100) and `offset`; `total` says how many there are in all.
- Ids: a project key comes from `GET /projects` (`key`); a client id from `GET /clients` (`id`); a deal id from a client's card (`GET /clients/{id}`, `deals[].id`).
- Nothing here sends anything to a client: `POST /brochures` returns a `url` for the agent to send.
- Prices are the developer's, in the developer's currency.

The full OpenAPI 3.1 document: https://realton.ai/docs/openapi.json

## The calls

### GET /projects: Search the catalog

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

Parameters:
- `q` (query): string, 0–120 chars. Words of a project's or a developer's name.
- `place` (query): string, 0–80 chars. A city or an emirate, by name or slug: Dubai, Batumi, Limassol.
- `area` (query): string, 0–80 chars. An area, by name or slug: Dubai Islands, JVC.
- `beds` (query): integer, 0–9. Bedrooms: 0 is a studio, 4 is four and more.
- `maxPrice` (query): number, ≥ 0. The most the client would pay, in `currency`.
- `currency` (query): string, pattern ^[A-Z]{3}$, default AED. The currency of `maxPrice`.
- `handoverBy` (query): integer, 2025–2045. The latest handover year.
- `lang` (query): string (en, he), default en. The language of place and area names.
- `limit` (query): integer, 1–100, default 25. How many projects in this page.
- `offset` (query): integer, ≥ 0, default 0. How many to skip: the next page starts at offset + limit.

Answer 200: The projects that fit, and how many there are in all.
- `total` (required): integer. How many projects fit, across all pages.
- `offset` (required): integer. The offset of this page.
- `catalogDate` (required): string. The day the catalog was last built, YYYY-MM-DD.
- `projects` (required): array.

Each of them:
- `key`: string. The project key, for `GET /projects/{key}` and `POST /brochures`.
- `name`: string. The project's name.
- `developer`: string or null. The developer's name.
- `market`: string or null (ae, cy, ge, om, sa). ae, cy, ge, om or sa.
- `place`: string or null. The city or emirate.
- `area`: string or null. The area.
- `stage`: string or null (OFF_PLAN, UNDER_CONSTRUCTION, READY). OFF_PLAN, UNDER_CONSTRUCTION or READY.
- `handover`: string or null. When it is handed over, as the developer says it: Q4 2028.
- `priceFrom`: number or null. The lowest price, in `currency`.
- `currency`: string. The developer's currency: AED, EUR, USD, OMR, SAR.
- `bedrooms`: array. The bedroom counts it has; 0 is a studio.
- `commissionPct`: number or null. The agent's commission, in percent.
- `photo`: string or null. A photo of it.

```json
{
  "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"
    }
  ]
}
```

```sh
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:
- `key` (path, required): string, pattern ^(studio|wp|snap):[A-Za-z0-9_.:-]{1,120}$. The project key from `GET /projects`.
- `lang` (query): string (en, he), default en. The language of names, plans and amenities.

Answer 200: The project.
- `entry`: object. Its catalog line: the same figures as `GET /projects`, with `title` for the name and slugs for place and area.
- `placeName`: string or null. The city or emirate.
- `areaName`: string or null. The area.
- `unitTypes`: array. Each unit type: label, beds, available (from the inventory), sizeSqft, sizeSqm, priceFrom, currency, pricePerArea, areaUnit.
- `plans`: array. Payment plans: each with its steps (label, timing, percent, phase) and its share before and after handover.
- `dldPct`: number or null. Dubai's registration fee on booking, in percent; null elsewhere.
- `amenities`: array. What the project offers.
- `gallery`: object. count, and images with their url.
- `nearby`: array. Places near it: category, name, km.

```sh
curl -X GET "https://realton.ai/api/v1/projects/{key}" \
  -H "Authorization: Bearer $REALTON_API_KEY"
```

### GET /clients: Your clients

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

Parameters:
- `q` (query): string, 0–80 chars. A name, a number or an email to look for.

Answer 200: The clients.
- `clients` (required): array.

Each of them:
- `id`: string. The client id.
- `name`: string or null. Their name.
- `whatsapp`: string or null. Their number.
- `email`: string or null. Their email.
- `language`: string or null. The language they speak.
- `source`: string. Where they came from.
- `stage`: string or null (NEW, CONTACTED, VIEWING, EOI, BOOKED, WON, LOST). The stage of their most advanced open deal.
- `project`: string or null. The project of that deal.
- `lastActivityAt`: string. The last thing that happened with them, ISO date-time.
- `ownerUserId`: string. The member they belong to.
- `openTasks`: integer. Their open tasks.

```sh
curl -X GET "https://realton.ai/api/v1/clients" \
  -H "Authorization: Bearer $REALTON_API_KEY"
```

### POST /clients: A new client

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

Body:
- `name` (required): string, 1–120 chars. Their full name.
- `whatsapp`: string, 0–30 chars. A number with its country code, +971 50 555 0147.
- `email`: string, 0–200 chars. An email address.
- `language`: string, 0–5 chars. The language they speak, a two-letter code: en, ar, he, ru…

```json
{
  "name": "Elena Petrova",
  "whatsapp": "+971505550147",
  "language": "ru"
}
```

Answer 201: The client.
- `id`: string. The client id.
- `name`: string or null. Their name.
- `language`: string or null. The language they speak.
- `whatsapp`: string or null. Their number, E.164.
- `email`: string or null. Their email.
- `ownerUserId`: string. The member they belong to.
- `updatedAt`: string. ISO date-time.

```sh
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:
- `id` (path, required): string, pattern ^c[a-z0-9]{20,32}$. The client id from `GET /clients`.
- `lang` (query): string (en, he), default en. The language of place names.

Answer 200: The card.
- `id`: string. The client id.
- `name`: string or null. Their name.
- `whatsapp`: string or null. Their number.
- `email`: string or null. Their email.
- `language`: string or null. The language they speak.
- `requirements`: object. What they are looking for: places, bedrooms, budget, handover.
- `ownerName`: string or null. The member they belong to.
- `deals`: array. Their deals: id, stage, projectKey, projectTitle, beds, unitLabel, price, currency, commissionPct, commission, lostReason.

```sh
curl -X GET "https://realton.ai/api/v1/clients/{id}" \
  -H "Authorization: Bearer $REALTON_API_KEY"
```

### POST /clients/{id}/notes: A note on a client's card

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

Parameters:
- `id` (path, required): string, pattern ^c[a-z0-9]{20,32}$. The client id.

Body:
- `text` (required): string, 1–4000 chars. The note.

```json
{
  "text": "Wants a sea view, budget AED 2M, moving in 2028."
}
```

Answer 201: The note was added.
- `id` (required): string. The note id.

```sh
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."}'
```

### GET /tasks: Your tasks

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

Parameters:
- `scope` (query): string (open, overdue, today, upcoming, someday, done), default open. open is every task not done.

Answer 200: The tasks.
- `tasks` (required): array.
- `counts` (required): object. How many tasks in overdue, today, upcoming, someday and done.

Each of them:
- `id`: string. The task id.
- `title`: string. What to do.
- `note`: string or null. More words about it.
- `dueAt`: string or null. When, ISO date-time.
- `dueKind`: string (AT, DAY, NONE). AT, DAY or NONE.
- `doneAt`: string or null. When it was done.
- `scope`: string (overdue, today, upcoming, someday, done). Where it stands now, in the member's time zone.
- `contact`: object or null. The client it is for: id and name.
- `dealId`: string or null. The deal it belongs to.

```sh
curl -X GET "https://realton.ai/api/v1/tasks" \
  -H "Authorization: Bearer $REALTON_API_KEY"
```

### POST /tasks: A new task

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

Body:
- `title` (required): string, 1–200 chars. What to do.
- `note`: string, 0–2000 chars. More words about it.
- `dueAt`: string, 0–40 chars. When: an ISO date-time with its offset, 2026-10-25T11:00:00+04:00. With dueKind DAY, any time on that day.
- `dueKind`: string (AT, DAY, NONE). AT for a time, DAY for a whole day, NONE for no date.
- `clientId`: string, pattern ^c[a-z0-9]{20,32}$. The client the task is for.

```json
{
  "title": "Call Elena about Soma Residences",
  "dueAt": "2026-10-25T11:00:00+04:00",
  "dueKind": "AT",
  "clientId": "cm2x8k1qz0001abcdeffghijk"
}
```

Answer 201: The task.
- `id`: string. The task id.
- `title`: string. What to do.
- `note`: string or null. More words about it.
- `dueAt`: string or null. When, ISO date-time.
- `dueKind`: string (AT, DAY, NONE). AT, DAY or NONE.
- `doneAt`: string or null. When it was done.
- `scope`: string (overdue, today, upcoming, someday, done). Where it stands now, in the member's time zone.
- `contact`: object or null. The client it is for: id and name.
- `dealId`: string or null. The deal it belongs to.

```sh
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"}'
```

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

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

Parameters:
- `id` (path, required): string, pattern ^c[a-z0-9]{20,32}$. The deal id.

Body:
- `stage` (required): string (NEW, CONTACTED, VIEWING, EOI, BOOKED, WON, LOST). The new stage.
- `lostReason`: string, 0–200 chars. Why it was lost; read only with LOST.

```json
{
  "stage": "VIEWING"
}
```

Answer 200: The deal moved.
- `ok` (required): boolean.

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

### POST /brochures: A brochure link

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

Body:
- `project` (required): string, pattern ^(studio|wp|snap):[A-Za-z0-9_.:-]{1,120}$. The project key.
- `clientId`: string, pattern ^c[a-z0-9]{20,32}$. The client it is for: their opens show on their card.
- `lang` (required): string (en, he). The language of the brochure.

```json
{
  "project": "studio:soma-residences",
  "clientId": "cm2x8k1qz0001abcdeffghijk",
  "lang": "en"
}
```

Answer 201: The link.
- `id` (required): string. The link id.
- `url` (required): string. The address to send: it opens the brochure in the agency's brand.
- `project` (required): string. The project name.
- `lang` (required): string. The language of the brochure.
- `client` (required): string or null. The client's name, when it is for one.

```json
{
  "id": "cm2x9p0aa0002abcdeffghijk",
  "url": "https://realton.ai/b/Hk3…",
  "project": "Soma Residences",
  "lang": "en",
  "client": "Elena Petrova"
}
```

```sh
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"}'
```

## For an AI assistant rather than code: MCP

Claude, ChatGPT, Claude Code and Cursor connect to `https://realton.ai/mcp` (Streamable HTTP; sign-in with OAuth, or a key with "AI clients (MCP)" ticked as a Bearer header). The tools, as the server lists them:

- `search_projects`: Projects in the agent's catalog that fit what a client wants: a place or an area (a name or its slug), bedrooms (0 is a studio), a budget in a currency (the price for those bedrooms must be within it), the latest handover year, payments after handover, words of a name or a developer. `order` 'less_before_handover' puts first the projects that ask the least before handover. Returns up to 8 with their figures for the bedrooms asked; the first ones are shown to the agent as cards.
- `project_details`: One project's unit types (bedrooms, size, price from), its payment plan step by step with what is paid before handover for each type, handover, Dubai's registration fee where it applies, and the agent's commission. Use the key from a search, or the name.
- `find_clients`: The agent's clients whose name or email holds the words, with their stage and project. Never their numbers.
- `client_context`: What a client wants (bedrooms, place, budget, handover by, who it is for), their deal and its stage, their shortlist, the brochures they were sent and opened, and their last messages. Never their number.
- `make_brochure`: A branded, tracked brochure link for one project, for a client when given, in English or Hebrew (other languages arrive later: say so). It is a draft: the agent opens it, checks it and sends it. Returns the card that opens it.
- `add_task`: A task in the agent's own list, for a client when one is named or in context: what to do, and when, in the agent's own time (YYYY-MM-DD for a day, YYYY-MM-DDTHH:MM for a time). The agent is reminded when it is due. Returns a card that opens the tasks.
- `add_note`: A note on a client's card, in the agent's words or as the agent dictated it. Returns a card that opens the client.
- `move_deal`: Moves one of a client's deals (its id from client_context) to a stage: NEW, CONTACTED, VIEWING, EOI, BOOKED, WON or LOST (a lost deal may carry the reason). Only when the agent asks for it. Returns a card that opens the pipeline.
- `add_client`: A new client in the agent's CRM: a name, and their WhatsApp number or email when the agent gave one, and their language when known. Search with find_clients first: never add a client who is already there. Returns a card that opens the client.
- `shortlist_project`: Adds a project (its key from a search) to a client's shortlist, where it is compared with the others. Returns a card that opens the client.
- `draft_post`: A draft post for a project (its key), written in the agency's brand and the workspace's default design: a carousel for a feed, or a banner (one image, which can also be a story). In a language the project has a page in. Takes up to a minute. The agent opens the draft, changes what they like and downloads the files. Returns a card that opens it.

How to connect each app: https://realton.ai/docs/connect-ai
