Skip to content

Errors

All errors share one envelope:

{
"error": {
"code": "invalid_url",
"message": "Must be a https://www.zillow.com property URL",
"request_id": "8f7a3b..."
}
}

error.code is stable and machine-readable. Match on it; do not parse message. Include request_id when reporting issues.

Status code mapping

HTTP Meaning
200 Success
201 Created (e.g. webhook)
202 Accepted, async job started
204 No content (e.g. webhook revoke)
400 Client validation failed
401 Missing or invalid API key
402 Out of credits
403 Account suspended or operation not allowed on current plan
404 Resource not found
409 Job not in expected state
429 Rate limit hit
502 Upstream call failed
504 Upstream call timed out

Common error codes

Code When
missing_api_key No Authorization header
invalid_api_key Bad format, unknown, or revoked
out_of_credits Account credit balance reached 0, top up at /app/billing or upgrade
rate_limited Per-minute rate limit hit
invalid_url URL doesn’t match the expected Zillow pattern
invalid_address Address too short or malformed
invalid_zpid Non-numeric zpid
missing_input A required body/query field is absent (e.g. POST /v1/search with no filters and no searchUrls; by-url with no url)
invalid_filters filters is present but unusable, most commonly a search with no bbox (a free-text location/city alone is not enough), or a malformed bbox/range object
invalid_search_url A searchUrls[].url is not a usable Zillow search URL, it must contain a ?searchQueryState=... query parameter (pretty URLs like /austin-tx/houses/ are rejected)
invalid_status Bad value for status
invalid_extract_units Bad value for extract_units
not_found Property/job/webhook not found
job_not_ready Job is not in succeeded
job_not_found UUID does not match an account-owned job
upstream_timeout Provider call exceeded timeout
upstream_error Provider returned non-2xx
invalid_json Body could not be parsed as JSON

Search validation errors (worked examples)

A search must carry a bounding box or a pre-built Zillow URL. These are the three ways a search request fails validation before it ever reaches upstream (all return 400):

// missing_input, nothing to search on
POST /v1/search { "maxItems": 50 }
→ { "error": { "code": "missing_input", "message": "..." } }
// invalid_filters, free-text location only, no bbox
POST /v1/search { "filters": { "location": "Austin, TX", "status": "for_sale" } }
→ { "error": { "code": "invalid_filters", "message": "..." } }
// invalid_search_url, URL has no searchQueryState
POST /v1/search { "searchUrls": [{ "url": "https://www.zillow.com/austin-tx/houses/" }] }
→ { "error": { "code": "invalid_search_url", "message": "..." } }

Fix: supply filters.bbox (or bbox=w,s,e,n on the GET wrapper), or a searchUrls[].url that contains ?searchQueryState=.... See Search for how to obtain a bbox.

Idempotency and retries

  • Reads (GET) are safe to retry on 5xx and 429.
  • Writes (POST async) create new jobs, retrying creates a new job. Use request_id correlation in your logs to match attempts.
  • Webhooks include a per-attempt counter (attempt) and a timestamp; treat any single delivery as at-least-once.