Reallyo Listings API
Send your rental and sale listings to Reallyo from your own systems or an AI agent; Reallyo publishes them to the listing portals. Any Reallyo account; your plan sets how many rentals can be available at once.
For AI agents (MCP):
In Claude or ChatGPT, add it as a custom connector: sign in with your Reallyo login and choose read only or read and write (no API key needed); disconnect it under API settings in your Reallyo dashboard. In code and developer tools, send the header
REST: OpenAPI 3.1 · Agent summary: llms.txt
Keys and connected apps: API settings in your Reallyo dashboard (no key yet? make one there; re-roll and disable keys; disconnect apps). Using the API means agreeing to the API Terms.
https://mcp.reallyo.comIn Claude or ChatGPT, add it as a custom connector: sign in with your Reallyo login and choose read only or read and write (no API key needed); disconnect it under API settings in your Reallyo dashboard. In code and developer tools, send the header
Authorization: Bearer rly_live_….REST: OpenAPI 3.1 · Agent summary: llms.txt
Keys and connected apps: API settings in your Reallyo dashboard (no key yet? make one there; re-roll and disable keys; disconnect apps). Using the API means agreeing to the API Terms.
Two ids, and the MLS number
id | Reallyo's id for the listing (a number). Every listing on your account has one, including those made in the Reallyo dashboard. A listing you create has id: null until Reallyo has created it. |
external_id | Your id for the unit (e.g. your property-management unit id), unique on your account. Listings made in the dashboard have none until you give them one. |
mls_id | The listing's MLS number (a field of the listing). /v1/listings/mls_id/{mls_id} names an existing listing by it, matched trimmed, ignoring case and repeated spaces; several matches → 409 mls_ambiguous with their ids. |
Use id for any listing you have seen in a response, external_id for your own units, and the MLS number when that is what you have.
How it works
- Create a listing with
POST /v1/listings;external_id(your own id) andmls_idare optional fields of it. The response is201 Createdwith Reallyo'sidand aLocationheader (or202 Acceptedif Reallyo has not finished creating it yet:idis null for a moment). A second create with the sameexternal_idis refused (409 external_id_taken, with the existing listing's id). To retry a create safely without an external_id, send anIdempotency-Keyheader. - Change or take down any listing on your account by any of its names:
PATCH/DELETE. To manage a listing made in the dashboard with your own id, give it one:PATCH /v1/listings/{id}with{"external_id":"UNIT-12B"}. - Every listing is checked first. A listing that fails the checks is refused with
422 invalid_listingand nothing is stored;error.details.errorsnames each field and what to send instead. - Accepted changes are stored and then applied to the listing, usually within seconds;
last_changesaysqueued, thenapplied. One that cannot be applied as sent isheldorfailed, with a message saying why. Changes can also bepaused: kept, and applied later in the order sent (below). - Available rentals count towards your plan's listing limit, those made in the dashboard included; sales and other statuses do not. At the limit a change that would add one is refused with
plan_limit_reachedand not saved; nothing else is done. To keep it, send it as a draft, then update it to available once you are under the limit (mark a unit rented, remove one, or upgrade). - Keep phone numbers, email addresses and web links out of the description: Zillow declines them, so Reallyo holds such listings.
- When a unit is let, set
statusto"rented". Removing a listing takes it down; it is kept, never deleted. - Keys: an account can have several named keys. A key can be read only (it reads and validates; a change is
403 key_read_only), disabled (403 key_disabled) or limited to IP addresses (403 ip_not_allowed, naming the address seen).GET /v1/menames the key and showsdaily_changes. - One listing per request, by design. Limits: 120 requests a minute per key. Reallyo applies up to 100 listing changes a day per account (unless agreed otherwise); later ones are kept and
pauseduntil midnight UTC, then applied in order. The API refuses changes (429 daily_limit) only past twice the daily limit. - Unusual bulk changes are paused until the account holder confirms them by email: within 24 hours, taking down more than a fifth of the account's available rentals (at least 10), adding many listings in states where it had none, or changing rents by more than half on many listings. Only those changes wait, with any later change to the same listings; your other changes go on. Once confirmed, they are applied in order.
Example
curl -X POST https://listings-api.reallyo.com/v1/listings \
-H "Authorization: Bearer $REALLYO_API_KEY" -H "Content-Type: application/json" \
-d '{"external_id":"UNIT-12B","mls_id":"A12012329",
"status":"available","offer_type":"rent","price":2450,"bedrooms":2,"bathrooms":1,
"description":"Bright two-bedroom with in-unit laundry, two blocks from the subway…",
"address":{"street_number":"222","street":"East 39th Street","unit":"12B",
"city":"New York","state_code":"NY","postcode":"10016"},
"available_from":"2026-11-01","pets":{"cats":true},
"photos":[{"url":"https://example.com/12b/living-room.jpg"}]}'
curl -X PATCH https://listings-api.reallyo.com/v1/listings/4100001 \
-H "Authorization: Bearer $REALLYO_API_KEY" -H "Content-Type: application/json" \
-d '{"external_id":"UNIT-3"}'Endpoints
GET /v1/me | Plan, listing limit, available rentals, limit remaining |
GET /v1/listings | Every listing on your account (dashboard and API), each with id, external_id, status, last_change and a summary (address, unit, price, bedrooms, photo count). Search with ?q=222 E 39th 12B; filter with ?bedrooms=, ?status=, ?last_change=; page with ?after= |
POST /v1/listings | Create a listing (the only way); returns Reallyo's id. Optional: external_id, mls_id, header Idempotency-Key |
GET /v1/listings/{id}GET /v1/listings/external_id/{external_id} | The whole listing (every field, photos as URLs), its status and last_change |
PATCH /v1/listings/{id}PATCH /v1/listings/external_id/{external_id} | Change some fields, e.g. {"status":"rented"}; {"external_id":"…"} gives the listing your own id |
DELETE /v1/listings/{id}DELETE /v1/listings/external_id/{external_id} | Take down (kept, never deleted) |
GET · PATCH · DELETE /v1/listings/mls_id/{mls_id} | The same, by MLS number (URL-encoded). GET /v1/listings?mls_id= filters by it. |
POST /v1/listings/validate | Check without storing |
Listing fields
status | "available" | "coming_soon" | "pending" | "rented" | "sold" | "draft" | "available" is on the market and published by Reallyo (counts towards your plan's listing limit). "coming_soon"/"pending" show on your Reallyo pages only. "rented"/"sold" take it off the market; "draft" keeps it private. default "available" |
offer_type | "rent" | "sale" | default "rent" |
title | string | Optional. Generated from the address and size when omitted. |
description | string | The listing text renters see. Required for "available". default "" |
address required | object | The property address. US only. |
address.street_number | string | House or building number, e.g. "222". default "" |
address.street required | string | Street name, e.g. "East 39th Street". |
address.unit | string | Apartment or unit, e.g. "16B". Empty for a whole house. default "" |
address.city required | string | |
address.state_code required | string | Two-letter US state code, e.g. "NY". |
address.postcode required | string | US ZIP code. |
address.neighborhood | string | default "" |
address.hide_street_number | boolean | Publish the street without the house number. realtor.com and apartments.com refuse such listings. default false |
latitude | number | |
longitude | number | |
price | number | Monthly rent (rent) or asking price (sale), in USD. Required for "available". |
bedrooms | integer | 0 for a studio. |
bathrooms | number | Half baths as .5, e.g. 1.5. |
square_feet | integer | |
property_type | "apartment" | "assisted living" | "barn" | "bungalow" | "cabin" | "castle" | "co-op" | "condo" | "cottage" | "detached house" | "duplex" | "farm" | "flat" | "fourplex" | "high-rise" | "house" | "houseboat" | "land" | "loft" | "maisonette" | "manufactured" | "mid-rise" | "mobile" | "multi-family home" | "penthouse" | "semi-detached house" | "senior housing" | "single-family home" | "studio" | "terraced house" | "townhouse" | "triplex" | "villa" | "windmill" | default "apartment" |
year_built | integer | |
available_from | string | string | "now", or the date the property becomes available. default "now" |
lease_term | "1_year" | "6_months" | "monthly" | "rent_to_own" | "variable" | Rentals only. default "1_year" |
pets | object | Rentals only. Which pets are allowed. default {"cats":false,"small_dogs":false,"large_dogs":false} |
pets.cats | boolean | default false |
pets.small_dogs | boolean | default false |
pets.large_dogs | boolean | default false |
furnished | boolean | Rentals only. default false |
smoking_allowed | boolean | Rentals only. default false |
utilities_included | array | Rentals only. default [] |
photos | array | In display order; the first is the cover. At least one is required for "available". We copy each photo to our CDN — your URL only has to work when you send it. We copy each link once; to change a photo, send it at a new link. default [] |
photos[].url required | string | A publicly reachable JPEG, PNG, GIF or WebP, up to 50 MB. |
photos[].caption | string | default "" |
videos | array | YouTube, Vimeo or Wistia links. Others are dropped. default [] |
mls_id | string | default "" |
Status
available | On the market: shown on Reallyo, which decides which portals it goes to. A rental counts towards your plan's listing limit. |
coming_soon · pending | Shown on your Reallyo pages; not sent to the portals and not counted against your listing limit. |
rented · sold · draft | On Reallyo, not sent to the portals. |
removed | Taken down (kept, never deleted). Left out of GET /v1/listings unless you ask for ?status=removed. |
last_change
What happened to the latest change you sent for the listing: result, message (what to do), checks, received_at, processed_at. Null for a listing never changed through the API.
queued | Accepted and stored, waiting to be applied. Until then, status and listing show the version you sent. |
paused | Accepted and stored, but waiting: past today's daily limit (applied after midnight UTC), or an unusual bulk change waiting for the account holder's confirmation. See message. |
applied | Done: status and listing show what Reallyo now holds. |
held | Not applied as sent: your plan's listing limit, contact details in the description, or a photo that could not be copied. See message. |
failed | Not applied; see message. |
Questions: hello@reallyo.com