Scrappa's GET /api/apartmentlist/search returns Apartment List rentals in one United States location as structured JSON.
Rentals only, United States
Apartment List lists homes for rent. It has no sale listings, so this API has no sale parameter.
What you get
total is the number of matching properties and total_units the number of matching units. Each listing has rental_id, slug, url, name, address, neighborhood, geo, phone, bed_range, price_range, units_available, soonest_available, floorplans with their units (price, fees, size, move-in date, lease length, apply link), photos, amenities, rating, review_summary and sponsored flags. Call the listing endpoint for fees, pet policy, specials and the property manager.
Filters are honoured
Beds, baths and price are checked on every unit before it is returned. A unit that does not match your filter is never returned, and a property with no matching unit is left out and counted in meta.omitted, so a page can hold fewer than per_page listings. beds takes 0 for a studio and 3 for "3 or more", the way the site does. baths is a minimum. applied_filters echoes what was used.
Location
location_id is required. Take it from /api/apartmentlist/location-autocomplete. An unknown id returns 422 (unknown_location).
Sorting and sponsored listings
default is the site's freshness order, price_asc and price_desc sort by price, and best_match is the site's own ranking. Sponsored listings keep the position the site gives them and carry is_featured: true and a featured_tag. They are never moved or removed, so a price sort can show a sponsored listing out of order.
Pagination
page is 1-based and per_page is 1-48. The full result list is kept for two minutes per filter set, so a page stays the same while you page through it. A page past the last one returns an empty listings list with the real total. It never returns another page's listings.
Prices
Prices are numbers in US dollars. A hidden price is null, never 0.
Run this endpoint
Endpoint
Parameters
Start with the required fields, then add optional filters only when your use case needs them.
Runnable path
1 required parameter needed before sending a request.
8 optional filters available.
integer
Required
Location id from location-autocomplete, for example 642592 for Austin, TX.
642592
string
Optional
Bedroom counts: 0 (studio), 1, 2 or 3 (3 or more). Repeat the parameter or separate with commas.
2
string
Optional
Minimum bathrooms: 1, 2 or 3.
example
integer
Optional
Minimum monthly rent in US dollars, per unit.
10
integer
Optional
Maximum monthly rent in US dollars, per unit.
1500
string
Optional
Amenity keys such as is_dog_friendly, is_cat_friendly, has_pool, has_gym, has_parking or has_in_unit_laundry. Properties must have all of them. Unknown keys are rejected.
example
string
Optional
default (freshness), price_asc, price_desc or best_match.
price_asc
integer
Optional
Result page, 1-based.
1
integer
Optional
Listings per page, 1-48 (default 20).
20
Request Examples
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrappa.co/api/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20",
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20');
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20', 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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20',
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20")
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20", 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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20', 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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20")
.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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20", 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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20"
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20"));
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20',
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/apartmentlist/search?location_id=642592&beds=2&price_max=1500&sort=price_asc&per_page=20")
.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_units
returned
pagination
applied_filters
listings
meta
Common listings fields
rental_id
slug
url
name
{
"success": true,
"total": 357,
"total_units": 4168,
"returned": 1,
"pagination": {
"page": 1,
"per_page": 20,
"total_pages": 18,
"has_next_page": true
},
"applied_filters": {
"location_id": 642592,
"beds": [
2
],
"price_max": 1500,
"sort": "price_asc"
},
"listings": [
{
"rental_id": "p191304",
"slug": "/tx/austin/polaris-on-the-park",
"url": "https://www.apartmentlist.com/tx/austin/polaris-on-the-park",
"name": "Polaris on the Park",
"address": "1720 Woodward Street, Austin, TX 78741",
"neighborhood": "Parker Lane",
"geo": {
"lat": 30.219922,
"lon": -97.743986
},
"phone": "(555) 010-0100",
"bed_range": [
2
],
"price_range": {
"lowest": 1049,
"highest": 1499,
"by_bed_count": {
"2": {
"min": 1049,
"max": 1499
}
}
},
"units_available": 29,
"soonest_available": "2026-10-10",
"floorplans": [
{
"floorplan_id": 8983421,
"name": "2 Bedroom",
"bed": 2,
"bath": 1.5,
"sqft": 904,
"sqft_max": 904,
"price": 1049,
"units": [
{
"unit_id": "p191304-aaea9642-f14a-11e9-a811-1866dab905f4",
"name": "1716-111",
"price": 1049,
"base_price": 1049,
"total_price": null,
"required_fees": null,
"sqft": 904,
"available_on": "2026-10-10",
"available_now": true,
"lease_length": 12,
"apply_online_url": "https://example.com/apply"
}
]
}
],
"photos": [
"https://cdn.apartmentlist.com/image/upload/c_fill,dpr_auto,f_auto,g_center,h_415,q_auto,w_640/4d2d7bc54a662f16cebd8dac28ade93c.jpg"
],
"community_amenities": [
{
"name": "Dogs allowed",
"key": "is_dog_friendly",
"group": "pets"
}
],
"unit_amenities": [
{
"name": "Dishwasher",
"key": "has_dishwasher",
"group": "unit_features"
}
],
"amenities_text": "On-site laundry, Google fiber, Patio / balcony, Hardwood floors, Dishwasher, Pet friendly + more",
"has_rent_special": false,
"rating": 4,
"review_summary": {
"title": "An oasis near vibrant Austin hotspots.",
"text": "Residents like the dog park and the courtyards.",
"tag": "Pet Paradise"
},
"is_featured": false,
"featured_tag": null,
"featured_description": null,
"show_price": true,
"source_name": "show_me_the_rent",
"is_fee_transparent": false,
"occupancy_types": [],
"updated_at": "2026-10-26T01:27:49.617Z"
}
],
"meta": {
"endpoint_family": "search",
"billable": true,
"attempts": 2,
"omitted": 0,
"id_list_cached": false
}
}
Errors
Handle these documented responses before retrying or showing customer-facing failures.
Unknown Location
The `location_id` is not an Apartment List location (`unknown_location`). Take the id from location-autocomplete. Non-billable.
{
"meta": {
"attempts": 1,
"billable": false,
"retryable": false,
"endpoint_family": "search"
},
"error": {
"code": "unknown_location",
"message": "Unknown location_id. Use an id from /api/apartmentlist/location-autocomplete."
},
"success": false
}Validation Error
A query parameter is missing, unknown or unusable. Unknown parameters are rejected, never ignored (`request_rejected` is the same failure raised by the source). Non-billable.
{
"errors": {
"sort": [
"The selected sort is invalid."
]
},
"message": "The selected sort is invalid."
}Source Unavailable
Apartment List could not be reached in time, answered with an error, or its page layout changed (`upstream_unavailable`, `upstream_blocked`, `deadline_exhausted`, `parser_drift`). Retryable and never billed. Clients are never rate limited.
{
"meta": {
"attempts": 6,
"billable": false,
"retryable": true,
"endpoint_family": "search"
},
"error": {
"code": "upstream_unavailable",
"message": "Apartment List 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.