The Async Property Search endpoint runs a Property Search asynchronously and delivers the result set to your webhookUrl. It accepts the same searchCriteria and most of the same options as the synchronous endpoint, but is tuned for higher result counts (take up to 1,000) and longer-running queries.
Endpoint
URL: POST /api/v1/property/search/async
Authentication: Bearer token (API key)
Request Body Structure
Async Property Search uses the same searchCriteria object as the sync endpoint, plus a webhookUrl under options for result delivery:
{
"searchCriteria": {
"query": "Phoenix, AZ",
"quickLists": ["high-equity", "not-owner-occupied"]
},
"options": {
"take": 1000,
"webhookUrl": "https://your-app.example.com/batchdata-webhook",
"errorWebhookUrl": "https://your-app.example.com/batchdata-error-webhook"
},
"datasets": ["basic", "valuation"]
}
Response
The HTTP response returns immediately with only a status object indicating the request was accepted, plus a requestId you can correlate with the eventual webhook delivery:
{
"status": {
"code": 200,
"text": "OK"
},
"meta": {
"requestId": "01KRCV36NPGHBE6FQER77S0XZR"
}
}
The full result set arrives at webhookUrl once processing completes.
Constraint: Search sessions are NOT supported on async
The most important difference between async and sync Property Search is that search sessions cannot be used on the async endpoint. Posting an options.searchSession block to /property/search/async returns:
400 Bad Request — "Invalid request. searchSession is not supported on async endpoints."
Why?
A search session is a stateful, forward-only delivery context: each successful request advances the session and consumes a slice of the underlying result. Async delivery breaks two of the assumptions that make sessions safe:
Retries and partial deliveries become ambiguous — if a webhook delivery fails, the customer can't tell whether the session has already advanced.
The session lifecycle (idempotency key + session id) is designed around the synchronous request/response round-trip; webhook retry semantics would re-deliver properties the session believes were already shipped.
What to do instead
If you need incremental delivery (no duplicate properties across requests), use the synchronous POST /api/v1/property/search endpoint with options.searchSession. The sync endpoint supports cursor pagination and search sessions and is the correct surface for session-backed delivery.
If you don't need incremental delivery and just want a large one-shot result set, the async endpoint is the right tool — but you'll need to drop the searchSession block.
Required token abilities
The async endpoint uses the same Property Search permissions as the sync endpoint. If you intend to call the sync endpoint with options.searchSession, your token additionally needs the property-search-sessions ability. Without it, the sync session call returns 403 — but that is a sync-endpoint concern; the async endpoint will still reject searchSession with the 400 above regardless of token abilities.
Related articles
BatchData Property Search Request Body Reference (sync) — the full request schema, cursor pagination, and search sessions.
Incremental Property Search: Cursor Pagination & Search Sessions — when to use each paging mode, with worked examples.
List Search Sessions (
GET /api/v2/property/search-sessions) — manage active sessions for the calling team.Delete Search Session (
DELETE /api/v2/property/search-sessions/{searchSessionId}) — free up a session slot.
