Download OpenAPI specification:openapi.json
Catalog, rates, availability, locations and inquiries for Rental Escapes partners.
Get a test key. Email partner support for a key starting re_test_. It reads the real catalog,
rates and availability, and lets you send inquiries that are checked but never created, so nobody is
contacted while you build.
Make a first call. Send the key in the X-RE-API-TOKEN header:
curl -H "X-RE-API-TOKEN: re_test_..." "https://api.rentalescapes.com/v2/properties?per_page=5"
Load the catalog once. Page through GET /properties (up to 200 per page, follow
pagination.next). For each property, fetch what you need: GET /properties/{id} for content,
/rates, /availability and /images. Store each property's updated times.
Stay in sync. At most hourly, call GET /properties/changes?since=<start of your previous run>.
Re-fetch only the areas whose time moved, and drop properties reported as removed.
Price and send leads. GET /properties/{id}/quote prices a stay. POST /inquiries hands a guest
to a reservations agent; with a test key the response says "test": true and nothing is created.
Go live. Ask for a live key (starts re_live_) and swap it in. Nothing else changes: same URL,
same responses.
Prefer a client? Import the OpenAPI document into your tools, or use the Postman collection with its test and live environments.
Every request carries the X-RE-API-TOKEN header. Keys have scopes: properties:read and
locations:read allow GET, inquiries:write allows POST /inquiries. A key may be limited to an
allow-list of properties; everything outside it behaves as if it did not exist (404, or an
unknown-property error on inquiries). Keep keys on your servers, never in a browser or mobile app.
Test mode. Keys starting re_test_ use the same URL and see the real catalog, rates and
availability, but POST /inquiries only validates: it returns the normal response with
"test": true and creates nothing. Every response to a partner key carries X-RE-Mode: test or
X-RE-Mode: live.
Every error has the same body:
{ "error": { "code": "validation_failed", "message": "Invalid inquiry.",
"validation": { "stay.checkin": "Must not be in the past." },
"request_id": "req_7f3a9c11e2b04d5a6c8e9f01" } }
Branch on code, which is stable: validation_failed, invalid_request, unauthorized,
forbidden, not_found, method_not_allowed, rate_limited, internal_error. message is for
people and may change. Every response carries an X-Request-Id header; send your own (8-64 of
A-Za-z0-9._-) to have it reused, and quote it when you contact us.
Per key, test and live alike: about 600 requests a minute and 10,000 an hour, and about 60
POST /inquiries per 10 minutes. Over a limit you get 429 with code: rate_limited and a
Retry-After header: wait that long, then retry. A 429 never creates anything, so retrying an
inquiry is safe. After the first full load, sync with GET /properties/changes rather than
re-reading the catalog.
The version is in the path (/v2). Within a version we only make additive changes:
type.Build your client to ignore fields it does not know and to handle unknown enum values gracefully.
Breaking changes (removing or renaming a field, changing a type, making a parameter required, changing authentication) only ship in a new version. We announce a new version at least 90 days ahead by email to every partner, and keep the previous version running for at least 6 months after it launches.
1.0.0 (October 2026). First release: property catalog and detail, rates, availability, photos, quotes, the change feed, the location catalog, property and general inquiries, and test-mode keys.
Paginated catalog of live properties (limited to the allow-list for restricted keys). Poll with updated_since for incremental sync.
| page | integer >= 1 Default: 1 Page number, from 1. |
| per_page | integer [ 1 .. 200 ] Default: 50 Page size. |
| updated_since | string <date-time> Only properties changed at or after this instant (ISO 8601). |
| location | integer Location id from GET /locations; matches the location and every descendant. |
| sort | string Default: "id" Enum: "id" "-id" "bedrooms" "-bedrooms" "sleeps" "-sleeps" "updated" "-updated" Sort field; prefix with - for descending. |
| checkin | string <date> With checkout: only properties free for the whole stay. |
| checkout | string <date> With checkin. |
| guests | integer >= 1 Minimum sleeps. |
| rooms | integer >= 1 Minimum bedrooms. |
required | Array of objects (PropertySummary) |
required | object (Pagination) |
{- "properties": [
- {
- "id": 117388,
- "name": "Necker Island",
- "type": "villa",
- "updated_at": "2019-08-24T14:15:22Z",
- "updated": {
- "content": "2019-08-24T14:15:22Z",
- "rates": "2019-08-24T14:15:22Z",
- "availability": "2019-08-24T14:15:22Z",
- "images": "2019-08-24T14:15:22Z"
}, - "bedrooms": 24,
- "bathrooms": 20,
- "sleeps": 48,
- "rating": 4.8,
- "latitude": 18.44104,
- "longitude": -77.98475,
- "location": {
- "id": 213,
- "name": "Necker Island",
- "path": [
- "Caribbean",
- "British Virgin Islands (BVI)",
- "Necker Island"
],
}, - "image": {
- "caption": "Infinity pool at sunset",
- "sizes": {
}
}
}
], - "pagination": {
- "page": 1,
- "per_page": 50,
- "total": 3970,
- "total_pages": 80,
- "next": "/properties?per_page=50&page=2"
}
}Lightweight change log for incremental sync. Without since, every live property with its area change times. With since, only live properties that changed in some area at or after it, plus properties that left the catalog after it (status: removed) so you can drop them. Refreshed hourly: poll no more often than that and pass the time of your previous run as since.
| since | string <date-time> Only changes at or after this instant (ISO 8601). |
| page | integer >= 1 Default: 1 Page number, from 1. |
| per_page | integer [ 1 .. 1000 ] Default: 500 Page size. |
required | Array of objects or objects (PropertyChange) |
required | object (Pagination) |
{- "changes": [
- {
- "id": 126859,
- "status": "live",
- "updated": {
- "content": "2019-08-24T14:15:22Z",
- "rates": "2019-08-24T14:15:22Z",
- "availability": "2019-08-24T14:15:22Z",
- "images": "2019-08-24T14:15:22Z"
}, - "removed_at": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "page": 1,
- "per_page": 50,
- "total": 3970,
- "total_pages": 80,
- "next": "/properties?per_page=50&page=2"
}
}Everything shown on the property page: the catalog summary (the same shape as GET /properties) plus descriptions, rooms and beds, amenities, policies and reviews. Rates, availability and photos have their own endpoints. Re-fetch when updated.content changes.
| id required | integer >= 1 Example: 553 Property id from the catalog. |
| id required | integer |
| name required | string |
| type required | string |
| url required | string <uri> Public page on rentalescapes.com. |
| updated_at required | string <date-time> Last change of any kind, UTC. Use with |
required | object (AreaUpdates) Last change to each area of the property, UTC, refreshed hourly. Re-fetch only the areas that moved: |
| bedrooms required | integer |
| bathrooms required | integer |
| sleeps required | integer |
| rating required | number or null Average review rating out of 5, one decimal. |
| latitude required | number or null |
| longitude required | number or null |
required | object (LocationRef) |
required | object or null Cover photo, or null when none is uploaded. |
| description required | string or null HTML. |
| location_description required | string or null |
required | Array of objects |
| amenity_notes required | string or null HTML. |
| staff required | Array of strings |
| inclusions required | string or null |
| house_rules required | string or null |
required | object |
required | object null when the owner has not said. |
required | object |
required | Array of objects Approved guest reviews, newest first. |
{- "id": 117388,
- "name": "Necker Island",
- "type": "villa",
- "updated_at": "2019-08-24T14:15:22Z",
- "updated": {
- "content": "2019-08-24T14:15:22Z",
- "rates": "2019-08-24T14:15:22Z",
- "availability": "2019-08-24T14:15:22Z",
- "images": "2019-08-24T14:15:22Z"
}, - "bedrooms": 24,
- "bathrooms": 20,
- "sleeps": 48,
- "rating": 4.8,
- "latitude": 18.44104,
- "longitude": -77.98475,
- "location": {
- "id": 213,
- "name": "Necker Island",
- "path": [
- "Caribbean",
- "British Virgin Islands (BVI)",
- "Necker Island"
],
}, - "image": {
- "caption": "Infinity pool at sunset",
- "sizes": {
}
}, - "description": "<p>A secluded nine-bedroom estate on the cliffs above Montego Bay, with an infinity pool and full staff.</p>",
- "location_description": "Ten minutes from Sangster International Airport, near Rose Hall.",
- "amenities": [
- {
- "category": "General",
- "items": [
- "Pool",
- "Wifi"
]
}
], - "amenity_notes": "<p>Daily housekeeping; chef available on request.</p>",
- "staff": [
- "Chef",
- "House Manager"
], - "inclusions": "Breakfast and daily housekeeping included.",
- "house_rules": "No events without approval. Quiet hours after 11pm.",
- "rooms": {
- "bedrooms": [
- {
- "name": "Master suite",
- "type": null,
- "sleeps": 0,
- "beds": {
- "king": 0,
- "queen": 0,
- "double": 0,
- "single": 0,
- "bunk": 0,
- "sofa_bed": 0,
- "crib": 0,
- "child": 0
}, - "notes": "Ocean view, private terrace."
}
], - "bathrooms": [
- {
- "name": "Master bathroom",
- "type": "full",
- "features": [
- "toilet"
], - "notes": "Outdoor rain shower."
}
], - "bedroom_notes": null,
- "bathroom_notes": null
}, - "policies": {
- "children": "yes",
- "pets": "yes",
- "smoking": "yes",
- "events": "yes",
- "seniors": "yes",
- "wheelchair_accessible": "yes",
- "long_term": "yes"
}, - "arrival": {
- "checkin_time": "15:00",
- "checkout_time": "12:00",
- "notes": "The property manager meets guests on arrival."
}, - "reviews": [
- {
- "author": "Sarah M.",
- "date": "2026-03-14",
- "title": "Perfect family week",
- "text": "The staff were wonderful and the views even better than the photos.",
- "rating": 5
}
]
}Seasonal rate periods, the default rate, fees, taxes and rate notes: the inputs to a quote.
| id required | integer >= 1 Example: 553 Property id from the catalog. |
| from | string <date> Exclude periods ending before this date. Default today. |
| to | string <date> Exclude periods starting after this date. Default open. |
| property_id required | integer |
required | object |
| from required | string <date> Start of the window returned. |
| to required | string or null <date> End of the window returned, or null when open-ended. |
required | Array of objects Seasonal periods. Several periods can share dates for different bedroom counts; use the smallest |
required | object or null Fallback when no period covers a date. No dates. |
required | Array of objects |
required | Array of objects |
| notes required | string or null Free-text rate notes; may contain HTML. |
{- "property_id": 553,
- "currency": {
- "code": "USD",
- "symbol": "$"
}, - "from": "2026-10-05",
- "to": null,
- "rates": [
- {
- "id": 90412,
- "name": "Low Season: 1 - 7 people",
- "start_date": "2027-04-15",
- "end_date": "2027-12-14",
- "rooms": 4,
- "nightly": 2853,
- "weekly": 0,
- "monthly": 0,
- "min_stay": 5,
- "balance_days": 60,
- "currency": "USD",
- "cancellation_policy": {
- "name": "Standard",
- "description": "Deposit refundable until 60 days before arrival, less a 10% fee."
}
}
], - "default_rate": {
- "id": 90400,
- "name": "Default",
- "rooms": 9,
- "nightly": 4250,
- "weekly": null,
- "monthly": null,
- "min_stay": 5,
- "balance_days": 60,
- "currency": "USD"
}, - "fees": [
- {
- "name": "Damage Waiver",
- "description": "Covers accidental damage up to $2,500.",
- "amount": 299,
- "currency": "USD",
- "type": "flat",
- "type_text": "per night",
- "refundable": true,
- "taxable": true
}
], - "taxes": [
- {
- "name": "General Consumption Tax",
- "rate": 10,
- "description": null
}
], - "notes": "Holiday weeks (Dec 20 - Jan 5) require a 7-night minimum."
}GET /properties/{id}/availability — booked date ranges for one property.
| id required | integer >= 1 Example: 553 Property id from the catalog. |
| from | string <date> Window start. Default today. |
| to | string <date> Window end. Default from + 2 years. |
| property_id required | integer |
| from required | string <date> Start of the window returned. |
| to required | string <date> End of the window returned. |
required | Array of objects Each range blocks the nights from checkin up to, not including, checkout. Ranges straddling the window are included whole. |
{- "property_id": 553,
- "from": "2026-10-05",
- "to": "2028-10-05",
- "booked": [
- {
- "checkin": "2026-12-20",
- "checkout": "2027-01-03",
- "checkin_full_day": true,
- "checkout_full_day": true,
- "status": "confirmed"
}
]
}GET /properties/{id}/images — full photo gallery for one property.
| id required | integer >= 1 Example: 553 Property id from the catalog. |
| property_id required | integer |
required | Array of objects In display order; the first is the cover. |
{- "property_id": 553,
- "images": [
- {
- "id": 48211,
- "position": 1,
- "caption": "Infinity pool at sunset",
- "sizes": {
}, - "width": 1920,
- "height": 1080
}
]
}Authoritative total for a specific stay, including fees, taxes and discounts.
| id required | integer >= 1 Example: 553 Property id from the catalog. |
| checkin required | string <date> Today or later. |
| checkout required | string <date> After checkin. |
| adults | integer [ 1 .. 50 ] Default: 2 Adults in the party. Used for capacity and for per-adult and per-guest fees. |
| children | integer [ 0 .. 50 ] Default: 0 Children in the party. They count toward capacity and per-guest fees, and per-child fees use this number. |
| bedrooms | integer [ 1 .. 50 ] Bedrooms to price; raised to fit the guests at two per room. |
| property_id required | integer |
required | object |
| price_on_request required | boolean |
required | object |
required | object or null |
| average_nightly_rate required | number or null |
| tax_rate required | number or null Combined tax percentage. |
| accuracy required | string or null Enum: "exact" "estimated" "incomplete" null
|
required | object or null |
{- "property_id": 553,
- "currency": {
- "code": "USD",
- "symbol": "$"
}, - "price_on_request": false,
- "stay": {
- "checkin": "2026-12-20",
- "checkout": "2026-12-27",
- "nights": 7,
- "guests": {
- "adults": 4,
- "children": 1
}, - "bedrooms": 3
}, - "totals": {
- "rate": 26901,
- "discounts": 0,
- "fees": 299,
- "taxes": 2690.1,
- "total": 29890.1,
- "refundable_deposits": 0,
- "total_payable": 29890.1
}, - "average_nightly_rate": 3843,
- "tax_rate": 10,
- "accuracy": "exact",
- "rate_range": {
- "min": 2853,
- "max": 4250
}
}Flat catalog of every location with live properties beneath it (counted within the allow-list for restricted keys). About 800 rows; refresh daily. Needs locations:read.
required | Array of objects Every location with live properties beneath it, ordered by path so a parent precedes its children. |
{- "locations": [
- {
- "id": 144,
- "parent_id": 16,
- "name": "St. James",
- "path": [
- "Caribbean",
- "Barbados",
- "St. James"
], - "property_count": 185
}
]
}Hands a stay request for the guest in contact to a reservations agent, who follows up by email. The inquiry is tagged with your partner source and, if your key has one, credited to your travel advisor, which carries to the booking. Needs inquiries:write. Property rules the agent enforces, such as a minimum stay or maximum guests, return 400 with a plain message and no field map.
| property_id | integer A live property from the catalog. |
object General inquiry: a catalog location id, free text, or both (the text is kept as a note). | |
required | object |
object Nightly budget, general inquiries only. | |
required | object The traveller the stay is for, not the advisor. A returning guest is recognised by email. The inquiry is attributed to your organisation through your API key; put the advisor handling the trip in |
| message | string <= 5000 characters Requests, and anything the agent should know, such as the advisor handling the trip. |
| reference | string <= 255 characters Your own id for this lead; stored and echoed back. |
| id required | integer |
| status required | string Value: "new" Always |
| test required | boolean True when sent with a |
| created_at required | string <date-time> |
| reference required | string or null Your |
required | object or null |
required | object or null
|
required | object or null |
required | object |
required | object |
required | object The Rental Escapes reservations agent who owns the lead. |
{- "property_id": 553,
- "destination": {
- "id": 144,
- "name": "west coast, near Sandy Lane"
}, - "stay": {
- "checkin": "2026-12-20",
- "checkout": "2026-12-27",
- "guests": {
- "adults": 4,
- "children": 1
}, - "bedrooms": 3
}, - "budget": {
- "min": 1500,
- "max": 4000
}, - "contact": {
- "first_name": "Ada",
- "last_name": "Lovelace",
- "email": "ada@example.com",
- "phone": "+1 514 555 0100"
}, - "message": "Celebrating an anniversary; private chef for two dinners. Advisor: Jane Smith, jane@agency.example",
- "reference": "trip-991"
}{- "id": 221345,
- "status": "new",
- "test": false,
- "created_at": "2026-10-05T14:02:11Z",
- "reference": "trip-991",
- "property": {
- "id": 553,
- "name": "Silent Waters Villa",
}, - "destination": {
- "id": 144,
- "name": "St. James",
- "path": [
- "Caribbean",
- "Barbados",
- "St. James"
]
}, - "budget": {
- "min": 1500,
- "max": 4000
}, - "stay": {
- "checkin": "2026-12-20",
- "checkout": "2026-12-27",
- "nights": 7,
- "guests": {
- "adults": 4,
- "children": 1
}, - "bedrooms": 3
}, - "contact": {
- "first_name": "Ada",
- "last_name": "Lovelace",
- "email": "ada@example.com"
}, - "agent": {
- "first_name": "Maria",
- "last_name": "Lopez",
- "email": "maria@rentalescapes.com",
- "phone": "1-800-208-5097",
- "extension": "826"
}
}