Skip to content

Async jobs

Some operations don’t fit in a sync HTTP request:

  • POST /v1/properties/batch — always async.
  • POST /v1/search — async if maxItems > 50 or extractionMethod=PAGINATION_WITH_ZOOM_IN or async: true.
  • POST /v1/search/with-details — always async (chained two-stage run).
  • GET /v1/buildings/by-url?sync=false — async dispatch for slow building scrapes.

All of them return 202 Accepted with a job_id:

{
"data": { "job_id": "8c2a...", "status": "running" },
"request_id": "..."
}

Track progress

Two ways:

  1. Poll GET /v1/jobs/{id} every few seconds until status becomes terminal.
  2. Webhook — register one webhook and we’ll POST when the job finishes.

Recommended: webhook for production, poll for local development and quick scripts.

Polling

async function awaitJob(jobId) {
for (;;) {
const r = await fetch(`${api}/v1/jobs/${jobId}`, {
headers: { authorization: `Bearer ${key}` }
});
const { data } = await r.json();
if (["succeeded","failed","timed_out","aborted"].includes(data.status)) return data;
await new Promise(r => setTimeout(r, 3000));
}
}

Fetching results

GET /v1/jobs/{id}/results?limit=200&offset=0&format=json

Returns up to 1000 items per page. See Pagination for the loop.

Job statuses

StatusMeaning
queuedCreated, dispatch in flight
runningUpstream is working
succeededDone; results available
failedUpstream returned an error or our chain failed
timed_outUpstream exceeded its timeout
abortedCancelled

Chained search → detail

/v1/search/with-details runs a search, then runs detail extraction on every zpid in the search result, all in one job. Useful for “give me the full detail of every for-sale home in this bbox.”

Terminal window
curl https://api.zillapi.com/v1/search/with-details \
-H "Authorization: Bearer $ZILLOW_API_KEY" \
-H "content-type: application/json" \
-d '{
"filters": { "status": "for_sale", "location": "San Francisco, CA", "beds": {"min": 3} },
"maxItems": 200
}'

The job has two internal stages — chain_stage: "search" then chain_stage: "detail". You only see one job_id and one final result set.

Limits

  • Batch detail: max 500 entries per job.
  • Search async: bounded by your plan’s monthly quota; we don’t artificially cap.
  • Concurrent jobs: bounded by your plan’s rate limit (since each kick-off counts as a request).