Zillow API in Java
Look up Zillow property and listing data from Java with the built-in HttpClient and Jackson for JSON, with a timeout per request and errors you can act on.
Base URL https://api.propertiesapi.com/v1 · auth header x-api-key. PropertiesAPI is an independent service that returns Zillow property and listing data as JSON, provided as-is.
How Java fits
Modern Java ships an HTTP client in java.net.http, so the only dependency here is Jackson for JSON, which most Spring and Jakarta projects already have. Reading the response as a JsonNode tree keeps the example short and makes nulls explicit: isNull() tells you Zillow didn't show a value.
Set the timeout on each HttpRequest rather than on the client, so single lookups and batches can wait different amounts of time. A live lookup takes typically 8 seconds, up to about 20 seconds.
If your service already uses typed DTOs, map only the fields you need and use boxed types (Double, Integer) so a null doesn't become zero.
Add Jackson
Any recent Jackson version works. Skip this if your project already has it.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>A client class
Encodes the query, sends x-api-key, and throws an exception carrying the API's error code.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
import java.util.Map;
public class PropertiesApi {
static final String BASE = "https://api.propertiesapi.com/v1";
static final HttpClient HTTP = HttpClient.newHttpClient();
static final ObjectMapper JSON = new ObjectMapper();
public static class ApiException extends RuntimeException {
public final int status; public final String code; public final JsonNode details;
ApiException(int status, JsonNode error) {
super(status + " " + error.path("code").asText("unknown") + ": " + error.path("message").asText());
this.status = status; this.code = error.path("code").asText("unknown"); this.details = error.path("details");
}
}
static JsonNode send(HttpRequest.Builder req, Duration timeout) throws Exception {
HttpResponse<String> res = HTTP.send(
req.header("x-api-key", System.getenv("PROPERTIESAPI_KEY")).timeout(timeout).build(),
HttpResponse.BodyHandlers.ofString());
JsonNode body = JSON.readTree(res.body());
if (res.statusCode() >= 400) throw new ApiException(res.statusCode(), body.path("error"));
return body;
}
public static JsonNode property(String param, String value) throws Exception {
String q = param + "=" + URLEncoder.encode(value, StandardCharsets.UTF_8);
return send(HttpRequest.newBuilder(URI.create(BASE + "/zillow/property?" + q)).GET(), Duration.ofSeconds(120));
}
public static JsonNode batch(List<String> items) throws Exception {
String body = JSON.writeValueAsString(Map.of("items", items));
return send(HttpRequest.newBuilder(URI.create(BASE + "/zillow/batch"))
.header("content-type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body)), Duration.ofSeconds(320));
}
}Look up a home and read nullable fields
path() never throws on a missing key, and isNull() is how you spot a value Zillow doesn't show.
JsonNode body = PropertiesApi.property("url", "https://www.zillow.com/homedetails/2640-Steiner-St-San-Francisco-CA-94115/15073305_zpid/");
JsonNode home = body.path("data");
System.out.println(home.path("address").asText() + " " + home.path("homeStatus").asText());
System.out.println(home.path("price").isNull() ? "no list price shown" : "price " + home.path("price").asLong());
System.out.println(home.path("zestimate").isNull() ? "no Zestimate" : "Zestimate " + home.path("zestimate").asLong());
System.out.println("price vs Zestimate %: " + home.path("calculated").path("price_vs_zestimate_pct"));
System.out.println(body.path("meta").path("cached").asBoolean() ? "cache hit (free)" : "live lookup");Errors and batch
Catch ApiException and branch on code. In a batch, each item has ok and either data or error.
try {
PropertiesApi.property("address", "2640 Steiner St, San Francisco, CA 94115");
} catch (PropertiesApi.ApiException e) {
switch (e.code) {
case "not_found" -> System.out.println("no matching Zillow property (not billed)");
case "address_ambiguous" -> System.out.println("closest match: " + e.details.path("candidate").path("detailUrl").asText());
case "rate_limited", "upstream_busy" -> Thread.sleep(1000L * e.details.path("retry_after").asLong(2));
default -> throw e;
}
}
JsonNode batch = PropertiesApi.batch(List.of("https://www.zillow.com/homedetails/2640-Steiner-St-San-Francisco-CA-94115/15073305_zpid/", "742 Evergreen Ter, Springfield, IL 62704"));
for (JsonNode r : batch.path("data")) {
if (r.path("ok").asBoolean()) System.out.println(r.path("index") + " " + r.path("data").path("address").asText());
else System.out.println(r.path("index") + " failed: " + r.path("error").path("code").asText());
}
System.out.println("credits used: " + batch.path("meta").path("credits"));Java gotchas
- URLEncoder encodes spaces as plus signs, which the API accepts. Don't double-encode a Zillow link that is already encoded.
- asLong() on a null node returns zero. Check isNull() first, or map to a DTO with boxed types.
- HttpTimeoutException is a client-side timeout. The lookup may still complete and be cached, so a retry soon after is usually free.
- Set a client timeout of at least 120 seconds: an occasional lookup takes longer.
Zillow API and Java: questions
Is there a Zillow API Java library?+
Java wrappers for Zillow's retired ZWSID API no longer work. PropertiesAPI is two HTTPS endpoints, so HttpClient and Jackson are all you need.
Does this work with Spring Boot?+
Yes. Use the same request with RestClient or WebClient: the x-api-key header, one of url, zpid or address, and a long response timeout.
How do I keep the key out of the code?+
Read it from an environment variable or your secret store, as the example does with PROPERTIESAPI_KEY. Never ship it in a mobile or browser app.
What does a lookup cost?+
Zillow links and addresses cost the same: 1 credit per successful lookup. Repeat lookups of the same home within 24 hours come from our cache and are free. You start with 50 free lookups.
Make your first call from Java
50 free lookups, no card, no approval.
Zillow is a trademark of Zillow, Inc. PropertiesAPI is an independent service and is not affiliated with, endorsed by or sponsored by Zillow.