Skip to content
Scrappa Get API key
QuintoAndar API 1 credit/request

QuintoAndar Search API Documentation

GET https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10

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.

QuintoAndar Search API Documentation 1 credit/request

Endpoint

Request preview
GET
https://scrappa.co/api/quintoandar/search?business=RENT&location=curitiba-pr-brasil&bedrooms=2&price_max=3000&sort=price_asc&rows=10
Auth header
x-api-key
Cost
1 credit/request
business = RENT location = curitiba-pr-brasil
Response preview
200 OK
{
    "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",
...

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.

business string Required

RENT or SALE.

Example value RENT
location string Required

Location slug from autocomplete (curitiba-pr-brasil) or a plain city name.

Example value curitiba-pr-brasil
price_min number Optional

Minimum rent (RENT) or sale price (SALE) in BRL.

Example value 10
price_max number Optional

Maximum rent (RENT) or sale price (SALE) in BRL.

Example value 3000
bedrooms integer Optional

Minimum bedrooms. Add bedrooms_max for an exact count.

Example value 2
bathrooms integer Optional

Minimum bathrooms. Add bathrooms_max for an exact count.

Example value 10
parking_spaces integer Optional

Minimum parking spaces.

Example value 10
suites integer Optional

Minimum suites.

Example value 10
area_min number Optional

Minimum area in square metres.

Example value 10
area_max number Optional

Maximum area in square metres.

Example value 10
property_type string Optional

Comma list of apartment, studio, house, house_condominium.

Example value example
furnished string Optional

true for furnished only, false for unfurnished only.

Example value example
amenities string Optional

Comma list of amenity keys from the filters endpoint. A listing must have all of them.

Example value example
installations string Optional

Comma list of building installation keys from the filters endpoint. A listing must have all of them.

Example value example
availability string Optional

ANY (default) or IMMEDIATE.

Example value example
origin string Optional

HYBRID (default), TRANSACTIONAL or CLASSIFIED.

Example value example
sort string Optional

relevance (default), price_asc, price_desc, newest or highest_rent (SALE only).

Example value price_asc
rows integer Optional

Listings per page, 1-500 (default 24). page x rows must stay at or below 1000.

Example value 10
page integer Optional

Result page, 1-based.

Example value 1

Request Examples

PHP
<?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
<?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();
}
JavaScript
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));
JavaScript
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);
}
Ruby
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
Python
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()
Python
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}")
Java
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());
        }
    }
}
Go
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))
}
Terminal
#!/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"
C#
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}");
        }
    }
}
TypeScript
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();
RUST
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
JSON Response
200 OK
{
    "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.

422

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
}
422

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."
}
503

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.