QUARRY

Developer

API Reference

Buy any credit pack at /credits, then create an API key from the API Keys page:

API access uses the existing $49, $199 and $699 credit packs, not a monthly plan. Property requests do not consume trace credits. Across all organization keys, requests are limited to 120 per minute and 10,000 per UTC day; quota exhaustion returns 429. New keys require available paid credits, with five active keys maximum. Successful traces consume one credit per hit. Owned past results remain readable when the balance is exhausted. Billing, key management, AUP acceptance and Google Earth token creation require a signed-in browser session.

curl https://quarry.fusiondataco.com/api/skiptrace \
  -H "Authorization: Bearer qk_live_..." \
  -H "content-type: application/json" \
  -d '{"name":"JANE DOE","city":"Phoenix","state":"AZ"}'

Request contract

Trace inputs accept a nonblank name, company or APN, or a paired latitude and longitude. Name/company/APN are limited to 300 characters, city to 120, state to 80, address to 500, phone to 80 and email to 320. Coordinates must be in range. Bulk trace accepts 1 to 25 of these same inputs.

Download the trace request JSON Schema

Property find requires a two-letter state and exactly one APN or address; city is optional. Coordinate lookup requires both nonblank lat and lng. Missing coverage is not proof that a property does not exist.

Status accepts either one job UUID or 1 to 25 comma-separated UUIDs. Larger batches are rejected, not truncated. Save every returned job ID before processing results.

400: correct the input. 401: check your key. 402: check paid access or available credits. 403: check scope and policy acceptance. 404: the record is unavailable to this account. 429: wait for Retry-After, which can extend until the UTC daily reset. 502/503: dependency unavailable. An uncertain start requires saved-job reconciliation before another POST.

Simulated API walkthrough

Explore the response flow before buying

These fixed examples run only in this page. No key, network request, provider lookup or credit charge. The sample job ID is fictional and cannot retrieve a real result.

Illustrative HTTP 202

{
  "jobId": "00000000-0000-4000-8000-000000000001",
  "status": "running"
}

Save the returned job ID. Poll its status with the same organization key; do not repeat the start request.

This demonstrates response handling, not data coverage, accuracy or provider availability.

Keep the job when your application restarts

The Node.js 20+ reference client uses no packages. It writes a local start journal before sending a real request, saves the returned job ID, and checks that same job in a separate command. It never retries a start automatically. The journal stores no API key or target input.

Download the live API reference client
# Set QUARRY_API_KEY in your process environment first.
# Put one authorized target in target.json. These commands use LIVE credits.
node quarry-trace.mjs start target.json saved-job.json
node quarry-trace.mjs status saved-job.json

If a start has no known job ID, preserve the journal and reconcile existing jobs in Quarry before trying again. A pending status is not a failed lookup. Only status checks may be retried after waiting; respect Retry-After on HTTP 429.

Quarry public API endpoints
MethodEndpointAuth
POST
/api/lists/{id}/import
Atomic CSV staging: {rows:[{ownerName?,parcelApn?,address?,city?,state?}],expectedIds:[saved row UUIDs]}. Maximum 500 new rows. Each needs name or APN. Rejects a changed or running list; returns importProtocol quarry-csv-v1. Read saved rows after an uncertain response before resuming.
key
POST
/api/lists/{id}/trace-reviewed
Queue exactly the reviewed saved list: {rows:[{id,ownerName,parcelApn,address,city,state}]}. All fields required; use empty strings for missing fields. Up to 5,000 rows. A changed snapshot returns 409; acceptance returns 202 and reviewProtocol quarry-reviewed-v1. Completed error jobs are not automatically retried.
key
GET
/api/parcels/bbox?minLng&minLat&maxLng&maxLat&limit&f=<json filters>
Parcels whose point falls in a bounding box. Optional f applies the buyer filters (absentee, outOfState, ownerType, excludeGovernment, vacantLand, acreageMin/Max, landValueMin/Max).
key
POST
/api/parcels/count
Count matching parcels for a filter set scoped by {state,county} or polygon [[lng,lat],...] or bbox. Capped at 25,000 and bounded by a 12 s timeout ({timedOut:true}).
key
POST
/api/lists/build
Build a list from the corpus: {name, filters, limit<=5000}. Rows carry absentee, out-of-state, owner type, acreage, land value, coordinates.
key
POST/GET/DELETE
/api/lists/{id}/trace
Bulk skip trace a whole list (up to 5,000) as a resumable background batch. POST starts, GET pumps and reports progress, DELETE pauses. A credit is held per running trace and consumed only on a hit.
key
GET
/api/parcels/point?lat&lng
Nearest parcel to a coordinate (owner + address).
key
GET
/api/parcels/find?state=TX&apn=R-08-217-004
Find a parcel by assessor parcel number. state is required: the corpus index is keyed (state, apn), and an APN is not unique across counties. Falls back to a prefix match when the exact number misses.
key
GET
/api/parcels/find?state=TX&address=14822 E SECTION&city=Denton
Find parcels by the start of a property street address. state is required for the same reason; city is optional.
key
POST
/api/skiptrace
Start one async skip-trace by {apn|name|lat+lng}. Returns 202 + jobId; a full trace runs for minutes. 1 credit held, consumed only on a hit. Requires the acceptable-use attestation.
key
GET
/api/skiptrace/status?job=<id> | ?jobs=<id,id,...>
Poll one job, or up to 25 at once. {status:"running"} until the engine finishes, then the ranked 2-phone / 2-email outcome with rpScore (0-100), rpLabel and rpReasons; dncStatus and litigatorStatus read not_checked.
key
POST
/api/skiptrace/bulk
Accepts up to 25 inputs. Returns an indexed outcome for each: running, suppressed, error or not_started, plus started/stopped counts. Processing can stop for credits, uncertainty or request budget. Preserve every job ID; never replay the whole request after a partial or lost response. Prefer saved-list import and trace-reviewed for recoverable batches.
key
GET/POST
/api/account/aup
Read or accept the not-FCRA acceptable-use attestation (accept from a signed-in session).
GET: key; POST: session
GET
/api/me
Org, credit balance, credits held by in-flight traces, and available.
key
GET
/api/coverage/counties
Every covered county with parcel and absentee counts (public, cached hourly).
public
POST
/api/coverage/request
Request a county: {email, state, county, note?}. Public, rate limited.
public
GET
/api/data/counties/download?state&slug
County file: builds a mail-ready list (up to 5,000 rows) and streams it as CSV.
key
GET/POST
/api/lists
List or create saved lists.
key
GET/POST
/api/lists/{id}/items
Read or add items to a list.
key
GET
/api/lists/{id}/export
Download a list as CSV: owner, situs, mailing, flags, acreage, land value, phone, phoneAlt, email, emailAlt, rpScore, rpLabel, dncStatus, litigatorStatus (formula-injection safe).
key
POST
/api/import
Parse a county-export, PropStream or generic owner CSV into typed rows.
key
POST
/api/import/trace
Start up to 50 imported rows as async traces. Returns 202 + job ids and a poll URL.
key
GET
/api/import/trace?jobs=<id,id,...>
Verified-contacts CSV for those jobs; rows still tracing read "running" (x-quarry-running header counts them).
key
GET
/api/kml/network
Download a Google Earth NetworkLink overlay (.kml). Signed-in session. The key baked into the file is bound to your org and expires after 30 days — re-download to renew.
session
GET
/api/kml/parcels?bbox=W,S,E,N
Parcels in view as KML placemarks. Session, or the signed per-org key inside the overlay.
session / signed token

Credits: 1 per verified skip-trace hit (no charge on a miss). Compliance: results exclude any opt-out / suppression-listed contact. Not for FCRA-regulated purposes.