REST API
Read-only, JSON, open to calls from the browser. Field names are stable: an incompatible change would ship as a new version.
Base URL
https://www.deveras.app/api/v1Access and keys
You do not need a key to start. With a key the limit is higher and you can follow your usage. Send it in the Authorization: Bearer … header or in x-api-key.
curl -H "Authorization: Bearer $API_KEY" \
"https://www.deveras.app/api/v1/listings?city=playa-del-carmen"Your key is secret: use it from your server, never in code that reaches the browser. If it leaks, revoke it and create another.
Limits and caching
- Without a key: 60 requests per minute per IP address.
- With a key: 600 requests per minute per key.
- Above the limit we answer
429with aRetry-Afterheader (seconds to wait). With a key, every response includesX-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Reset. - Responses can be cached for 60 seconds (
Cache-Control). Listings do not change often: keep the responses and save requests.
Response shape
Every successful response has data (the result) and attribution (the mention you must display). Lists add pagination, with links to the previous and next page, also sent in the Link header.
{
"data": [
{
"id": "k7m2x9p",
"url": "https://www.deveras.app/en/p/bright-two-bedroom-near-the-beach-k7m2x9p",
"title": "Bright two-bedroom near the beach",
"language": "en",
"type": "apartment",
"operation": "rent",
"terms": [
"long",
"mid"
],
"price": {
"amount": 1200,
"currency": "USD",
"amount_mxn": 21960,
"period": "month"
},
"sale": null,
"bedrooms": 2,
"bathrooms": 1.5,
"area_m2": 78,
"land_m2": null,
"furnished": true,
"pets_allowed": false,
"amenities": [
"pool",
"ac",
"wifi"
],
"location": {
"city": {
"slug": "playa-del-carmen",
"name": "Playa del Carmen"
},
"zone": {
"slug": "centro",
"name": "Centro"
},
"coordinates": {
"lat": 20.627,
"lng": -87.074,
"precision": "approximate"
}
},
"photos": [
{
"url": "https://www.deveras.app/media/public/listings/k7m2x9p/1.jpg",
"width": 1600,
"height": 1200,
"alt": "Living room",
"room": "living"
}
],
"advertiser": {
"handle": "ana-lopez",
"name": "Ana López",
"role": "owner",
"agency_name": null,
"avatar_url": null,
"trust_score": 82,
"reviews": {
"count": 4,
"average": 4.75
},
"verifications": [
{
"kind": "email",
"verified_at": "2026-01-05T10:00:00.000Z"
},
{
"kind": "identity",
"verified_at": "2026-03-02T10:00:00.000Z"
}
],
"url": "https://www.deveras.app/en/u/ana-lopez"
},
"verifications": [
{
"kind": "ownership",
"verified_at": "2026-04-01T10:00:00.000Z"
}
],
"shares_commission": false,
"demo": false,
"published_at": "2026-06-10T15:00:00.000Z",
"availability_confirmed_at": "2026-10-01T12:00:00.000Z"
}
],
"pagination": {
"page": 1,
"per_page": 24,
"total": 1,
"pages": 1,
"links": {
"self": "https://www.deveras.app/api/v1/listings?city=playa-del-carmen&beds=2&max=25000",
"first": "https://www.deveras.app/api/v1/listings?city=playa-del-carmen&beds=2&max=25000",
"last": "https://www.deveras.app/api/v1/listings?city=playa-del-carmen&beds=2&max=25000",
"prev": null,
"next": null
}
},
"attribution": {
"text": "Listings from Deveras",
"url": "https://www.deveras.app/en",
"license_url": "https://www.deveras.app/en/developers/license",
"notice": "Free to reuse, including commercially, as long as you show this mention visibly and link each listing to its `url`. Do not remove verification context or the demo flag, and do not publish contact details."
}
}Good to know about the fields
- url
- The listing’s page on Deveras. It is the required link in any reuse.
- price
amountis in the listing’s currency (currency);amount_mxnis the same price in pesos. Theminandmaxfilters and price sorting use pesos.- sale
- Sales only (
operation: sale,price.period: total): pre-sale, delivery, title type, HOA fee and price per m².nullfor rentals. - location.coordinates
precisionisexactorapproximate. When approximate, the point is offset on purpose: draw an area, not a pin. It can benull.- verifications
- The proofs checked by the platform, with their kind and date. On the listing they are about the property; under
advertiser, about the person. An empty list means “not verified”. - demo
trueon demonstration data, which is not a real listing. Left out unless you ask fordemo=1.- locale
locale=es,enorfrpicks the language of titles, descriptions and links. Without a translation you get the original text (languagetells you which).
What we never return
Exact address, phone, WhatsApp, email, identity documents, internal identifiers and unpublished listings. Nor tenant profiles. If a free-text field contains a phone number or an email address, we hide it.
Endpoints
Search listings
GET/api/v1/listings
Published listings, most recent first, with the same filters as the site search. Rentals by default; sales with operation=sale.
- operationstring — optional — rent · sale — default: rent
rent(the default) orsale. A search returns one or the other, never both.- citystring — optional
- City (slug from
/places). Without it, every city is searched. - zonestring — optional
- Zone inside the city. Requires
city. - typestring — optional — apartment · house · studio · room · villa · commercial · land
- Property type.
- bedsinteger — optional
- Minimum number of bedrooms.
- bathsinteger — optional
- Minimum number of bathrooms.
- mininteger — optional
- Minimum price in pesos (MXN): the rent, or the total price of a sale.
- maxinteger — optional
- Maximum price in pesos (MXN): the rent, or the total price of a sale.
- furnishedboolean — optional
1for furnished listings only.- petsboolean — optional
1for listings that accept pets only. Rentals only.- termstring — optional — long · mid · short
- Term:
long(12 months or more),mid(1 to 11 months) orshort(nightly or weekly). Rentals only. - amenitiesstring[] — optional — pool · gym · ac · parking · rooftop · security · washer · elevator · cowork · balcony · garden · kitchen · wifi · tv · beach_walk · generator · cistern · storage · bbq · jacuzzi
- Amenities the listing must all have, separated by commas.
- verifiedboolean — optional
1for advertisers with a verified identity only.- qstring — optional
- Free text, searched in the title and the description.
- advertiserstring — optional
- Only this profile’s listings.
- sortstring — optional — recent · price_asc · price_desc — default: recent
- Order:
recent,price_ascorprice_desc. - pageinteger — optional — default: 1
- Page number, starting at 1.
- per_pageinteger — optional — default: 24
- Listings per page.
- demoboolean — optional — default: 0
1to include demonstration data (flagged withdemo: true).- localestring — optional — es · en · fr — default: es
- Language of texts and links:
es,enorfr.
curl "https://www.deveras.app/api/v1/listings?city=playa-del-carmen&beds=2&max=25000&furnished=1"const response = await fetch("https://www.deveras.app/api/v1/listings?city=playa-del-carmen&beds=2&max=25000");
const { data, pagination, attribution } = await response.json();
for (const listing of data) {
// listing.url is the page of the listing: always link to it.
console.log(listing.title, listing.price.amount, listing.price.currency, listing.url);
}
// Show attribution.text, linked to attribution.url, wherever you display the listings.
console.log(attribution.text, attribution.url, pagination.total);Get a listing
GET/api/v1/listings/{shortId}
The full listing: description, every photo, conditions, what is included, distances and verifications.
- shortIdstring
- Listing id (the
idfield). - demoboolean — optional — default: 0
1to include demonstration data (flagged withdemo: true).- localestring — optional — es · en · fr — default: es
- Language of texts and links:
es,enorfr.
curl "https://www.deveras.app/api/v1/listings/k7m2x9p?locale=en"Cities and zones
GET/api/v1/places
Cities and their zones, with the slugs used by the city and zone filters and the number of listings for rent (listing_count) and for sale (sale_count).
- demoboolean — optional — default: 0
1to include demonstration data (flagged withdemo: true).- localestring — optional — es · en · fr — default: es
- Language of texts and links:
es,enorfr.
curl "https://www.deveras.app/api/v1/places"An advertiser’s public profile
GET/api/v1/profiles/{handle}
Name, role, trust score, reviews and verified proofs of an owner or agent.
- handlestring
- Profile handle (the
advertiser.handlefield). - demoboolean — optional — default: 0
1to include demonstration data (flagged withdemo: true).- localestring — optional — es · en · fr — default: es
- Language of texts and links:
es,enorfr.
curl "https://www.deveras.app/api/v1/profiles/ana-lopez"Errors
Errors use the usual HTTP status and always the same shape. Rely on code, which is stable; message is for you.
{
"error": {
"code": "invalid_parameter",
"message": "One or more parameters are invalid.",
"status": 400,
"details": [
{
"param": "beds",
"message": "Invalid input: expected number, received string"
}
],
"docs_url": "https://www.deveras.app/en/developers/api"
}
}- invalid_parameterHTTP 400
- A parameter is missing, unknown or has an invalid value.
detailssays which one. - invalid_api_keyHTTP 401
- The key does not exist, is revoked or is malformed.
- not_foundHTTP 404
- The route does not exist.
- listing_not_foundHTTP 404
- No published listing has this id.
- profile_not_foundHTTP 404
- No public advertiser profile has this handle.
- place_not_foundHTTP 404
- The city or zone does not exist. See
/places. - advertiser_not_foundHTTP 404
- The profile given in
advertiserdoes not exist. - method_not_allowedHTTP 405
- The API is read-only: use
GET. - rate_limitedHTTP 429
- Too many requests. Wait for the time given in
Retry-After. - internal_errorHTTP 500
- Something failed on our side. Please retry.
OpenAPI document
The full description of the API in OpenAPI 3.1 is generated from the same definitions the server uses, so it is always up to date. Use it to generate a client or import it into your favorite tool.