Home / Docs
OffMarketAPI docs
REST + MCP reference for off-market real estate signals — probate, pre-foreclosure, tax delinquency, and code violations, read nightly from county records and matched to parcels.
Authentication
Every request carries your key as a bearer token. Keys are issued per account during the founding phase.
# header on every REST call
Authorization: Bearer $OMA_KEY
Base URLs
| Surface | URL |
|---|---|
| REST | https://api.offmarketapi.com/v0 |
| MCP | https://mcp.offmarketapi.com/mcp |
Connect over MCP
Claude
# Settings → Connectors → Add custom connector Name: OffMarketAPI URL: https://mcp.offmarketapi.com/mcp # authorize with your API key
ChatGPT
{
"name": "offmarketapi",
"server_url": "https://mcp.offmarketapi.com/mcp",
"authorization": "Bearer $OMA_KEY"
}
curl
curl -H "Authorization: Bearer $OMA_KEY" \ "https://api.offmarketapi.com/v0/distressed?county=hillsborough-fl&signal=probate&since=2026-07-12"
Endpoints
search_distressedGET /v0/distressed — filter by
county, signal[], value, equity, absentee, sinceget_propertyGET /v0/property/{parcel_id} — owner, assessed value, liens, last deed
daily_diffGET /v0/diff?since=… — everything new since your last pull; built for cron agents
get_caseGET /v0/case/{case_id} — probate / foreclosure case metadata + parties
Example — search_distressed
# request GET /v0/distressed?county=hillsborough-fl&signal=probate&absentee=true&max_value=400000 # response { "county": "hillsborough-fl", "synced_at": "2026-07-13T04:12:09Z", "delayed": false, "count": 1, "records": [ { "case_id": "fl-hillsborough-26CP00xx41", "signal": "probate", "source": "hillsborough_clerk_probate_docket", "filed_date": "2026-07-11", "first_seen_at": "2026-07-12T04:12:09Z", "property": { "parcel_id": "A-xx-29-18-ZZZ-000x", "assessed_value": 412300, "absentee": true }, "match_confidence": 0.94 } ] }
Freshness fields
Every record carries provenance so an agent can trust — or discount — its age:
| Field | Meaning |
|---|---|
| source | The exact county system the record was read from. |
| filed_date | Date the case/notice hit the public record. |
| first_seen_at | When our pipeline first captured it (UTC). |
| delayed | true on the free tier — records are served on a 7-day delay. |
If a county hasn't synced within 24 hours, responses for it set "stale": true and include synced_at so you never act on data that lies about its age.
Tiers & limits
| Tier | Quota | Freshness |
|---|---|---|
| FREE | 50 queries/mo · 1 county | 7-day delay (delayed:true) |
| BUILDER | 5k queries/mo · 3 counties | last night's sync |
| FOUNDING | 25k queries/mo · all counties | last night's sync · daily_diff |
| AGENCY | usage-based | volume · white-label |
Rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) accompany every response. Request a key →
Errors
Standard HTTP status codes; the body is always JSON with an error string.
| Code | Meaning |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | County or tier not permitted on your plan. |
| 404 | Unknown parcel_id or case_id. |
| 429 | Rate limit exceeded — see X-RateLimit-Reset. |