Scrappa's GET /api/quintoandar/search returns QuintoAndar listings for rent or sale in Brazil as structured JSON.
What you get
One request returns one page of listings, the total match count and the location the search resolved to. Each listing has prices (rent_price, sale_price, total_cost, fees), area, rooms, address, coordinates, photos, amenities and installations. origin says whether QuintoAndar manages the listing (TRANSACTIONAL) or a partner publishes it (CLASSIFIED). Pass it to the property endpoint.
Filters are honoured
Every returned listing is checked against the filters you sent. About 3 percent of upstream rows are mislabelled (for example a rent search returning a sale-only listing). Those rows are removed, so a page can hold fewer than rows listings. The count removed is in meta.filtered_out. Pages are never padded. total is the platform count before this check. applied_filters echoes what was applied.
Location
location takes a slug from the autocomplete endpoint (curitiba-pr-brasil, pinheiros-sao-paulo-sp-brasil) or a plain city name that is unique in Brazil. An unknown slug returns a 422, never a wider region.
Pagination window
Only the first 1000 results of a query are reachable: page x rows must stay at or below 1000, and rows at or below 500. A deeper page, or a page past the last result, returns a non-billable 422 (page_out_of_range). Split large areas with price or neighbourhood filters.
Sort
relevance (default), price_asc and price_desc (total monthly cost for rent), newest, and highest_rent (SALE only, highest rental return).
What this API does not cover
Public listing data only. Contact details, lead references and agent accounts are not available. Free-text address search, new-build developments and map search are not available yet.
Run this endpoint
Endpoint
Parameters
Start with the required fields, then add optional filters only when your use case needs them.
Runnable path
2 required parameters needed before sending a request.
17 optional filters available.
string
Required
RENT or SALE.
RENT
string
Required
Location slug from autocomplete (curitiba-pr-brasil) or a plain city name.
curitiba-pr-brasil
number
Optional
Minimum rent (RENT) or sale price (SALE) in BRL.
10
number
Optional
Maximum rent (RENT) or sale price (SALE) in BRL.
3000
integer
Optional
Minimum bedrooms. Add bedrooms_max for an exact count.
2
integer
Optional
Minimum bathrooms. Add bathrooms_max for an exact count.
10
integer
Optional
Minimum parking spaces.
10
integer
Optional
Minimum suites.
10
number
Optional
Minimum area in square metres.
10
number
Optional
Maximum area in square metres.
10
string
Optional
Comma list of apartment, studio, house, house_condominium.
example
string
Optional
true for furnished only, false for unfurnished only.
example
string
Optional
Comma list of amenity keys from the filters endpoint. A listing must have all of them.
example
string
Optional
Comma list of building installation keys from the filters endpoint. A listing must have all of them.
example
string
Optional
ANY (default) or IMMEDIATE.
example
string
Optional
HYBRID (default), TRANSACTIONAL or CLASSIFIED.
example
string
Optional
relevance (default), price_asc, price_desc, newest or highest_rent (SALE only).
price_asc
integer
Optional
Listings per page, 1-500 (default 24). page x rows must stay at or below 1000.
10
integer
Optional
Result page, 1-based.
1
Request Examples
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_KEY_HERE"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
<?php
use Illuminate\Support\Facades\Http;
$response = Http::timeout(30)
->withHeaders(['x-api-key' => 'YOUR_API_KEY_HERE'])
->get('https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10');
if ($response->successful()) {
echo $response->body();
} else {
echo "Error: " . $response->status();
}
const options = {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE'
}
};
fetch('https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10', options)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.text();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
const axios = require('axios');
const options = {
method: 'GET',
url: 'https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10',
headers: {
x-api-key: 'YOUR_API_KEY_HERE',
}
};
try {
const response = await axios(options);
console.log(response.data);
} catch (error) {
console.error('Error:', error.message);
}
require 'net/http'
require 'uri'
uri = URI.parse("https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = 'YOUR_API_KEY_HERE'
begin
response = http.request(request)
puts response.body
rescue => e
puts "Error: #{e.message}"
end
import http.client
import json
conn = http.client.HTTPSConnection("scrappa.co")
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
conn.request("GET", "/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
except Exception as e:
print(f"Error: {e}")
finally:
conn.close()
import requests
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
response = requests.get('https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10', headers=headers)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class ApiExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10")
.addHeader("x-api-key", "YOUR_API_KEY_HERE")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println(response.body().string());
} else {
System.out.println("Error: " + response.code());
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("x-api-key", "YOUR_API_KEY_HERE")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(string(body))
}
#!/bin/bash
curl -X GET \
-H "x-api-key: YOUR_API_KEY_HERE" \
"https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10"
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY_HERE");
try
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10"));
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
import axios from 'axios';
async function run(): Promise<void> {
try {
const response = await axios({
method: 'GET',
url: 'https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE',
},
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
}
void run();
use reqwest::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let response = client
.get("https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10")
.header("x-api-key", "YOUR_API_KEY_HERE")
.send()
.await?;
println!("{}", response.text().await?);
Ok(())
}
Response Schema
Example response fields are illustrative; inspect the JSON before integrating.
Example response fields
Scan these fields before integrating.
success
total
total_transactional
total_classified
page
rows
returned
has_more
+4 more
Common listings fields
id
origin
url
for_rent
{
"success": true,
"total": 584,
"total_transactional": 584,
"total_classified": 0,
"page": 1,
"rows": 10,
"returned": 10,
"has_more": true,
"resolved_location": {
"slug": "curitiba-pr-brasil",
"type": "CITY",
"name": "Curitiba",
"city": "Curitiba",
"state_code": "PR",
"formatted_name": "Curitiba - PR",
"latitude": -25.480876,
"longitude": -49.304425
},
"applied_filters": {
"business": "RENT",
"location": "curitiba-pr-brasil",
"sort": "price_asc",
"price_max": 3000,
"bedrooms": 2
},
"listings": [
{
"id": 893892728,
"origin": "TRANSACTIONAL",
"url": "https://www.quintoandar.com.br/imovel/893892728/alugar",
"for_rent": true,
"for_sale": false,
"type": "Apartamento",
"price": 1318,
"rent_price": 1318,
"sale_price": null,
"total_cost": 1913,
"condominium_fee": 500,
"iptu": 42,
"iptu_plus_condominium": 542,
"area": 53,
"bedrooms": 2,
"bathrooms": 1,
"suites": 0,
"parking_spaces": 1,
"is_furnished": false,
"has_elevator": false,
"address": "Rua Rosam\u00e9lia de Oliveira",
"neighbourhood": "Campo Comprido",
"region": "Campo Comprido",
"city": "Curitiba",
"latitude": -25.4582091,
"longitude": -49.3285549,
"cover_image": "https://www.quintoandar.com.br/img/893892728-393.9820271578673IMG9002.jpg",
"images": [
"https://www.quintoandar.com.br/img/893892728-44.647550986580576IMG1315.jpg"
],
"image_captions": [
"Quarto 2"
],
"amenities": [
"CHURRASQUEIRA",
"AREA_DE_SERVICO"
],
"installations": [
"PLAYGROUND",
"SALAO_DE_FESTAS"
],
"condominium": {
"id": 344059,
"name": null
},
"visit_status": "ACCEPT_NEW",
"special_conditions": [
"Exclusivity"
],
"tags": [
"RENT_ON_TERMINATION"
]
}
],
"meta": {
"billable": true,
"attempts": 1,
"last_status": 200,
"endpoint_family": "search",
"filtered_out": 0
}
}
Errors
Handle these documented responses before retrying or showing customer-facing failures.
Unknown Location or Page Too Deep
The location is unknown (`unknown_location`), the filter combination was rejected (`invalid_request`), or the page passes the first 1000 results or the last result (`page_out_of_range`). Non-billable.
{
"meta": {
"billable": false,
"retryable": false,
"endpoint_family": "search"
},
"error": {
"code": "page_out_of_range",
"message": "QuintoAndar returns at most 1000 results per query. Narrow the filters or lower page x rows."
},
"success": false
}Validation Error
A query parameter failed validation or is not supported. Unsupported parameters are rejected instead of ignored. Non-billable.
{
"errors": {
"business": [
"The selected business is invalid."
]
},
"message": "The selected business is invalid."
}Upstream Unavailable
QuintoAndar could not be reached after a retry, or answered with a body this API cannot read (`upstream_unavailable`, `upstream_blocked`, `parser_drift`). Retryable and never billed. Clients are never rate limited.
{
"meta": {
"attempts": 2,
"billable": false,
"retryable": true,
"last_status": 503,
"endpoint_family": "search"
},
"error": {
"code": "upstream_unavailable",
"message": "QuintoAndar is temporarily unavailable. Please retry."
},
"success": false
}Generate Code with AI
Copy a ready-made prompt with all the endpoint details, parameters, and example responses. Paste it into ChatGPT, Claude, or any AI assistant to instantly generate working code.
Try It Live
Test this endpoint in our interactive playground with real data.