{"openapi":"3.1.0","info":{"title":"PARCEL API","description":"\n**US county property records as an API.** Parcels, owners, assessments, sales,\nphotos and polygons for the counties we collect - one schema across every county,\nserved from our own database.\n\nEvery path here is under `/v1`. That prefix is the contract: routes are added to it\nand fields are added to responses, but nothing already in it is renamed or removed\nwithout a `/v2`.\n\n## The documents\n\n| What | Where |\n|---|---|\n| The documentation home, linking every document below | [`/developers`](/developers) |\n| This page | [`/docs`](/docs), and [`/redoc`](/redoc) for the same thing laid out differently |\n| The OpenAPI 3 document behind it | [`/openapi.json`](/openapi.json) |\n| The developer guide, as a page and as Markdown | [`/docs/guide`](/docs/guide), [`/docs/api.md`](/docs/api.md) |\n| What changed, newest first: page, JSON, Markdown, Atom feed | [`/docs/changelog`](/docs/changelog), [`/changelog`](/changelog), [`/changelog.md`](/changelog.md), [`/changelog.atom`](/changelog.atom) |\n| A one-screen index, for an agent deciding whether to call us | [`/llms.txt`](/llms.txt) |\n\nNone of these needs a credential. The Markdown and text forms exist because not\nevery reader is a browser: `curl https://13-140-33-19.sslip.io/docs/api.md` is the\nwhole guide, `/llms.txt` is the short version of it, and\n`curl \"https://13-140-33-19.sslip.io/changelog?since=0.26.0\"` says what changed\nsince the version you built against.\n\n## Authenticating\n\nOne header on every request:\n\n```\nAuthorization: Bearer pk_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nYour key is shown once, when it is issued. It is stored here only as a SHA-256\nhash, so a lost key is replaced rather than looked up. Keep it server-side: a key\nin browser JavaScript is a key you have given away.\n\n## Plans and limits\n\n| Plan | Requests / minute | Requests / month | Scopes |\n|---|---|---|---|\n| `free` | 60 | 5,000 | `read` |\n| `starter` | 300 | 100,000 | `read` |\n| `pro` | 1,000 | 1,000,000 | `read` |\n| `enterprise` | 3,000 | unlimited | `read` |\n| `internal` | 6,000 | unlimited | `read`, `write`, `admin` |\n\nA key may carry its own rate limit or monthly quota, which then wins over the\nplan's - so one customer can be given a different number without inventing a plan\nfor them.\n\nTwo ceilings apply, and they are different things. The **rate limit** is requests\na minute, as a token bucket that lets you burst a full minute's worth and then\nrefills steadily. The **quota** is requests a calendar month, resetting at midnight\nUTC on the 1st.\n\nEvery response tells you where you stand:\n\n| Header | Means |\n|---|---|\n| `X-Plan` | The plan this key is on. |\n| `X-RateLimit-Limit` | Requests a minute, or `unlimited`. |\n| `X-RateLimit-Remaining` | What is left in the bucket right now. |\n| `X-Quota-Limit` | Requests this calendar month, or `unlimited`. |\n| `X-Quota-Used` | What you have spent of it so far this month. |\n| `X-Quota-Reset` | When the quota resets: midnight UTC on the 1st, ISO-8601. |\n\nRead those rather than counting requests yourself. A key with no monthly ceiling\nreports `unlimited`, and its usage is still metered - that is what the invoice is\nbuilt from. `GET /v1/usage` returns your own meter for the month, broken down by\nday and by product area.\n\n## When something goes wrong\n\nEvery error answers with the same envelope:\n\n```json\n{\n  \"error\": {\"code\": \"invalid_parameter\",\n            \"message\": \"bbox=w,s,e,n is required\",\n            \"request_id\": \"6f1c4e0a9b2d4f1ea0c7b3d21e5a7c44\"},\n  \"detail\": \"bbox=w,s,e,n is required\"\n}\n```\n\n**Switch on `error.code`.** It is a stable token and does not change once it has\nshipped; `message` is written for a person and gets reworded.\n\n| Status | `error.code` | Means | What to do |\n|---|---|---|---|\n| **400** | `invalid_parameter` | A parameter could not be honoured. The message names it. | Fix the parameter. |\n| **401** | `unauthorized` | The key is missing, malformed, revoked or expired. | Check the header; ask for a new key. |\n| **402** | `suspended` | The key is suspended - a billing state. `reason` says why. | Talk to us; the key works again the moment it is reactivated. |\n| **403** | `forbidden` | The key is valid but the route needs a scope it does not carry. | You are reaching an internal route. It is not part of the product. |\n| **404** | `not_found` | No such record. | - |\n| **422** | `invalid_parameter` | A typed parameter would not parse. | The message names the first offender. |\n| **429** | `rate_limited` | The per-minute bucket is empty. | `Retry-After` is in seconds. Wait and retry. |\n| **429** | `quota_exceeded` | The calendar month's quota is spent. | The body carries `resets_at`; retrying before then will not help. |\n| **500** | `internal` | Our fault. | Quote the `request_id` to us. |\n\nA route may answer with a code more specific than its status - the change feed's\n`too_far_behind`, the map layer's `bbox_too_large`. It arrives in the same field,\nso switching on `error.code` needs no special case for them.\n\nEvery response, including errors, carries `X-Request-ID`, and every error body\nrepeats it as `error.request_id`. Send your own and it is echoed back (up to 64\ncharacters of letters, digits and `-_.:`). Quoting it is the fastest way to have a\ncall looked up.\n\n## Paging\n\nList routes return `{items, count, total, next_cursor, next_offset}`. `count` is\nthis page, `total` is the whole filtered set. There are two paging modes and the\nresponse tells you which one you are in: with the default `order=id` you follow\n`next_cursor` (stable while rows are being written underneath you); with any other\norder you follow `next_offset`. The other field is `null`, and both are `null` on\nthe last page. `limit` is 1-500, default 100.\n\n## The id you should store\n\n  * **`property_id`** - `\"{county_fips}-{parcel_id_norm}\"`, e.g.\n    `13153-0W050J08B000`. Derived from the county's own parcel number, so it is\n    identical across re-imports and rebuilds. Unique. **This is the one to store**,\n    and `GET /v1/parcels/{property_id}` resolves it back to a full record. It is the\n    only identifier on a parcel object.\n  * `parcel_id_norm` - the county parcel number, normalized (uppercase; spaces,\n    `+`, `.`, `-`, `/` removed).\n  * `parcel_id_raw` - the parcel number exactly as the county prints it, padding\n    included. Display only.\n\n## How fresh the data is\n\nEach parcel carries `updated_at` - when we last wrote it - and `last_seen_at`,\nwhen a source last confirmed it exists. Counties are recollected on their own\ncycles, not continuously, so `updated_at` is the honest answer to \"how old is\nthis?\" and `GET /v1/counties/{fips}` reports the county's own last update and how\nmuch of it we hold. For keeping a copy in step, use\n`GET /v1/counties/{fips}/changes?since=`, which returns upserts **and** deletes;\n`GET /v1/counties/{fips}/export` is the bulk download of a whole county as CSV or\nNDJSON.\n\n## Attribution\n\nData from county public records. It is assessor and GIS data published by the\ncounties themselves, collected and normalized by us. It is **not** a title search,\nnot a survey, and not legal advice about who owns anything; county records contain\nerrors, and we pass those through rather than invent corrections. Check the county\nof record before acting on a value that matters.\n\n## Quick start\n\n```bash\nexport PARCEL=https://13-140-33-19.sslip.io KEY=pk_your_key_here\ncurl -s -H \"Authorization: Bearer $KEY\" \"$PARCEL/v1/counties?with_data=1\"\ncurl -s -H \"Authorization: Bearer $KEY\" \"$PARCEL/v1/parcels?q=109+Freeman+Dr\"\ncurl -s -H \"Authorization: Bearer $KEY\" \"$PARCEL/v1/parcels/13153-0W050J08B000\"\ncurl -s -H \"Authorization: Bearer $KEY\" \"$PARCEL/v1/usage\"\n```\n","contact":{"name":"PARCEL support"},"version":"0.55.0"},"servers":[{"url":"https://13-140-33-19.sslip.io","description":"VPS"}],"paths":{"/v1/counties/{fips}/export":{"get":{"tags":["Export & sync"],"summary":"Export a whole county","description":"Stream every parcel of one county as a file. This is the bulk door: it uses a server-side cursor, so a county of any size streams without being loaded into memory, and the response carries `Content-Disposition: attachment`.\n\n* **`format=csv`** (default) - a header row, then one row per parcel. Lists and objects are JSON-encoded inside their cell and booleans are written `true`/`false`.\n* **`format=ndjson`** - one JSON object per line.\n\nColumns are the parcel list columns (`property_id` first, no internal row number) plus `record_url`, `geocode_precision`, `price_per_sqft` and each address as two lines (`situs_address_line1`, `situs_address_line2`, `owner_address_line1`, `owner_address_line2`: the unit, such as `STE 5552`, on line 2), in that order. A county whose data carries a licence's credit (Pitt County NC) has one more column last, `attribution`, filled on every row. Anything else is a **400**.\n\n`since` gives you a crude incremental export (`updated_at >= since`), but it cannot tell you about parcels that have *disappeared*. For a downstream copy you want to keep in step, use `/counties/{fips}/changes`, which reports deletes too.","operationId":"export_county_v1_counties__fips__export_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"`csv` (default) or `ndjson`. Anything else is a 400.","default":"csv","title":"Format"},"description":"`csv` (default) or `ndjson`. Anything else is a 400."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date (`YYYY-MM-DD`) or datetime. Keeps only parcels with `updated_at >=` this. A naive value is read as UTC.","title":"Since"},"description":"ISO date (`YYYY-MM-DD`) or datetime. Keeps only parcels with `updated_at >=` this. A naive value is read as UTC."}],"responses":{"200":{"description":"The county, streamed as a file.","content":{"text/csv":{"example":"property_id,county_fips,situs_address\\n13153-0W050J08B000,13153,109 FREEMAN DR\\n"},"application/x-ndjson":{"schema":{"$ref":"#/components/schemas/ParcelSummary"},"example":"{\"property_id\":\"13153-0W050J08B000\",\"situs_address\":\"109 FREEMAN DR\"}\\n"}}},"400":{"description":"`format` was not `csv` or `ndjson`, or `since` was not an ISO date/datetime."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/changes":{"get":{"tags":["Export & sync"],"summary":"Read the change feed across counties","description":"The change feed with no county in the path: every county we hold, or one state with `state=`. Same items, same cursor, same retention as `GET /counties/{fips}/changes` - a sync that follows more than one county wants this one, because a single cursor then covers all of them and there is nothing to fan out.\n\nEach item is `{property_id, op, at}` where `op` is `upsert` or `delete` and `property_id` names the county, so one feed is enough to route a change to the right row.\n\n### How to page\n\nTwo watermarks come back and you pick one.\n\n| Field | Feed it back as | Use it when |\n|---|---|---|\n| `next_cursor` | `cursor=` | **Always, if you can store a string.** An opaque token carrying the exact position in the feed. |\n| `next_since` | `since=` | You can only store a timestamp. Comparison is strictly greater-than. |\n\nOmit both on the first call and the feed starts from the beginning. Then pass the\nlast answer's `next_cursor` back each time, stop when `items` is empty, keep the\ncursor, and resume from it later - hours or days later, inside the retention below.\n\nThe cursor is **opaque**: it is base64, it will decode, and the shape behind it is\nfree to change. Store it, do not read it.\n\n`since=` is the older, cruder watermark. Because its comparison is strict, a page\nthat would end in the middle of one timestamp is cut short instead - so a page can\ncome back shorter than `limit`, and if every item on a full page shares one\ntimestamp the page is returned as-is and only `cursor=` gets past it. Passing both\n`since` and `cursor` uses the cursor.\n\n### Ordering, and what you are promised\n\nItems are **oldest first** in a strictly increasing order: the timestamp, then\nupserts before deletes at the same instant, then the row number. Follow the cursor\nand you see every change exactly once - none skipped, none repeated.\n\nOne thing the feed does **not** do is replay history. It reports a parcel's\n**current** state, not each edit: a row that changed three times between two polls\nappears once, with its latest `updated_at`. That is what a cache wants, and it is\nwhy the feed cannot be used as an audit trail - `GET /counties/{fips}/raw/...` is.\n\n### Deletes, and how long they are kept\n\nA `delete` is a **tombstone**: the parcel vanished from a full enumeration of every\nsource we have for that county and the collector wrote it off. Drop the row.\n\nTombstones are kept **90 days**. Resume from a watermark older than that and the\nfeed answers **409** with `code: \"too_far_behind\"`, naming the retention and the\nfull-reload route, rather than handing back a page that would quietly leave rows in\nyour copy that we have deleted. Recovering from that is: reload the county with\n`GET /counties/{fips}/export?format=ndjson`, treat anything not in the file as\ngone, and start the feed again with no `since` or `cursor`.\n\nA county that **renumbers** a parcel is the same mechanism, not a special case: the\nold `property_id` is tombstoned and the new one arrives as an upsert. There is no\nedit that changes a `property_id` in place, so a cache keyed on it never has to\nmerge two rows - it deletes one and inserts the other.","operationId":"all_changes_v1_changes_get","parameters":[{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date (`YYYY-MM-DD`) or datetime; strictly greater-than. Prefer `cursor`.","title":"Since"},"description":"ISO date (`YYYY-MM-DD`) or datetime; strictly greater-than. Prefer `cursor`."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The previous answer's `next_cursor`. Wins over `since` when both are given.","title":"Cursor"},"description":"The previous answer's `next_cursor`. Wins over `since` when both are given."},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Two-letter state code, any case (`GA`). Omit for every county we hold.","title":"State"},"description":"Two-letter state code, any case (`GA`). Omit for every county we hold."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Items per page, clamped to 1-5000.","default":1000,"title":"Limit"},"description":"Items per page, clamped to 1-5000."}],"responses":{"200":{"description":"One page of changes from every county, oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeFeed"},"example":{"items":[{"property_id":"13153-0W050J08B000","op":"upsert","at":"2026-09-14T03:21:55+00:00"},{"property_id":"13153-0W050J09A000","op":"delete","at":"2026-09-14T03:22:10+00:00"}],"count":2,"since":"1970-01-01T00:00:00+00:00","next_since":"2026-09-14T03:22:10+00:00","next_cursor":"eyJ0cyI6IjIwMjYtMDktMTRUMDM6MjI6MTArMDA6MDAiLCJvcCI6ImRlbGV0ZSJ9","limit":1000,"state":"GA"}}}},"400":{"description":"`since` was not an ISO date or datetime, or `cursor` was not a cursor this API issued."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"409":{"description":"Your watermark is older than the tombstone retention; the body carries `code: \"too_far_behind\"` and the full-reload route."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/changes":{"get":{"tags":["Export & sync"],"summary":"Read the change feed for a county","description":"An incremental feed for keeping a downstream copy in step. Two sources merged into one time-ordered list, **oldest first**: upserts (parcels whose `updated_at` moved) and deletes (parcels that vanished from a full enumeration and were tombstoned by the collector).\n\nEach item is `{property_id, op, at}` where `op` is `upsert` or `delete`. Fetch the record itself with `GET /parcels/{property_id}`; a `delete` means there is nothing left to fetch.\n\n### How to page\n\nTwo watermarks come back and you pick one.\n\n| Field | Feed it back as | Use it when |\n|---|---|---|\n| `next_cursor` | `cursor=` | **Always, if you can store a string.** An opaque token carrying the exact position in the feed. |\n| `next_since` | `since=` | You can only store a timestamp. Comparison is strictly greater-than. |\n\nOmit both on the first call and the feed starts from the beginning. Then pass the\nlast answer's `next_cursor` back each time, stop when `items` is empty, keep the\ncursor, and resume from it later - hours or days later, inside the retention below.\n\nThe cursor is **opaque**: it is base64, it will decode, and the shape behind it is\nfree to change. Store it, do not read it.\n\n`since=` is the older, cruder watermark. Because its comparison is strict, a page\nthat would end in the middle of one timestamp is cut short instead - so a page can\ncome back shorter than `limit`, and if every item on a full page shares one\ntimestamp the page is returned as-is and only `cursor=` gets past it. Passing both\n`since` and `cursor` uses the cursor.\n\n### Ordering, and what you are promised\n\nItems are **oldest first** in a strictly increasing order: the timestamp, then\nupserts before deletes at the same instant, then the row number. Follow the cursor\nand you see every change exactly once - none skipped, none repeated.\n\nOne thing the feed does **not** do is replay history. It reports a parcel's\n**current** state, not each edit: a row that changed three times between two polls\nappears once, with its latest `updated_at`. That is what a cache wants, and it is\nwhy the feed cannot be used as an audit trail - `GET /counties/{fips}/raw/...` is.\n\n### Deletes, and how long they are kept\n\nA `delete` is a **tombstone**: the parcel vanished from a full enumeration of every\nsource we have for that county and the collector wrote it off. Drop the row.\n\nTombstones are kept **90 days**. Resume from a watermark older than that and the\nfeed answers **409** with `code: \"too_far_behind\"`, naming the retention and the\nfull-reload route, rather than handing back a page that would quietly leave rows in\nyour copy that we have deleted. Recovering from that is: reload the county with\n`GET /counties/{fips}/export?format=ndjson`, treat anything not in the file as\ngone, and start the feed again with no `since` or `cursor`.\n\nA county that **renumbers** a parcel is the same mechanism, not a special case: the\nold `property_id` is tombstoned and the new one arrives as an upsert. There is no\nedit that changes a `property_id` in place, so a cache keyed on it never has to\nmerge two rows - it deletes one and inserts the other.\n\n`GET /changes` is the same feed with no county in the path, for a sync that follows more than one of them.","operationId":"county_changes_v1_counties__fips__changes_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date (`YYYY-MM-DD`) or datetime; strictly greater-than. Omit to start from the beginning. Prefer `cursor`.","title":"Since"},"description":"ISO date (`YYYY-MM-DD`) or datetime; strictly greater-than. Omit to start from the beginning. Prefer `cursor`."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The previous answer's `next_cursor`. Wins over `since` when both are given.","title":"Cursor"},"description":"The previous answer's `next_cursor`. Wins over `since` when both are given."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Items per page, clamped to 1-5000.","default":1000,"title":"Limit"},"description":"Items per page, clamped to 1-5000."}],"responses":{"200":{"description":"One page of changes, oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeFeed"},"example":{"items":[{"property_id":"13153-0W050J08B000","op":"upsert","at":"2026-09-14T03:21:55+00:00"},{"property_id":"13153-0W050J09A000","op":"delete","at":"2026-09-14T03:22:10+00:00"}],"count":2,"since":"1970-01-01T00:00:00+00:00","next_since":"2026-09-14T03:22:10+00:00","next_cursor":"eyJ0cyI6IjIwMjYtMDktMTRUMDM6MjI6MTArMDA6MDAiLCJvcCI6ImRlbGV0ZSJ9","limit":1000}}}},"400":{"description":"`since` was not an ISO date or datetime, or `cursor` was not a cursor this API issued."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"409":{"description":"Your watermark is older than the tombstone retention; the body carries `code: \"too_far_behind\"` and the full-reload route."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/coverage":{"get":{"tags":["Counties"],"summary":"Show collection coverage for a county","description":"How complete one county is: the raw counts, the same numbers as percentages of `parcels`, the newest good run per source, and - while a qPublic run is actually in flight - an ETA.\n\n`pct_arcgis` near 100 with a low `pct_qpublic` is the normal mid-collection shape: ArcGIS enumerates every parcel and its geometry quickly, then qPublic fills in detail one page at a time. `pct_sales` and `pct_buildings` are the share of parcels that have at least one row in those detail tables, so they track qPublic. Sources overlap, so the percentages do not sum to 100.\n\n`fields_pct` is the share carrying each detail column, `missing` names the kinds of detail under 10% of the parcels carry (owners, sale prices, buildings, values; sale prices are not expected in a non-disclosure state), `not_published` the kinds no free official source carries here (`not_published_why` says why, per kind), and `detail_status` sums that up: `full`, `partial`, or `none` when the parcels carry little beyond the map shape. `counted_at` is when this county's numbers were read and `counts_age_s` how long ago that was: a county is recounted when a run on it finishes, so it can be fresher than the national copy.\n\n`eta` is projected from the run's own measured throughput (`stats.stored` over elapsed time) across the parcels still missing qPublic detail. It is `null` unless a qPublic run is running *and* has stored something - there is nothing to extrapolate from before that.","operationId":"county_coverage_v1_counties__fips__coverage_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."}],"responses":{"200":{"description":"Coverage for the county, with an ETA when one can be computed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountyCoverage"},"example":{"parcels":67544,"from_qpublic":44012,"from_arcgis":67544,"with_photos":21870,"with_location":67544,"with_sales":43980,"with_buildings":41220,"pct_qpublic":65.2,"pct_arcgis":100.0,"pct_photos":32.4,"pct_sales":65.1,"pct_buildings":61.0,"pct_location":100.0,"fields_pct":{"owner":99.1,"mailing":98.7,"value":99.1,"sale_date":88.9,"sale_price":61.0,"year_built":74.2,"sqft":74.0,"beds":60.3},"detail_status":"full","missing":[],"not_published":[],"not_published_why":{},"last_good_run":{"arcgis":{"id":388,"finished_at":"2026-09-14T03:21:55+00:00"}},"eta":{"run_id":391,"stored":1240,"elapsed_seconds":3127,"rate_per_min":23.79,"remaining_parcels":23532,"seconds_remaining":59352,"eta_at":"2026-09-18T19:31:23+00:00"},"counted_at":"2026-09-18T03:22:10+00:00","counts_age_s":42}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/coverage":{"get":{"tags":["Counties"],"summary":"Coverage for every county in one call","description":"One row per county we have a source for or parcels in: how much of it we hold, how deep it goes, and whether collection is healthy. This is the route behind a national map coloured by how good the data is.\n\n`GET /counties/{fips}/coverage` answers the same question for one county; doing that for the whole country is 3,143 requests, which is why this exists. It is answered from a copy kept in memory, so it costs no query whatever the county count.\n\nPass `state=` for one state. Counties we have neither a source for nor a single parcel in are left out - use `GET /counties` for the full registry of 3,000-odd.\n\n### `status`\n\n| Status | Means |\n|---|---|\n| `ok` | Records collect cleanly, and something has collected recently. |\n| `degraded` | We hold records, and collection has a problem: a source that is not collecting cleanly, a run that stopped, no collector configured, or nothing complete in 45 days. |\n| `none` | We hold no parcels for this county. `reason` says why. |\n\n`reason` is always present and always a plain sentence - it is written to be shown\nto whoever is looking at the map. `last_error` is the same kind of sentence for the\nmost recent run that did not finish, and is `null` when the latest run of every\nsource finished; a county can be `degraded` for staleness alone, with nothing\nhaving failed.\n\n### Detail\n\n`status` is about collection: whether the county's records arrive cleanly. It\nsays nothing about how much each record carries, and a county whose map layer\ncollects every night while nothing fills in the sale, the owner or the building\nis `ok`. The detail fields say that part:\n\n| Field | Means |\n|---|---|\n| `missing` | The kinds of detail under 10% of the county's parcels carry, from `owners`, `sale prices`, `buildings` (a year built or a living area) and `values` - leaving out what is `not_published`. Empty when nothing is missing. |\n| `not_published` | The kinds no free official bulk source publishes for this county, as far as we have looked: sale prices in the twelve non-disclosure states, and the county findings in `config/not-published.json` (owner names in five California counties, in Allegheny PA and - under its download terms - in King County WA; sale prices in Los Angeles and Monterey). Never counted as missing. |\n| `detail_status` | `full` (nothing missing), `partial`, or `none` - every kind a source could publish is missing, so the parcels carry little beyond the map shape. |\n\nWhen something is missing, `reason` says so after a semicolon (\"records are\ncollecting cleanly; no sale prices or buildings yet\"), so a reader of the sentence\nalone is not told that a county of outlines is in good shape; what is not published\nfollows the same way (\"...; owners and sale prices are not published here\").\n\n### The percentages\n\nAll four are shares of `parcel_count`, to one decimal, and `0.0` when we hold no\nparcels.\n\n| Field | Share of parcels that |\n|---|---|\n| `depth_pct` | a detail collector has opened, so they carry more than the outline and the id. |\n| `photos_pct` | have at least one image. |\n| `sales_pct` | have at least one recorded sale, from a detail collector. |\n| `sale_date_pct` | carry a last sale date, from any source - a map layer or a roll fills it without a sale record. Zero means a `sold_after` filter finds nothing in this county. |\n| `located_pct` | carry a latitude. |\n\n`counts_age_s` is how many seconds old the oldest numbers in the answer are: the\ncounts, the runs and the verdicts behind `status` come from one copy counted in the\nbackground, in full on a timer and county by county after each finished collection\nrun, because scanning every parcel row costs minutes and a national map does not\nneed the count to the second. A county recounted after a run is fresher than the\nage says; `GET /counties/{fips}/coverage` gives that county's own `counted_at`.\n`generated_at` is when this answer was assembled. Answers carry an `ETag`; send it\nback as `If-None-Match` and an unchanged answer is a `304` with no body.","operationId":"coverage_v1_coverage_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Two-letter state code, any case (`GA`). Omit for every state.","title":"State"},"description":"Two-letter state code, any case (`GA`). Omit for every state."}],"responses":{"200":{"description":"Every county we collect, with its coverage and its status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Coverage"},"example":{"items":[{"fips":"13153","state":"GA","name":"Houston County","status":"ok","parcel_count":67544,"depth_pct":65.2,"photos_pct":32.4,"sales_pct":65.1,"located_pct":100.0,"detail_status":"partial","missing":["sale prices"],"not_published":[],"last_good_run_at":"2026-09-14T03:21:55+00:00","reason":"records are collecting cleanly; no sale prices yet"},{"fips":"13001","state":"GA","name":"Appling County","status":"none","parcel_count":0,"depth_pct":0.0,"photos_pct":0.0,"sales_pct":0.0,"located_pct":0.0,"detail_status":"none","missing":[],"not_published":[],"reason":"no parcel keys yet - we have no list of this county's parcels to collect from"}],"generated_at":"2026-09-22T09:14:02+00:00","counts_age_s":42}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parcels/{property_id}/images/{variant}":{"get":{"tags":["Images"],"summary":"List a parcel's images by variant","description":"Image metadata for one parcel, filtered to one variant - the route to use when you want thumbnails for a grid and full-size images only on click.\n\nCompared with `GET /parcels/{property_id}/images`, this adds the variant filter, `sha256`, and a `bytes_url` pointing at the ETag-cached fetch route.\n\n`stored` is authoritative for **this** row: only `stored: true` rows have bytes on this box, and a `stored: false` row is fetched from its source, stored and served by the first request to its `bytes_url` while `source_expires_at` has not passed. `caption` is the county page's own text for the picture. `has_full` is about the picture rather than the row - whether the full-resolution version of the same photo is stored - so a thumbnail with `has_full: false` is all there is of it, and a grid can say so. `source_url` is the county's own link and is provenance only - qPublic signs those and they expire roughly 24 hours after the fetch, so never hand one to a browser.","operationId":"parcel_images_variant_v1_parcels__property_id__images__variant__get","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","description":"The property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`.","title":"Property Id"},"description":"The property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`."},{"name":"variant","in":"path","required":true,"schema":{"type":"string","description":"`full`, `thumb`, or `all` for both. Anything else is a 400.","title":"Variant"},"description":"`full`, `thumb`, or `all` for both. Anything else is a 400."}],"responses":{"200":{"description":"Image metadata for that variant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageList"},"example":{"items":[{"id":77013,"source":"qpublic","kind":"photo","position":1,"variant":"thumb","caption":"Property photo","mime":"image/jpeg","byte_size":8120,"sha256":"3f1c9a...","fetched_at":"2026-09-14T03:21:55+00:00","stored":true,"has_full":true,"source_url":"https://qpublicimages.blob.core.windows.net/...","source_expires_at":"2026-09-15T03:21:50+00:00","url":"/images/77013","bytes_url":"/images/77013/bytes"}],"variant":"thumb"}}}},"400":{"description":"`variant` was not `full`, `thumb` or `all`."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel with that property id, or the id is malformed."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/images/{image_id}/bytes":{"get":{"tags":["Images"],"summary":"Fetch image bytes with caching","description":"The stored bytes of one image, with an **ETag** (the stored `sha256`) and `Cache-Control: private, max-age=86400, immutable`. Send the ETag back as `If-None-Match` and an unchanged image answers **304** with no body - this is the route to use in any UI that shows the same photos repeatedly.\n\n**A link-only image is fetched on the first request.** With the collector on `images=urls` a row holds the county's link and no bytes. The first request fetches the bytes from `source_url` (the collector's User-Agent, the scraper's main proxy, a hard 20 second deadline, one fetch per image however many requests arrive together, four fetches at most at once), stores them, and serves them; every later request is served from storage, and stored bytes are never fetched again. Only a real JPEG, PNG, GIF or WebP is stored, and its content type is the one its bytes say. Only https links on the image hosts the collector records are fetched, from public addresses, following at most three redirects on the same host. If the source refuses - a 403, a 429, a Cloudflare challenge page, anything that is not an image, the deadline - the answer is a **503** with `Retry-After: 900` and a JSON body naming `source_url`, and nothing is stored. That source URL is then remembered for fifteen minutes: a request for it inside them gets the same 503 at once, without asking the source. A 503 whose `Retry-After` is 30 means this server was busy, not the source. A signed link past its expiry, or one outside the image hosts, is not tried: that is the 404 below.\n\n**Returns image bytes, not JSON.** The exceptions are the 404 for a row whose bytes cannot be had and the 503 for a source that refused, both JSON carrying `stored: false` and the original `source_url`. Comparison follows RFC 7232 weak semantics, so `W/` prefixes, quoted forms, a comma-separated list and `*` all work.","operationId":"image_bytes_v1_images__image_id__bytes_get","parameters":[{"name":"image_id","in":"path","required":true,"schema":{"type":"integer","description":"`raw_images.id`, from a `bytes_url` or an image metadata row.","title":"Image Id"},"description":"`raw_images.id`, from a `bytes_url` or an image metadata row."}],"responses":{"200":{"description":"The image bytes, with an ETag.","content":{"image/jpeg":{},"image/png":{},"application/octet-stream":{}}},"304":{"description":"Your `If-None-Match` ETag still matches; no body."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No such image row, or its bytes cannot be had: no link was recorded, the link is not https on one of the image hosts the collector records, or the signed link expired before anybody asked (a JSON body then carries `stored: false`, `source_url` and `reason`; the parcel's next scrape records a fresh link).","content":{"application/json":{"example":{"error":"image bytes not stored","stored":false,"source_url":"https://qpublicimages.blob.core.windows.net/...","reason":"the source link expired at 2026-09-15T03:21:50+00:00; the parcel's next scrape records a fresh one","source_expires_at":"2026-09-15T03:21:50+00:00"}}}},"503":{"description":"The image is held only as a link and its source refused the fetch just now (403, 429, a Cloudflare challenge page, a timeout). Nothing was stored; `Retry-After` says when to ask again, and the next request tries the source again.","content":{"application/json":{"example":{"detail":"the image could not be fetched from its source: the source answered 403","stored":false,"source_url":"https://qpublicimages.blob.core.windows.net/...","reason":"the source answered 403","retry_after_s":900,"error":{"code":"unavailable","message":"the image could not be fetched from its source: the source answered 403","request_id":"6f1c4e0a9b2d4c1e8f3a7b5d2e9c1a40"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/parcels/by-apn/{apn}":{"get":{"tags":["Parcels"],"summary":"Get one parcel by county parcel number","description":"Look a parcel up by the county's own parcel number (APN), in **any** spelling. The value is normalized before the lookup - uppercased, with spaces, `+`, `.`, `-` and `/` removed - so `0W050J    08B000`, `0W050J++++08B000` and `0w050j 08b000` all resolve to the same parcel.\n\nThis is the route for reconciling against a county's own spreadsheet or deed record, where the parcel number arrives formatted however that office writes it. If you control the stored value, store `property_id` and use `GET /parcels/{property_id}` instead - same answer, one path segment.\n\nReturns the same full record as `GET /parcels/{property_id}` - typed columns, `record_url`, `sales[]`, `buildings[]`, `values[]`, `images[]`, resolved `owners[]`, typed `permits[]`, every page module in `sections[]`, and `no_data_modules[]`. All three detail routes are assembled by the same code, so they cannot drift apart.","operationId":"parcel_by_apn_v1_counties__fips__parcels_by_apn__apn__get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153`).","title":"Fips"},"description":"Five-digit county FIPS code (`13153`)."},{"name":"apn","in":"path","required":true,"schema":{"type":"string","description":"The county parcel number in any spelling. It is the last path segment and may contain spaces and `/`, so URL-encode it.","title":"Apn"},"description":"The county parcel number in any spelling. It is the last path segment and may contain spaces and `/`, so URL-encode it."}],"responses":{"200":{"description":"The full parcel record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelDetail"},"example":{"property_id":"13153-0W050J08B000","county_fips":"13153","state":"GA","parcel_id_norm":"0W050J08B000","parcel_id_raw":"0W050J    08B000","account_number":"13554","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_state":"GA","situs_zip":"31088","owner_name":"SMITH JOHN A","owner_names":["SMITH JOHN A","SMITH MARY B"],"owner_address":"109 FREEMAN DR","owner_city":"WARNER ROBINS","owner_state":"GA","owner_zip":"31088","owner_occupied":true,"owner_id":"13153_SMITH_JOHN_A","owner_verified":true,"owner_display":"SMITH, JOHN A","property_class":"R3","property_use":"Residential","zoning":"R-1","tax_district":"COUNTY","homestead":true,"land_acres":0.46,"building_count":1,"building_style":"RANCH","year_built":1978,"heated_sqft":1684,"bedrooms":3,"full_baths":2,"half_baths":0,"condition":"AVERAGE","last_sale_date":"2019-06-14","last_sale_price":132000,"assessed_year":2025,"land_value":18000,"improvement_value":141200,"total_value":159200,"est_annual_tax":1234.5,"latitude":32.6105,"longitude":-83.6219,"geocode_source":"gis","geocode_precision":"parcel","photo_count":2,"sketch_count":1,"sources":["arcgis","qpublic"],"source_urls":{"qpublic":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000"},"record_url":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000","last_seen_at":"2026-09-14T03:21:55+00:00","updated_at":"2026-09-14T03:21:55+00:00","home_type":"single_family","home_type_basis":"inferred","zillow":{"zpid":35956751,"status":"recently_sold","status_at":"2026-09-30","sold_seen":"2026-09-30","price":214000,"url":"https://www.zillow.com/homedetails/109-Freeman-Dr-Warner-Robins-GA-31088/35956751_zpid/"},"messy_title_likely":false,"messy_title_reasons":[],"messy_title":{"likely":false,"reasons":[],"evidence":[],"checked_at":"2026-10-21T04:31:10+00:00"},"source_keys":{"qpublic":"0W050J    08B000","arcgis":"0W050J    08B000"},"sales":[{"id":9901,"source":"qpublic","sale_date":"2019-06-14","sale_price":132000,"grantor":"JONES ROBERT","grantee":"SMITH JOHN A","deed_book_page":"4412/233","reason":"Fair Market Value"}],"buildings":[{"id":3310,"source":"qpublic","kind":"residential","position":1,"year_built":1978,"sqft":1684,"value":141200,"attributes":{"Exterior Wall":"BRICK","Heat":"CENTRAL"}}],"values":[{"source":"qpublic","year":2025,"land_value":18000,"improvement_value":141200,"accessory_value":0,"total_value":159200,"previous_value":151400}],"images":[{"id":77012,"source":"qpublic","kind":"photo","position":1,"variant":"full","caption":"Property photo","mime":"image/jpeg","byte_size":148221,"fetched_at":"2026-09-14T03:21:55+00:00","stored":true,"has_full":true,"source_url":"https://qpublicimages.blob.core.windows.net/...?sig=expired","source_expires_at":"2026-09-15T03:21:50+00:00","url":"/images/77012"}],"owners":[{"entry_id":"13153_SMITH_JOHN_A","entry_name":"SMITH, JOHN A","verified":true,"identity_id":51204,"canonical_name":"SMITH JOHN","kind":"person","key":"person|smith john a|109 freeman dr|31088","method":"auto"}],"permits":[{"date":"2021-04-02","number":"B21-0417","type":"REROOF","raw":{"Permit Date":"04/02/2021","Permit Number":"B21-0417","Type":"REROOF"}}],"sections":[{"name":"Summary","fields":[{"label":"Parcel Number","value":"0W050J    08B000"}],"grids":[],"images":[]}],"no_data_modules":["Mobile Homes","Conservation Use"]}}}},"400":{"description":"The parcel number normalized to nothing."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel with that number in that county."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parcels/by-key/{key}":{"get":{"tags":["Parcels"],"summary":"Get one parcel by a stored key, in either spelling","description":"Look a parcel up by a key you already stored, whichever way it is spelled: the property id `13153-0W050J08B000`, or the old `parcel_key` form `13153:0W050J08B000` the same value had before 0.8.0.\n\n**This route exists for the rename and goes with the next release.** It accepts the colon spelling so a key written down earlier still resolves; new code should call `GET /parcels/{property_id}`, which is the same record at a shorter path. The parcel-number half is normalized for you, so a stored key that kept the county's spacing (`13153:0w050j 08b000`) resolves too.\n\nA malformed key is a **400** that says what the shape is; a well-formed key for a parcel we do not hold is a **404**.\n\nReturns the same full record as `GET /parcels/{property_id}` - typed columns, `record_url`, `sales[]`, `buildings[]`, `values[]`, `images[]`, resolved `owners[]`, typed `permits[]`, every page module in `sections[]`, and `no_data_modules[]`. All three detail routes are assembled by the same code, so they cannot drift apart.","operationId":"parcel_by_key_v1_parcels_by_key__key__get","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","description":"`{county_fips}-{parcel_number}` (e.g. `13153-0W050J08B000`) or the old `{county_fips}:{parcel_number}`. The parcel-number half is normalized, so any spelling of it works.","title":"Key"},"description":"`{county_fips}-{parcel_number}` (e.g. `13153-0W050J08B000`) or the old `{county_fips}:{parcel_number}`. The parcel-number half is normalized, so any spelling of it works."}],"responses":{"200":{"description":"The full parcel record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelDetail"},"example":{"property_id":"13153-0W050J08B000","county_fips":"13153","state":"GA","parcel_id_norm":"0W050J08B000","parcel_id_raw":"0W050J    08B000","account_number":"13554","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_state":"GA","situs_zip":"31088","owner_name":"SMITH JOHN A","owner_names":["SMITH JOHN A","SMITH MARY B"],"owner_address":"109 FREEMAN DR","owner_city":"WARNER ROBINS","owner_state":"GA","owner_zip":"31088","owner_occupied":true,"owner_id":"13153_SMITH_JOHN_A","owner_verified":true,"owner_display":"SMITH, JOHN A","property_class":"R3","property_use":"Residential","zoning":"R-1","tax_district":"COUNTY","homestead":true,"land_acres":0.46,"building_count":1,"building_style":"RANCH","year_built":1978,"heated_sqft":1684,"bedrooms":3,"full_baths":2,"half_baths":0,"condition":"AVERAGE","last_sale_date":"2019-06-14","last_sale_price":132000,"assessed_year":2025,"land_value":18000,"improvement_value":141200,"total_value":159200,"est_annual_tax":1234.5,"latitude":32.6105,"longitude":-83.6219,"geocode_source":"gis","geocode_precision":"parcel","photo_count":2,"sketch_count":1,"sources":["arcgis","qpublic"],"source_urls":{"qpublic":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000"},"record_url":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000","last_seen_at":"2026-09-14T03:21:55+00:00","updated_at":"2026-09-14T03:21:55+00:00","home_type":"single_family","home_type_basis":"inferred","zillow":{"zpid":35956751,"status":"recently_sold","status_at":"2026-09-30","sold_seen":"2026-09-30","price":214000,"url":"https://www.zillow.com/homedetails/109-Freeman-Dr-Warner-Robins-GA-31088/35956751_zpid/"},"messy_title_likely":false,"messy_title_reasons":[],"messy_title":{"likely":false,"reasons":[],"evidence":[],"checked_at":"2026-10-21T04:31:10+00:00"},"source_keys":{"qpublic":"0W050J    08B000","arcgis":"0W050J    08B000"},"sales":[{"id":9901,"source":"qpublic","sale_date":"2019-06-14","sale_price":132000,"grantor":"JONES ROBERT","grantee":"SMITH JOHN A","deed_book_page":"4412/233","reason":"Fair Market Value"}],"buildings":[{"id":3310,"source":"qpublic","kind":"residential","position":1,"year_built":1978,"sqft":1684,"value":141200,"attributes":{"Exterior Wall":"BRICK","Heat":"CENTRAL"}}],"values":[{"source":"qpublic","year":2025,"land_value":18000,"improvement_value":141200,"accessory_value":0,"total_value":159200,"previous_value":151400}],"images":[{"id":77012,"source":"qpublic","kind":"photo","position":1,"variant":"full","caption":"Property photo","mime":"image/jpeg","byte_size":148221,"fetched_at":"2026-09-14T03:21:55+00:00","stored":true,"has_full":true,"source_url":"https://qpublicimages.blob.core.windows.net/...?sig=expired","source_expires_at":"2026-09-15T03:21:50+00:00","url":"/images/77012"}],"owners":[{"entry_id":"13153_SMITH_JOHN_A","entry_name":"SMITH, JOHN A","verified":true,"identity_id":51204,"canonical_name":"SMITH JOHN","kind":"person","key":"person|smith john a|109 freeman dr|31088","method":"auto"}],"permits":[{"date":"2021-04-02","number":"B21-0417","type":"REROOF","raw":{"Permit Date":"04/02/2021","Permit Number":"B21-0417","Type":"REROOF"}}],"sections":[{"name":"Summary","fields":[{"label":"Parcel Number","value":"0W050J    08B000"}],"grids":[],"images":[]}],"no_data_modules":["Mobile Homes","Conservation Use"]}}}},"400":{"description":"The key has neither a dash nor a colon, its FIPS half is not five digits, or its parcel-number half is empty."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel with that key."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/keys":{"get":{"tags":["Parcels"],"summary":"Explain the parcel identifiers","description":"A machine-readable statement of what every identifier on a parcel means, and which one to store. Constant - it describes the contract, not the data - so a client can fetch it once at start-up, or a developer can read it here instead of guessing from a sample row.\n\nThe short version: **store `property_id`**. There is no other identifier on a parcel object - the internal row number does not leave this process. The full version is in this document's introduction and in the response below.\n\n`docs` points at the rest of the contract: `/openapi.json` for the routes and shapes, `/docs/api.md` for the developer guide as Markdown, and `/llms.txt` for the one-screen index. None of the three needs a credential.","operationId":"key_semantics_v1_keys_get","responses":{"200":{"description":"What each identifier means and how to look one up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentifierGuide"},"example":{"stable_key":"property_id","property_id_format":"{county_fips}-{parcel_id_norm}","property_id_example":"13153-0W050J08B000","fields":{"property_id":"THE id: {county_fips}-{parcel_id_norm}; stable across re-imports and rebuilds; store this","parcel_id_norm":"county parcel number, normalized (uppercase, whitespace/+/./-// removed); cross-source join key, and the half of property_id after the dash","parcel_id_raw":"county parcel number verbatim from the primary source, padding included","account_number":"county alternate id (Houston GA: GIS PIN); label, not a key","source_keys":"{source: exact key spelling that source uses}; source_keys.qpublic is the qPublic URL key"},"lookups":{"by_property_id":"GET /parcels/{property_id}","by_stored_key":"GET /parcels/by-key/{key} (accepts the old {fips}:{apn} spelling for one release)","by_apn":"GET /counties/{fips}/parcels/by-apn/{parcel_number_in_any_spelling}"},"docs":{"openapi":"/openapi.json","guide_markdown":"/docs/api.md","index":"/llms.txt","human":"/docs","home":"/developers","changelog":"/changelog"}}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."}}}},"/v1/owners":{"get":{"tags":["Owners"],"summary":"Search owners","description":"Search owner entries - one per county and mailing-address-qualified name, which is the owner a person reads and links to.\n\n`entry_id` is `{fips}_{NAME}`, with `~2`, `~3` when one county holds more than one owner of that name at different mailing addresses. Feed it to `/owners/{entry_id}` for the owner's own page and to `?owner=` on the parcel list for everything they hold in that county.\n\n`buyer_id` is set once that owner has bought something (`/buyers/{buyer_id}`); `verified` says an admin has confirmed the owner rather than the matcher alone.\n\n### Parameters\n\n| Parameter | Meaning |\n|---|---|\n| `q` | Substring of the display name. An entry id is matched exactly instead, so pasting one finds that owner. |\n| `kind` | `person`, `org`, `trust`, `gov`, `unknown`. |\n| `county` | Five-digit FIPS. |\n| `verified` | `1` keeps confirmed owners, `0` the rest. |\n| `min_parcels` | Keep owners holding at least this many. |\n| `identity_id` | Every entry of one cross-county owner (the `identity_id` on a hit): the same owner in each county. |\n| `mailing_zip` | Five-digit ZIP of the owner's mailing address, any county. |\n| `mailing_address` | The mailing street line, compared whole (case and spacing ignored). Needs `mailing_zip`: with it, every owner in every county who mails to that address. |\n| `limit` | 1-500, default 50. |\n| `offset` | 0-100000, default 0. |\n\nOrdered by `parcel_count` descending, so the biggest holders come first. A `limit` or `offset` that is not a number falls back to its default rather than erroring.\n\n### Each hit\n\n| Field | Meaning |\n|---|---|\n| `entry_id` | The owner's id: one county, one name at one mailing address. |\n| `display_name` | The name as the county prints it. |\n| `county_fips`, `county_name` | The county this entry is in. |\n| `parcel_count` | Parcels this owner is on in that county today, co-ownership included. |\n| `total_value` | Those parcels' total market value added up; `null` until the nightly owner run has filled it. |\n| `identity_id` | The same owner across counties (the matcher's link of name and mailing address); `null` when the matcher has not reached it. `GET /owners/{entry_id}/parcels` lists every county's parcels. |\n| `kind`, `verified`, `buyer_id`, `mailing_address`, `mailing_city`, `mailing_state`, `mailing_zip` | As on `GET /owners/{entry_id}`. |","operationId":"owner_list_v1_owners_get","responses":{"200":{"description":"Matching owners, biggest holders first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerList"},"example":{"items":[{"entry_id":"13153_SMITH_JOHN_A","display_name":"SMITH, JOHN A","kind":"person","county_fips":"13153","county_name":"Houston","parcel_count":7,"total_value":1012400,"identity_id":51204,"buyer_id":"BID-000123","verified":true,"mailing_address":"109 FREEMAN DR","mailing_city":"WARNER ROBINS","mailing_state":"GA","mailing_zip":"31088"}],"total":1}}}},"400":{"description":"`mailing_address` without a five-digit `mailing_zip`, or a `mailing_zip` or `identity_id` that is not one."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."}}}},"/v1/owners/holdings":{"post":{"tags":["Owners"],"summary":"How much each owner holds, for many owners","description":"For a list of owner names (or owner ids), how many parcels each one holds **today**, county-wide or nationwide, in one call - the \"owns at least N\" filter for a list of buyers.\n\nBody: `{\"names\": [...], \"owner_ids\": [...], \"county\": \"13153\"}`. `names` and `owner_ids` together hold 1 to 500 values; `county` (optional) counts one county only.\n\n* A **name** is read as an owner line, the way the rolls print it (`SMITH JOHN A`, `OAKPOINT HOLDINGS LLC`). A company matches exactly. A person can be several owners - two JOHN A SMITHs at two mailing addresses are two - so every owner the name matches is listed under `owners`, `ambiguous` is true, and the headline `parcels` / `counties` are the biggest one's.\n* An **owner id** (`grantee_owner_id` on a sale row, `entry_id` from `/owners`) is one owner exactly: use it when you have it.\n\nEach owner carries `parcels` (every parcel whose current owner line is theirs - a lot they bought and resold is not counted), `counties` (biggest first) with `by_county`, `mailing_states` and `owner_id`, its entry for `GET /owners/{entry_id}`. An owner merged across counties by the matcher counts every county. A name with no owner on file answers `matched: false`, `parcels: 0`. Answers come in the order asked; a repeated value is answered once.\n\nThe owner index is rebuilt by the nightly owner run, so an owner line that changed since that run is counted under its old name.","operationId":"owner_holdings_v1_owners_holdings_post","requestBody":{"description":"`names` and/or `owner_ids`: 1 to 500 values in all; `county`: an optional five-digit FIPS.","content":{"application/json":{"example":{"names":["OAKPOINT HOLDINGS LLC","SMITH JOHN A"],"owner_ids":["13153_DOE_JANE"]}}},"required":true},"responses":{"200":{"description":"One answer per value asked, in order.","content":{"application/json":{"schema":{},"example":{"items":[{"name":"OAKPOINT HOLDINGS LLC","matched":true,"parcels":37,"counties":["13153","13021"],"ambiguous":false,"owners":[{"owner_id":"13153_OAKPOINT_HOLDINGS_LLC","display_name":"OAKPOINT HOLDINGS LLC","kind":"org","parcels":37,"counties":["13153","13021"],"by_county":{"13153":30,"13021":7},"mailing_states":["GA"],"entry_ids":["13153_OAKPOINT_HOLDINGS_LLC","13021_OAKPOINT_HOLDINGS_LLC"]}]}],"count":1}}}},"400":{"description":"Body was not a JSON object, `names` / `owner_ids` were not lists of strings, both were empty, there were more than 500, or `county` was not five digits."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."}}}},"/v1/owners/{entry_id}/parcels":{"get":{"tags":["Owners"],"summary":"List every parcel one owner holds, in every county","description":"An owner's whole portfolio as a parcel list: the same rows, filters and paging as `GET /counties/{fips}/parcels`, across every county the owner holds in, with an `owner` block that says who it is and what each county holds.\n\n### `scope`\n\n| Value | The parcels of |\n|---|---|\n| `identity` (default) | The same owner in every county: every entry the matcher linked by name and mailing address (`identity_id`). An owner the matcher has not linked yet is answered as `entry`, and `owner.scope` says so. |\n| `entry` | This entry alone: one county, one name at one mailing address. |\n| `mailing` | Every owner, in any county, whose mailing address is this owner's (street line and five-digit ZIP) - the LLCs and people that share one office or PO box. |\n\nA parcel is on the list when the owner is on its current owner line, co-ownership included - the parcels `parcel_count` counts. An all-digits path is read as an `identity_id` (always scope `identity`).\n\n### Paging and outlines\n\n`limit` 1-500 (default 100) and `cursor`: feed `next_cursor` back as `cursor=` until it is `null`, so a portfolio of any size is listed whole. `geometry=1` adds each lot's outline (GeoJSON) to its row. Every parcel filter (`min_value`, `home_type`, `fields`, ...) applies on top.\n\n### `owner`\n\n`entry_id`, `display_name`, `kind`, `county_fips`, `identity_id`, `identity_name`, `mailing_*`, `scope` (the one used), `parcel_count` and `total_value` (the entries' own counts added up), `entries_total` and `entries[]` (up to 200, biggest first: `entry_id`, `county_fips`, `county_name`, `display_name`, `parcel_count`, `total_value`, ...). `total` is the exact number of distinct parcels on the list.","operationId":"owner_parcels_v1_owners__entry_id__parcels_get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","description":"An owner entry id (`13153_CHONG_AARON_H`), or an `identity_id`.","title":"Entry Id"},"description":"An owner entry id (`13153_CHONG_AARON_H`), or an `identity_id`."}],"responses":{"200":{"description":"The owner and one page of what they hold.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerPortfolio"},"example":{"owner":{"entry_id":"13153_OAKPOINT_HOLDINGS_LLC","display_name":"OAKPOINT HOLDINGS LLC","kind":"org","county_fips":"13153","identity_id":9,"identity_name":"OAKPOINT HOLDINGS LLC","scope":"identity","mailing_address":"PO BOX 100","mailing_city":"MACON","mailing_state":"GA","mailing_zip":"31201","parcel_count":37,"total_value":5120400,"entries_total":2,"entries":[{"entry_id":"13153_OAKPOINT_HOLDINGS_LLC","county_fips":"13153","county_name":"Houston","display_name":"OAKPOINT HOLDINGS LLC","kind":"org","parcel_count":30,"total_value":4200100,"identity_id":9,"mailing_address":"PO BOX 100","mailing_city":"MACON","mailing_state":"GA","mailing_zip":"31201"},{"entry_id":"13021_OAKPOINT_HOLDINGS_LLC","county_fips":"13021","county_name":"Bibb","display_name":"OAKPOINT HOLDINGS LLC","kind":"org","parcel_count":7,"total_value":920300,"identity_id":9,"mailing_address":"PO BOX 100","mailing_city":"MACON","mailing_state":"GA","mailing_zip":"31201"}]},"items":[{"property_id":"13153-0W050J08B000","county_fips":"13153","state":"GA","parcel_id_norm":"0W050J08B000","parcel_id_raw":"0W050J    08B000","account_number":"13554","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_state":"GA","situs_zip":"31088","owner_name":"SMITH JOHN A","owner_names":["SMITH JOHN A","SMITH MARY B"],"owner_address":"109 FREEMAN DR","owner_city":"WARNER ROBINS","owner_state":"GA","owner_zip":"31088","owner_occupied":true,"owner_id":"13153_SMITH_JOHN_A","owner_verified":true,"owner_display":"SMITH, JOHN A","property_class":"R3","property_use":"Residential","zoning":"R-1","tax_district":"COUNTY","homestead":true,"land_acres":0.46,"building_count":1,"building_style":"RANCH","year_built":1978,"heated_sqft":1684,"bedrooms":3,"full_baths":2,"half_baths":0,"condition":"AVERAGE","last_sale_date":"2019-06-14","last_sale_price":132000,"assessed_year":2025,"land_value":18000,"improvement_value":141200,"total_value":159200,"est_annual_tax":1234.5,"latitude":32.6105,"longitude":-83.6219,"geocode_source":"gis","geocode_precision":"parcel","photo_count":2,"sketch_count":1,"sources":["arcgis","qpublic"],"source_urls":{"qpublic":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000"},"record_url":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000","last_seen_at":"2026-09-14T03:21:55+00:00","updated_at":"2026-09-14T03:21:55+00:00","home_type":"single_family","home_type_basis":"inferred","zillow":{"zpid":35956751,"status":"recently_sold","status_at":"2026-09-30","sold_seen":"2026-09-30","price":214000,"url":"https://www.zillow.com/homedetails/109-Freeman-Dr-Warner-Robins-GA-31088/35956751_zpid/"},"messy_title_likely":false,"messy_title_reasons":[]}],"count":1,"total":37,"next_cursor":4812}}}},"400":{"description":"`scope` is not one of identity, entry, mailing; `scope=mailing` for an owner with no mailing street and ZIP; or a parcel filter was malformed."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No owner with that id."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owners/{entry_id}":{"get":{"tags":["Owners"],"summary":"Show one owner","description":"One owner on one page: the entry, the property it holds in that county, the same owner in every other county, the pairs still open against it and the history of what humans have ruled.\n\n| Field | What it holds |\n|---|---|\n| `parcels[]` | Up to 500 parcels this owner is named on in this county, most valuable first, each by its property id. |\n| `same_owner_elsewhere[]` | The other entries the matcher put in the same identity - the same owner, another county. |\n| `keys[]` | Every spelling merged into that identity. |\n| `candidates[]` | Up to 200 pairs touching any of those spellings, each with the verdict fields. |\n| `decisions[]` | Up to 200 rulings on them, newest first. |\n| `verified` | An admin has confirmed this owner. `verified_by` is who, or null when the flag is the matcher's own (see `POST /owners/{entry_id}/verify`). |\n\n**The identity id still works.** An all-digits path is read as `owner_identities.id` and answers the older shape - the identity, its keys, its parcels, its pairs - because the review page links there.\n\nEvery pair carries **two verdicts**:\n\n  * `auto_verdict` - what the matcher decided. `true` = it merged the pair, `false` = it held them apart. It never moves when a human rules.\n  * `admin_verdict` - what a human decided, read off `status`: `confirmed` → `true`, `rejected` → `false`, anything else → `null` (nobody has ruled).\n  * `effective_verdict` - the one that counts: the admin's if there is one, the machine's otherwise.\n  * `overridden` - `true` when the two disagree.\n\nThat is the whole product: the machine decides everything, a human thumbs it up or\ndown, and either way the decision is recorded and trains the rule that produced it.","operationId":"owner_detail_v1_owners__entry_id__get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","description":"An owner entry id (`13153_CHONG_AARON_H`), or an `owner_identities.id` for the older shape.","title":"Entry Id"},"description":"An owner entry id (`13153_CHONG_AARON_H`), or an `owner_identities.id` for the older shape."}],"responses":{"200":{"description":"The owner, what they hold, and the evidence behind them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerDetail"},"example":{"entry_id":"13153_SMITH_JOHN_A","county_fips":"13153","county_name":"Houston","display_name":"SMITH, JOHN A","kind":"person","last":"SMITH","first":"JOHN","middle":"A","seq_n":1,"mailing_address":"109 FREEMAN DR","mailing_city":"WARNER ROBINS","mailing_state":"GA","mailing_zip":"31088","mailing_addresses":["109 FREEMAN DR WARNER ROBINS GA 31088"],"parcel_count":7,"buyer_id":"BID-000123","verified":true,"verified_by":"blaine","verified_at":"2026-09-18T14:02:00+00:00","identity_id":51204,"identity_name":"SMITH JOHN","key":"P|SMITH|JOHN|A||1f2e3d4c","first_seen_at":"2026-09-14T04:26:31+00:00","updated_at":"2026-09-19T04:26:31+00:00","parcels":[{"property_id":"13153-0W050J08B000","county_fips":"13153","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_zip":"31088","owner_name":"SMITH JOHN A","total_value":159200,"last_sale_date":"2019-06-14","last_sale_price":132000,"owner_verified":true}],"same_owner_elsewhere":[{"entry_id":"13021_SMITH_JOHN_A","county_fips":"13021","county_name":"Bibb","display_name":"SMITH, JOHN A","parcel_count":2,"verified":false}],"keys":[{"key":"P|SMITH|JOHN|A||1f2e3d4c","display":"SMITH JOHN A","kind":"person","method":"auto","n_mentions":9,"addrs":["109 FREEMAN DR WARNER ROBINS GA 31088"],"counties":["13153"]}],"candidates":[{"id":8841,"a_key":"P|SMITH|JOHN|A||1f2e3d4c","b_key":"P|SMITH|JOHN|A||9c4d1a77","score":0.93,"rule":"same_name_nearby_addr","status":"pending","reasons":["exact surname"],"auto_verdict":true,"other_key":"P|SMITH|JOHN|A||9c4d1a77","other_display":"SMITH JOHN A","effective_verdict":true,"overridden":false}],"decisions":[{"id":77,"a_key":"P|SMITH|JOHN|A||1f2e3d4c","b_key":"P|SMITH|J|A||1f2e3d4c","decision":"confirm","decided_by":"blaine","decided_at":"2026-09-15T18:04:00+00:00","rule":"same_addr_initial","score":0.88}]}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No owner with that id."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/match/buyers":{"get":{"tags":["Links / buyer matching"],"summary":"Rank likely buyers for a property","description":"Given one property, rank the investors most likely to want it. The UI calls this **Links**.\n\nCandidates are real buyers of real property nearby: every qualifying purchase with a known buyer inside the radius, grouped per buyer, then scored. The target's own sale history is excluded, or a property would nominate its current owner every time. Government agencies are dropped before scoring (the VA takes back hundreds of houses on foreclosure and is not somebody you can sell to) unless you pass `include_gov=1`.\n\n### Naming the property\n\nEither `property_id` (preferred) or `q` is required; without one it is a **400**. An address that matches several properties answers **300** with a `candidates` list instead of guessing - retry with one of their property ids. `county` narrows an address search.\n\n### Parameters\n\n| Parameter | Meaning |\n|---|---|\n| `property_id` | The id, `{fips}-{apn}`. A malformed one is a **400**. |\n| `q` | Street address. Must contain a street. |\n| `county` | Five-digit FIPS, narrows `q`. |\n| `radius_miles` | 0.1-25, default 10. |\n| `limit` | Buyers returned, 1-100, default 25. |\n| `include_gov` | `1`/`true`/`yes`/`on` keeps agencies in. |\n| `voter_id` | Your voter; fills each buyer's `votes.mine`. Up to 64 characters. |\n\n### Local Buyers filters\n\nWho bought lots like this one nearby lately, and holds enough to matter. Every filter is optional and they combine; the ranking of whoever is left is unchanged.\n\n| Parameter | Meaning |\n|---|---|\n| `months` | Only purchases in the last N months (1-600) count: the candidates, their `purchases`, `nearby` and the proximity and recency they score on. |\n| `bought_after` | The same window as a date, `YYYY-MM-DD`. Pass one of `months` and `bought_after`, not both (**400**). |\n| `same_type` | `1`: only purchases in this property's type bucket (`sfr`, `multifamily`, `land`, `mobile_home`, `commercial`, `other`). Ignored when the target has none. |\n| `min_owned_ever` | Keep buyers who have owned at least N lots (`owned_ever`). |\n| `min_owned_now` | Keep buyers who own at least N lots today (`owned_now`). |\n| `absentee` | `1`: keep buyers who bought one of these lots to hold, not to live in; `0`: keep only owner-occupant buyers. A buyer whose `absentee` is null meets neither. |\n\nEach buyer carries the three numbers the filters read:\n\n| Field | What it holds |\n|---|---|\n| `owned_now` | Parcels on the current roll in this buyer's name, every county. |\n| `owned_ever` | Every distinct lot a qualifying deed on file shows them buying, plus the lots on the roll in their name that no such deed covers. A lot bought and still held counts once. Deeds go back as far as each county publishes them, so this is a floor, not a lifetime census. |\n| `absentee` | `true` for an org or an agency, and for a person or trust when one of these lots is not at one of their mailing addresses; `false` when every one is; `null` when there is no address to compare. |\n\n`filters` echoes what was applied (`bought_after` is the cutoff a `months` value worked out to; `type_bucket` the bucket `same_type` kept) and `excluded_by_filters` counts the buyers the requirements removed.\n\nIf fewer than `limit` buyers survive at a radius under 10 miles, the search widens to 10 and `widened` is `true`.\n\n### How it ranks\n\nSeven signals, each 0-1, times its weight (`GET /match/weights`; defaults below). Six come from the buyer's purchase history and sum to 100; `human_signal` adds the votes.\n\n| Component | Weight | Measures |\n|---|---|---|\n| `proximity` | 25 | How much they already buy near this property. |\n| `price` | 20 | Their median purchase against this property's price. |\n| `type` | 20 | The share of their purchases in this property's type bucket. |\n| `recency` | 20 | How recently, and how steadily, they buy. |\n| `frequency` | 10 | How many qualifying purchases they have. |\n| `characteristics` | 5 | Square feet, beds, baths and acres against their typical buy. |\n| `human_signal` | 15 | The votes on this buyer, here and everywhere; 0.5 for everyone until somebody votes. |\n\nA missing input scores 0 for that component rather than inventing a number.\n\n### Reading the answer\n\n`score` is 0-100, **normalised to the weights in force**: `round(points / sum(weights) * 100, 1)`. `points` is the raw weighted sum of `components`, each of which shows its own `value`, `weight` and `points`, and `weights` in the answer is the set in force, so the arithmetic is auditable. The ranking sorts on `points`. `evidence` is the same reasoning in sentences. `nearby` counts their purchases by distance band, `purchases` lists up to ten of them (the counts use all of them), and `mailing_addresses` is where a skip-trace starts.\n\n### Votes\n\nUsers vote on each suggested buyer with `POST /match/votes` (a user counts 1, an admin 2). Every buyer carries `votes` - the weighted `up`, `down` and `net` on this property, and `mine`, the vote of the `voter_id` you pass (your key's own voters only), and `own`, your key's own totals and the status they alone add up to. Only trusted keys' votes count in `up`, `down`, `net`, the status and the score; for a caller whose key is not trusted, `up`, `down`, `net`, `status` and the pins and hides are its own key's votes alone. `status` is `verified` when `net` reaches the threshold (2 by default), and the buyer is pinned to the front with `pinned: true`; `rejected` at minus the threshold, and the buyer moves into `hidden[]`; `auto` in between. The votes also move the score through `components.human_signal` (weight 15; 0.5, its midpoint, for every buyer when nobody has voted, so an unvoted ranking is unchanged). A buyer with 3 weighted down votes across properties and no up vote anywhere is dropped before scoring and counted in `excluded_flagged`; a name that hits an `exclude_buyer` rule is dropped too, counted in `excluded_by_rule`. `rematch` is the newest vote event on this property (`at`, `kind`, `reason`), or null: the ranking is computed live, so the call after a vote already reflects it.\n\n`feedback` and `feedback_totals` are the pre-0.16 fields, kept for old readers: the newest vote on the pair in the verdict shape, and the buyer's weighted ups and downs everywhere.\n\nA target with no coordinates answers 200 with empty `buyers` and a `note` saying so - there is nothing to measure distance from.","operationId":"match_buyers_v1_match_buyers_get","responses":{"200":{"description":"The ranked buyers, with the target and the weights that produced them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuyerMatchResult"},"example":{"target":{"property_id":"13153-0W050J08B000","county_fips":"13153","latitude":32.6105,"longitude":-83.6219,"type_bucket":"sfr","price":159200.0,"heated_sqft":1684.0,"bedrooms":3.0,"full_baths":2.0,"land_acres":0.46,"year_built":1978,"situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","total_value":159200.0,"last_sale_date":"2019-06-14","last_sale_price":132000.0},"radius_miles":10.0,"widened":false,"candidates":38,"excluded_flagged":1,"excluded_by_rule":0,"include_gov":false,"weights":{"proximity":25.0,"price":20.0,"type":20.0,"recency":20.0,"frequency":10.0,"characteristics":5.0,"human_signal":15.0},"generated_at":"2026-09-29T14:02:12+00:00","buyers":[{"rank":1,"identity_id":51204,"name":"OAKPOINT HOLDINGS LLC","kind":"org","buyer_id":"BID-000123","entry_ids":["13153_OAKPOINT_HOLDINGS_LLC"],"score":72.1,"points":82.9,"components":{"proximity":{"value":0.82,"weight":25.0,"points":20.5},"price":{"value":0.91,"weight":20.0,"points":18.2},"type":{"value":0.75,"weight":20.0,"points":15.0},"recency":{"value":0.6,"weight":20.0,"points":12.0},"frequency":{"value":0.4,"weight":10.0,"points":4.0},"characteristics":{"value":0.34,"weight":5.0,"points":1.7},"human_signal":{"value":0.7666,"weight":15.0,"points":11.5}},"evidence":["4 purchases within 1 mile, nearest 0.3 mi","buys single-family in this price band (median $148,000)","last purchase 3 months ago"],"stats":{"purchases":31,"purchases_12m":6,"purchases_24m":11,"avg_price":151200.0,"median_price":148000.0,"first_purchase":"2017-03-02","last_purchase":"2026-06-11","counties":["13153"],"cities":["WARNER ROBINS"],"type_mix":{"sfr":0.87,"land":0.13},"flip_rate":0.29,"median_hold_months":14.0,"distressed_share":0.19},"nearby":{"within_1mi":4,"within_3mi":9,"within_10mi":17,"nearest_miles":0.31},"purchases":[{"transaction_id":99213,"property_id":"13153-0W050J11C000","situs_address":"127 FREEMAN DR","situs_city":"WARNER ROBINS","county_fips":"13153","sale_date":"2026-06-11","sale_price":142000.0,"type_bucket":"sfr","distance_miles":0.31,"flags":[]}],"mailing_addresses":["PO BOX 1180 WARNER ROBINS GA 31099"],"owned_ever":44,"owned_now":27,"absentee":true,"votes":{"up":2,"down":0,"net":2,"mine":"up","own":{"up":2,"down":0,"net":2,"status":"verified"}},"feedback":{"id":88,"property_id":"13153-0W050J08B000","identity_id":51204,"verdict":true,"decided_by":"u_1842","voter_role":"admin","weight":2,"decided_at":"2026-09-29T14:02:11+00:00"},"feedback_totals":{"up":5,"down":1},"status":"verified","pinned":true}],"hidden":[],"rematch":{"at":"2026-09-29T14:02:11+00:00","kind":"verified","reason":"BID-000123 was verified on this property (net +2, threshold 2)"}}}}},"400":{"description":"No property was named, `property_id` was malformed, `q` held no street, `radius_miles`/`limit` was out of range, or `voter_id` was longer than 64 characters."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No property matched."},"300":{"description":"The address matched several properties; retry with one of the property ids returned.","content":{"application/json":{"example":{"candidates":[{"property_id":"13153-0W050J08B000","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","county_fips":"13153"},{"property_id":"13021-1180024000","situs_address":"109 FREEMAN DR","situs_city":"MACON","county_fips":"13021"}],"detail":"2 properties match that address; retry with property_id"}}}}}}},"/v1/match/votes":{"get":{"tags":["Links / buyer matching"],"summary":"List votes","description":"The votes behind the ranking.\n\n**With a customer key** it is your own votes: `property_id` is required, and `items` holds only the votes your key sent on that property (narrow to one person with `voter_id`). `by_buyer` is every voted buyer on the property, keyed by `buyer_id` (`identity:<id>` for a buyer without one yet), with the weighted `up`, `down`, `net` of **all** voters and the `status` they add up to (trusted keys' votes only, as the ranking counts them), plus `own`, your key's totals and status alone. Each item says whether it is `counted`.\n\n**With an admin key** it is every key's votes, newest first, with `key_name` and the buyer's `name`, filtered by any of `property_id`, `voter_id`, `key_id` (`0` = the master token), `since` (ISO date or date-time), and paged with `limit` (1-500, default 100) and `offset`; `total` counts the filtered set. `by_buyer` is added when `property_id` is given. A customer key asking for another key's votes is a **403**.","operationId":"get_votes_v1_match_votes_get","responses":{"200":{"description":"Your votes on the property and the totals per buyer (admin: every key's, paged).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchVoteList"},"example":{"items":[{"id":88,"property_id":"13153-0W050J08B000","buyer_id":"BID-000123","identity_id":51204,"voter_id":"u_1842","voter_role":"user","weight":1,"key_id":7,"vote":"up","note":"bought two doors down last month","voted_at":"2026-09-29T14:02:11+00:00","counted":true}],"by_buyer":{"BID-000123":{"buyer_id":"BID-000123","identity_id":51204,"up":3,"down":1,"net":2,"status":"verified","own":{"up":1,"down":0,"net":1,"status":"auto"}}}}}}},"400":{"description":"`property_id` was missing (customer keys) or malformed, or a filter or paging value could not be read."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"403":{"description":"A customer key asked for another key's votes."},"404":{"description":"No property with that id."}}},"post":{"tags":["Links / buyer matching"],"summary":"Vote on one buyer for one property","description":"A thumbs up or down from one of your users on one buyer suggested for one property.\n\n**This is the one write a `read` key may make**: the vote is your user's own opinion, it is stored against your key, and only your key can replace or withdraw it.\n\n| Field | Meaning |\n|---|---|\n| `property_id` | The property, `{fips}-{apn}`. |\n| `buyer_id` or `identity_id` | The buyer, as `/match/buyers` named it. If both are sent, `identity_id` wins. |\n| `voter_id` | Your stable id for the person voting, up to 64 characters. One vote per voter per buyer per property. |\n| `voter_role` | `user` (weight 1, the default) or `admin` (weight 2). |\n| `vote` | `up`, `down`, or `null` to withdraw. **Must be present**; a missing key is a 400, so a client that forgot it cannot erase a vote. |\n| `note` | Optional, up to 2,000 characters. |\n\nA repeat vote by the same voter replaces the old one.\n\n### The answer\n\n`vote` is the stored row (`null` once withdrawn). `totals` is the pair's weighted `up`, `down` and `net` across every voter. `status` is `verified` when `net` reaches the threshold (2 by default: one admin, or two users), `rejected` at minus the threshold, `auto` otherwise. `crossed` is `true` when this vote changed the status. `rematch` is the newest vote event on the property (`at`, `kind`, `reason`): the ranking is computed live, so the next `GET /match/buyers` already reflects it.\n\n### Whose votes count\n\nFor a trusted key (PARCEL sets `vote_trust`; keys holding `admin` always are), `totals`, `status` and `crossed` are the **shared** view: the votes of trusted keys only. For a key that is not trusted they are its own votes alone - its status, never from or into anyone else's. `counted` says whether this vote is part of the shared view; `own` is always your key's own totals and status. An untrusted key's `voter_role: \"admin\"` is recorded as `user`, weight 1.\n\nA `voter_id` another key already used on this pair is a **409** `vote_conflict`: prefix your voter ids (`presaling:1842`) and it never happens.","operationId":"post_vote_v1_match_votes_post","requestBody":{"description":"`property_id`, `buyer_id` (or `identity_id`), `voter_id` and `vote` are required; `voter_role` defaults to `user`; `note` is optional.","content":{"application/json":{"example":{"property_id":"13153-0W050J08B000","buyer_id":"BID-000123","voter_id":"u_1842","voter_role":"user","vote":"up","note":"bought two doors down last month"}}},"required":true},"responses":{"200":{"description":"The vote was stored (or withdrawn), with what the pair now adds up to.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchVoteResult"},"example":{"ok":true,"vote":{"id":88,"property_id":"13153-0W050J08B000","buyer_id":"BID-000123","identity_id":51204,"voter_id":"u_1842","voter_role":"user","weight":1,"key_id":7,"vote":"up","note":"bought two doors down last month","voted_at":"2026-09-29T14:02:11+00:00","counted":true},"totals":{"up":3,"down":1,"net":2},"status":"verified","crossed":true,"counted":true,"own":{"up":1,"down":0,"net":1,"status":"auto"},"rematch":{"at":"2026-09-29T14:02:11+00:00","kind":"verified","reason":"BID-000123 was verified on this property (net +2, threshold 2)"}}}}},"400":{"description":"Body was not a JSON object, or a field was missing or malformed - the message names it."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No property, or no buyer, with that id."},"409":{"description":"That `voter_id` already voted on this pair through another key (`vote_conflict`)."},"422":{"description":"The property is in a use-restricted county (`use_restricted`)."}}}},"/v1/buyers/{buyer_id}":{"get":{"tags":["Links / buyer matching"],"summary":"Show one buyer","description":"One investor: the entities they buy through, what they have bought, and the profile the ranking scores them on.\n\n`buyer_id` is `BID-000123` - one number for the firm behind every entity and every county, minted the first time they appear as the grantee of a qualifying purchase.\n\n**A retired number still resolves.** When two investors are later proved to be one, the newer number is retired with a pointer to the survivor; asking for it answers with the survivor, `retired: true` and `requested` naming what you asked for.\n\n| Field | What it holds |\n|---|---|\n| `entries[]` | Every owner entry that belongs to this buyer - one per county and name. |\n| `stats` | The buyer_stats profile: price band, type mix, counties, flip rate, hold months. |\n| `purchases[]` | The 50 newest qualifying purchases, by property id. |","operationId":"buyer_detail_v1_buyers__buyer_id__get","parameters":[{"name":"buyer_id","in":"path","required":true,"schema":{"type":"string","description":"A buyer id, `BID-000123`.","title":"Buyer Id"},"description":"A buyer id, `BID-000123`."}],"responses":{"200":{"description":"The investor, their entities and their purchases.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuyerDetail"},"example":{"buyer_id":"BID-000123","requested":"BID-000123","retired":false,"name":"OAKPOINT HOLDINGS LLC","kind":"org","created_at":"2026-09-19T04:26:31+00:00","identity_ids":[51204],"entries":[{"entry_id":"13153_OAKPOINT_HOLDINGS_LLC","county_fips":"13153","county_name":"Houston","display_name":"OAKPOINT HOLDINGS LLC","parcel_count":31,"verified":false}],"stats":{"purchases":31,"purchases_12m":6,"purchases_24m":11,"avg_price":151200.0,"median_price":148000.0,"first_purchase":"2017-03-02","last_purchase":"2026-06-11","counties":["13153"],"cities":["WARNER ROBINS"],"type_mix":{"sfr":0.87,"land":0.13},"flip_rate":0.29,"median_hold_months":14.0,"distressed_share":0.19},"purchases":[{"property_id":"13153-0W050J11C000","county_fips":"13153","situs_address":"127 FREEMAN DR","situs_city":"WARNER ROBINS","sale_date":"2026-06-11","sale_price":142000.0,"type_bucket":"sfr","flags":[]}]}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No buyer with that id."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/buyers":{"get":{"tags":["Links / buyer matching"],"summary":"Search buyers","description":"Find an investor by name.\n\n`q` is a substring of the investor's name, which is the canonical name of the entity the buyer id was minted from. Ordered by purchases, so the most active buyer matching the name comes first. Without `q` it is the most active buyers overall.\n\nThe same search asked again within five minutes is answered from memory: investors and their purchase counts change only when the nightly match build runs. The answer carries an `ETag`; send it back as `If-None-Match` for a `304`.\n\n| Parameter | Meaning |\n|---|---|\n| `q` | Substring of the buyer's name. |\n| `min_purchases` | Keep buyers with at least this many qualifying purchases. |\n| `county` | Five-digit FIPS; keeps buyers who have bought there. |\n| `limit` | 1-50, default 50. |","operationId":"buyer_list_v1_buyers_get","responses":{"200":{"description":"Matching buyers, most active first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuyerList"},"example":{"items":[{"buyer_id":"BID-000123","name":"OAKPOINT HOLDINGS LLC","purchases":31,"last_purchase":"2026-06-11","counties":["13153"]}],"total":1}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."}}}},"/v1/usage":{"get":{"tags":["Keys & usage"],"summary":"Show your own usage this month","description":"What **your** key has spent this calendar month, and what it is allowed to spend. This is the one route in this group a customer can call: it needs `read`, and it only ever reports the key that made the request.\n\n`by_day` and `by_family` break the month down - a *family* is the product area a route belongs to (`Parcels`, `Counties`, `Images`, `Owners`, `Links / buyer matching`), which is the grain an invoice is written at. `errors` counts responses of 400 and above, so a month of 404s is visible before it becomes a surprise.\n\n`used` is live and includes requests not yet written to the meter; `totals.requests` is what the table holds and can trail it by up to fifteen seconds. `quota` and `remaining` are null for a plan with no monthly ceiling - usage is still metered, it simply is not capped. `resets_at` is midnight UTC on the first of next month.\n\n`?month=YYYY-MM` reads a past month; the default is this one.","operationId":"my_usage_v1_usage_get","parameters":[{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`YYYY-MM`. Defaults to this month.","title":"Month"},"description":"`YYYY-MM`. Defaults to this month."}],"responses":{"200":{"description":"Your key's month.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"},"example":{"key":"acme-corp","key_id":3,"plan":"starter","month":"2026-09","quota":100000,"used":41208,"remaining":58792,"resets_at":"2026-10-01T00:00:00+00:00","rate_limit_per_min":300,"by_day":[{"day":"2026-09-17","requests":20110,"errors":14},{"day":"2026-09-18","requests":21098,"errors":3}],"by_family":[{"family":"Parcels","requests":39902,"errors":17},{"family":"Images","requests":1306,"errors":0}],"totals":{"requests":41208,"errors":17}}}}},"400":{"description":"`month` was not `YYYY-MM`."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parcels/{property_id}/comps":{"get":{"tags":["Parcels"],"summary":"Find comparable recent sales near a parcel","description":"Recent sales near one property that look like it - the comps - in one call.\n\nA comp is a sale recorded in the last `months`, priced over $1,000 (at or\nunder that it is a transfer, not a price), on a parcel whose own point is inside\nthe circle around the subject, which is not the subject, and whose record fits\nevery range below. The sale is any in the parcel's sale history, or its last sale\nwhere the county publishes no history. **One comp per property**: its newest\nqualifying sale in the window. The circle crosses county lines.\n\n### Parameters\n\n| Parameter | Meaning |\n|---|---|\n| `radius_m` | Metres around the subject, 1-8047, default 1609 (a mile). Over five miles is a **422** `radius_too_large`. |\n| `months` | Sold within this many months, 1-60, default 24. |\n| `beds` | Bedrooms, the subject's plus or minus this, 0-10, default 1 (`0` = exactly). |\n| `baths` | Baths (full, plus half a bath per half bath), plus or minus this, 0-10, default 1. |\n| `sqft_pct` | Heated square feet within this percent of the subject's, 0-100, default 25. |\n| `lot_pct` | Lot acres within this percent of the subject's, 0-500, default 50. |\n| `year` | Year built, the subject's plus or minus this many years, 0-100. **Off unless sent** (`year=15` keeps houses built within 15 years of the subject's). |\n| `same_type` | `1` (default) keeps comps of the subject's `type_bucket` (`sfr`, `multifamily`, `land`, `mobile_home`, `commercial`); `0` keeps every type. |\n| `arms_length` | `1` (default) skips sales whose county reason marks them as not a purchase - quit-claims, family and estate transfers, corrections (the same rules that decide which sales count for buyer matching). A lot whose newest sale was one comps on the purchase before it instead. `0` keeps every priced sale. |\n| `limit` | Comps returned, 1-200, default 25. |\n| `order` | `distance` (default, nearest first), `similarity` (most similar first) or `recent` (newest sale first). Ties go to the nearer comp. |\n| `widen` | `1` (default): fewer than `limit` comps and the circle doubles once, never past five miles. `0` keeps the radius exactly. |\n| `fields` | Comma-separated subset of a comp's fields; `property_id` is always kept. Unknown name: **400**. |\n| `geometry` | `1` adds each comp's parcel polygon (`geometry`), excluded by default because it is large. Also on with `fields=...,geometry`. |\n\nAny of `beds`, `baths`, `sqft_pct`, `lot_pct`, `year` may be **`any`**, which\nswitches that range off - the answer for a county that records no bedrooms at all.\n\n### Measures nobody recorded\n\nZero is \"not recorded\", never a zero-bedroom house, and comes back `null`. When\nthe **subject** lacks a measure its range is switched off, and `ranges.off` says\nwhich and why: `subject_missing`, `any` (switched off - by you, or for `year`\nbecause you did not send it), or, for `type_bucket`, `subject_other` (the\nsubject's type is none of the buckets, so there is nothing to match on). A comp\nlacking a measure a range needs is not a comp.\n\n### Reading the answer\n\n`subject` is the property's own facts. `ranges` is what was applied: `radius_m`\n(after any widening) beside `radius_requested_m`, the window `sold_after` to\n`sold_before`, `arms_length`, each range as `{min, max}` with the parameter that\nmade it (null when off), and `type_bucket`. Each comp carries its sale\n(`sale_date`, `sale_price`, `price_per_sqft`), `distance_m`, the parcel's key facts\nand **`similarity`**, 0-1: for every range in force, 1 at the subject's own figure\nand 0 at the edge of the plus-or-minus, averaged (null when no range was in force).\n\nEach comp also says what kind of sale it was. `sale_reason` is the county's own\ntransfer reason, verbatim, or null where the county records none (most counties\noutside qPublic's). **`arms_length`** is `true` when that reason is a purchase,\n`false` when it is not (only with `arms_length=0`), and `null` when there was no\nreason to judge. `sale_flags` lists what a sale that still counts carries:\n`distressed` (foreclosure, bank or judgment sale), `multi_parcel` (the price\ncovers more than this lot: the county's reason says so, the deed is shared with\nother parcels, or a client flagged it with `POST /sales/flags`) or `unvalidated`\n(the assessor did not verify it).\n\n**`summary`** is over the comps returned, so it follows `limit` and every range:\n`median_sale_price`, `median_price_per_sqft`, and how many comps each median was\ntaken over (`with_sale_price`, `with_price_per_sqft`; a comp with no recorded size\nhas a price but no price per square foot). `fields=` does not narrow it.\n\n`count` is the comps returned, `matched` is how many passed every filter before\n`limit`, `widened` says the radius grew, and `capped` says more than\n2,000 candidate sales sat inside the circle, so `matched` is a floor\nand the nearest 2,000 were the pool; a capped pool never widens.\n\nA subject with no coordinates answers 200 with no comps and a `note` - there is\nnothing to measure distance from. The answer carries an `ETag` and\n`Cache-Control: private, max-age=60`, and a matching `If-None-Match` is a `304`.","operationId":"parcel_comps_v1_parcels__property_id__comps_get","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","description":"The subject's property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`.","title":"Property Id"},"description":"The subject's property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`."}],"responses":{"200":{"description":"The subject, the ranges applied and the comps, nearest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompsResult"},"example":{"subject":{"property_id":"13153-0W050J08B000","county_fips":"13153","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_zip":"31088","latitude":32.6105,"longitude":-83.6219,"type_bucket":"sfr","property_use":"Residential","heated_sqft":1684,"land_acres":0.46,"year_built":1978,"last_sale_date":"2019-06-14","last_sale_price":132000.0},"ranges":{"radius_m":1609.0,"radius_requested_m":1609.0,"months":24,"sold_after":"2024-09-29","sold_before":"2026-09-29","sale_price_over":1000,"arms_length":true,"heated_sqft":{"min":1263.0,"max":2105.0,"pct":25.0},"land_acres":{"min":0.23,"max":0.69,"pct":50.0},"year_built":{"min":1963.0,"max":1993.0,"plus_minus":15.0},"type_bucket":"sfr","off":{"bedrooms":"subject_missing","baths":"subject_missing"}},"items":[{"property_id":"13153-0W050J11C000","county_fips":"13153","situs_address":"127 FREEMAN DR","situs_city":"WARNER ROBINS","situs_zip":"31088","sale_date":"2026-06-11","sale_price":162000,"price_per_sqft":99.39,"sale_reason":"Fair Market Value","arms_length":true,"sale_flags":[],"distance_m":184.2,"similarity":0.914,"bedrooms":3,"baths":2.0,"full_baths":2,"heated_sqft":1630,"land_acres":0.41,"year_built":1981,"type_bucket":"sfr","property_use":"Residential","latitude":32.6118,"longitude":-83.6204}],"count":1,"matched":1,"widened":false,"capped":false,"order":"distance","summary":{"comps":1,"median_sale_price":162000,"median_price_per_sqft":99.39,"with_sale_price":1,"with_price_per_sqft":1}}}}},"304":{"description":"Not modified - the If-None-Match ETag still matches."},"400":{"description":"A parameter was not a number, was out of range, `order` was unknown, or `fields` named an unknown field."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel with that property id, or the id is malformed."},"422":{"description":"`radius_m` is over five miles; the body carries `code: \"radius_too_large\"` and the maximum."}}}},"/v1/sales":{"get":{"tags":["Parcels"],"summary":"List every recorded sale in an area","description":"One row per recorded deed on every parcel inside a box or a circle, sold inside a window - the full sale history of an area in one call, newest first, each with the parcel's id, point and use word. Where a county records only each lot's last sale (ArcGIS, file, ORKA and Socrata counties), that sale is the row, with `sale_id: null` and `source: \"last_sale\"`.\n\n### Parameters\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `w,s,e,n`, at most **0.1 square degrees** (about 33 x 33 km at Georgia's latitude); larger is a **422** `bbox_too_large`. |\n| `near`, `radius_m` | A circle instead: `lat,lng` and metres (default 1000, at most 8047, five miles; wider is a **422** `radius_too_large`). Pass `bbox` or `near`, not both. |\n| `sold_after`, `sold_before` | The window, `YYYY-MM-DD`, both inclusive (`from` / `to` are the same). Default: the last 12 months to today. |\n| `transfers` | `0` (default): no deed at $1,000 or less. `1`: every recorded deed, $0 family transfers included - slower on an area not read lately. |\n| `arms_length` | `1`: drop sales whose `arms_length` is `false`. |\n| `use` | Comma list of use words: only parcels of those uses. |\n| `limit`, `offset` | Rows per page (1-5,000, default 1,000) and the page start (at most 100,000). `truncated: true` means there is another page at `next_offset`. |\n\n### Each row\n\n| Field | What it holds |\n|---|---|\n| `property_id`, `county_fips` | The parcel, as every route names it. |\n| `latitude`, `longitude` | The parcel's point. |\n| `situs_address`, `situs_city` | Its address. |\n| `property_use` | The normalised use word: `residential`, `commercial`, `agricultural`, `industrial`, `exempt`, `vacant` or `unknown`. |\n| `sale_id`, `source` | The deed row (`parcel_sales.id`), or `null` and `\"last_sale\"` for a parcel's own last sale where its county records nothing more. |\n| `sale_date`, `sale_price` | The deed. A null price is one the county did not record (non-disclosure states). |\n| `grantor`, `grantee` | Seller and buyer as the county wrote them. Null for a use-restricted county. |\n| `deed_type` | The county's deed or instrument type where it names one (`WD`, `QC`...); null for most counties. |\n| `deed_book_page`, `plat_book_page`, `reason` | The county's book references and transfer reason. |\n| `arms_length` | `false`: price $1,000 or less, or a reason a transfer rule excludes (quit-claim, family, estate, correction). `true`: a reason no rule excludes. `null`: the county gave no reason. |\n| `sale_flags` | `distressed`, `multi_parcel`, `unvalidated`: labels on a sale that still counts. |\n| `flag_sources` | Who set each flag: `{\"multi_parcel\": [\"county\", \"deed\"]}`. `county` is the county's own sale reason; `deed` is a deed shared with other parcels (`deed_parcels`); a key's name is a flag that key sent with `POST /sales/flags` (another customer's shows as `client`). |\n| `deed_parcels` | How many parcels of the county carry a sale that day under the same deed reference - 2 or more is a package sale, listed by `GET /parcels/{property_id}/sales/siblings`. Null where the deed reference names no deed. |\n| `qualified`, `disqualified_reason` | The buyer matcher's own verdict on the deed (`no_buyer`, `unpriced`, `excluded:<rule>`...). Null until the nightly match build has seen it. |\n| `grantee_owner_id` | The buyer as an owner we know: an `entry_id` for `GET /owners/{entry_id}` - theirs in the sale's county when they hold one there. Null until the nightly build links it, or when the buyer owns nothing on our rolls. |\n| `grantee_buyer_id` | The buyer's investor number, for `GET /buyers/{buyer_id}`. |\n| `grantee_mailing_state` | The buyer's mailing state (`GA`), for an out-of-state filter: their owner entry's, else on a lot's newest sale the lot's own owner mailing state. Null when neither is known, and for a use-restricted county. |\n\n`filters` echoes the area and the window used.","operationId":"list_sales_v1_sales_get","responses":{"200":{"description":"The sales in the area and window, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesPage"},"example":{"items":[{"property_id":"13153-0W050J11C000","county_fips":"13153","latitude":32.6102,"longitude":-83.6231,"situs_address":"127 FREEMAN DR","situs_city":"WARNER ROBINS","property_use":"residential","sale_id":9120031,"source":"qpublic","sale_date":"2026-06-11","sale_price":142000,"grantor":"SMITH JOHN A","grantee":"OAKPOINT HOLDINGS LLC","deed_book_page":"4431 / 207","reason":"Fair Market Value","arms_length":true,"sale_flags":[],"flag_sources":{},"deed_parcels":1,"qualified":true,"grantee_owner_id":"13153_OAKPOINT_HOLDINGS_LLC","grantee_buyer_id":"BID-000123","grantee_mailing_state":"GA"}],"count":1,"truncated":false,"filters":{"bbox":[-83.71,32.54,-83.54,32.69],"sold_after":"2025-10-09","sold_before":"2026-10-09","transfers":false,"arms_length":false}}}}},"400":{"description":"No area, both `bbox` and `near`, a malformed area, date, use word, flag or page number, or `sold_after` after `sold_before`."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"The area is over the maximum: `bbox_too_large` or `radius_too_large`, with the maximum in the body."}}}},"/v1/sales/histogram":{"get":{"tags":["Parcels"],"summary":"Count the sales in an area by period","description":"The sales `GET /sales` would list, counted by `bucket` - `day`, `week` (starting Monday, the default) or `month` - every period from the one holding `sold_after` to the one holding `sold_before`, empty ones included, so twelve months by week is one call with 53 buckets.\n\nEach bucket carries `start` and `end` (both inclusive), `sales`, `priced` (over $1,000), and the `median_price` and `total_price` of the priced ones. The top level carries the same over the whole window.\n\n### Parameters\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `w,s,e,n`, at most **0.1 square degrees** (about 33 x 33 km at Georgia's latitude); larger is a **422** `bbox_too_large`. |\n| `near`, `radius_m` | A circle instead: `lat,lng` and metres (default 1000, at most 8047, five miles; wider is a **422** `radius_too_large`). Pass `bbox` or `near`, not both. |\n| `sold_after`, `sold_before` | The window, `YYYY-MM-DD`, both inclusive (`from` / `to` are the same). Default: the last 12 months to today. |\n| `transfers` | `0` (default): no deed at $1,000 or less. `1`: every recorded deed, $0 family transfers included - slower on an area not read lately. |\n| `arms_length` | `1`: drop sales whose `arms_length` is `false`. |\n| `use` | Comma list of use words: only parcels of those uses. |\n| `bucket` | `day`, `week` or `month`. At most 1,000 buckets: a longer window needs a longer bucket (**400**). |","operationId":"sales_histogram_v1_sales_histogram_get","responses":{"200":{"description":"Sales per period over the window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesHistogram"},"example":{"bucket":"week","buckets":[{"start":"2026-09-28","end":"2026-10-04","sales":41,"priced":38,"median_price":189000,"total_price":7843500}],"sales":2255,"priced":2101,"median_price":205000,"filters":{"bbox":[-83.71,32.54,-83.54,32.69],"sold_after":"2025-10-09","sold_before":"2026-10-09","transfers":false,"arms_length":false}}}}},"400":{"description":"As `GET /sales`, or a `bucket` that is not day, week or month, or a window of more buckets than the maximum."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"The area is over the maximum."}}}},"/v1/parcels/{property_id}/sales/siblings":{"get":{"tags":["Parcels"],"summary":"List the other parcels on one sale's deed","description":"The parcels a county recorded on the same deed as one of this parcel's sales - what a \"$700k sale\" that was really four houses actually covered - for grouping a package sale.\n\n`sale_date` (required) picks the sale; `deed_book_page` narrows it when the parcel has two that day. A sibling is a parcel of the same county with a sale that day under the same deed reference (`via: deed`), or one a client flagged together with this parcel through `POST /sales/flags` (`via:` that key's name). A deed reference without a digit 1-9 names no deed; a reference over 200 parcels is a county's placeholder and lists nothing (`truncated: true`).","operationId":"deed_siblings_v1_parcels__property_id__sales_siblings_get","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","examples":["13153-0W050J08B000"],"title":"Property Id"}},{"name":"sale_date","in":"query","required":true,"schema":{"type":"string","description":"The sale's date, YYYY-MM-DD.","title":"Sale Date"},"description":"The sale's date, YYYY-MM-DD."},{"name":"deed_book_page","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Book Page"}}],"responses":{"200":{"description":"The other parcels on the deed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeedSiblings"},"example":{"property_id":"13021-N0740410","sale_date":"2025-12-12","deed_book_page":["12348 1"],"siblings":[{"property_id":"13021-N0740411","situs_address":"1033 MIMOSA DR","situs_city":"MACON","sale_price":770000,"deed_book_page":"12348 1","via":["deed","presaling-com-live-site-2026-10-12"]}],"count":1,"truncated":false}}}},"400":{"description":"`sale_date` is missing or not a date."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel by that id."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parcels/{property_id}/deeds":{"get":{"tags":["Parcels"],"summary":"List every deed a parcel is on, with the other parcels on each","description":"Every recorded deed of this parcel - its sale rows and its own last sale - as a deed record: `county_fips`, `deed_book_page`, `sale_date`, `price`, `parcel_count` and `parcels[]`, every parcel of the county recorded on that deed (this one included), newest deed first. `multi_parcel=1` keeps only the deeds that cover more than one parcel - the package sales, for grouping lots. A sale whose reference has no digit 1-9 names no deed and is left out; a reference over 200 parcels is a county's placeholder (`truncated: true`, no parcels). See 'Package sales'.","operationId":"parcel_deeds_v1_parcels__property_id__deeds_get","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","examples":["13153-0W050J08B000"],"title":"Property Id"}},{"name":"multi_parcel","in":"query","required":false,"schema":{"type":"boolean","description":"Only deeds covering 2+ parcels.","default":false,"title":"Multi Parcel"},"description":"Only deeds covering 2+ parcels."}],"responses":{"200":{"description":"The parcel's deeds, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelDeeds"},"example":{"property_id":"13021-N0740410","deeds":[{"county_fips":"13021","deed_book_page":"12348 1","sale_date":"2025-12-12","price":770000,"prices_differ":false,"parcel_count":17,"multi_parcel":true,"truncated":false,"parcels":[{"property_id":"13021-N0740228","situs_address":"1147 MIMOSA DR","situs_city":"MACON","sale_price":770000,"source":"last_sale"}]}],"count":1}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel by that id."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/deeds":{"get":{"tags":["Parcels"],"summary":"Look up one deed by its reference","description":"The parcels one recorded deed covers in a county, by the deed reference as the county writes it - `deed_book_page` on a sale row or `last_sale_deed` on a parcel (`12348 1`, `4431 / 207`, an instrument number). `sale_date` narrows it to one day; without it every day the reference was recorded on is answered (normally one), newest first, each as a deed record. A reference with no digit 1-9 names no deed (400).","operationId":"county_deed_v1_counties__fips__deeds_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","examples":["13021"],"title":"Fips"}},{"name":"deed_book_page","in":"query","required":true,"schema":{"type":"string","description":"The deed reference, as the county writes it.","title":"Deed Book Page"},"description":"The deed reference, as the county writes it."},{"name":"sale_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"YYYY-MM-DD: only that day's deed.","title":"Sale Date"},"description":"YYYY-MM-DD: only that day's deed."}],"responses":{"200":{"description":"The deed, one record per day.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeedList"},"example":{"items":[{"county_fips":"13021","deed_book_page":"12348 1","sale_date":"2025-12-12","price":770000,"prices_differ":false,"parcel_count":17,"multi_parcel":true,"truncated":false,"parcels":[{"property_id":"13021-N0740228","situs_address":"1147 MIMOSA DR","situs_city":"MACON","sale_price":770000,"source":"last_sale"}]}],"count":1}}}},"400":{"description":"`fips` is not a county code, `deed_book_page` is missing or names no deed, or `sale_date` is not a date."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sales/flags":{"post":{"tags":["Parcels"],"summary":"Flag a sale on many parcels","description":"Tell PARCEL that one sale covered several parcels - a package deed the county did not label - so it is flagged `multi_parcel` on every parcel named. Body:\n\n`{\"property_ids\": [...], \"sale_date\": \"2025-12-12\", \"deed_book_page\": \"12348 1\", \"flag\": \"multi_parcel\", \"flagger_id\": \"presaling:42\", \"note\": \"...\"}`\n\n* `property_ids`: 1 to 200 parcels, the ones the deed covered. All of them are flagged together as one group, and each lists the others as `GET /parcels/{property_id}/sales/siblings`.\n* `sale_date` (or `sale_id`, one sale row's id, which gives the date and deed reference) picks the sale; `deed_book_page` is kept as given. A parcel with no recorded sale that day is flagged all the same: the flag rides the parcel and the date.\n* `flag`: `multi_parcel` (the default and, today, the only one).\n* `flagger_id` (optional): your own user, kept with the flag.\n* `remove: true` takes back the flags this key set for those parcels on that date.\n\nThe flag is recorded under the name of the API key that sent it (`flagged_by`), and every sale row lists that name among its `flag_sources` - so a flag your users set is never mistaken for one the county set (`county`) or a shared deed (`deed`). Flagging the same parcels again changes nothing (`already`).","operationId":"flag_sales_v1_sales_flags_post","requestBody":{"description":"`property_ids` (1-200) plus `sale_date` or `sale_id`.","content":{"application/json":{"example":{"property_ids":["13021-N0740410","13021-N0740411"],"sale_date":"2025-12-12","deed_book_page":"12348 1","flag":"multi_parcel"}}},"required":true},"responses":{"200":{"description":"What was flagged, already flagged, or not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleFlagResult"},"example":{"group_id":"f3b1c2a9d4e5","flag":"multi_parcel","flagged_by":"presaling-com-live-site-2026-10-12","sale_date":"2025-12-12","deed_book_page":"12348 1","marked":["13021-N0740410","13021-N0740411"],"already":[],"missing":[],"removed":0}}}},"400":{"description":"Body not a JSON object; no property ids, or over the limit; no `sale_date`/`sale_id`, or not a date; an unknown flag."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."}}}},"/v1/acqtrack/regions":{"get":{"tags":["AcqTrack"],"summary":"Rank every county, state or ZIP by sales","description":"What AcqTrack draws for one circle, for every region at once, so the country can be ranked and mapped: `scope` `county` (5-digit FIPS), `state` or `zip`; `months` the window ending this month (1-48); `use` any of `residential`, `commercial`, `agricultural`, `industrial`, `exempt`, `vacant`, `unknown` (default all); `state=GA` narrows county and ZIP; `sort` `dollars`, `dollars_per_lot`, `sales`, `all_sales`, `parcels`, `buyers`, `acres`, `distressed`, `flip`, `fliprate` (largest first; `flip` is the smallest average hold first and `fliprate` the largest $/day, each with fewer than 2 flips last); `limit` (default 100) and `offset`; `series=1` adds each region's months. `month=YYYY-MM` answers that one month instead (any of the last 60; a Timeline step, one call a month); `fields=key,dollars` keeps only those fields of each region.\n\nEvery measure is over each lot's own last sale in the window, as AcqTrack's circle reads it, with flips from the lot's sale history; `dollars` counts a package deed once, `dollars_per_lot` sums every lot's price. A restricted county is listed with every measure null; no priced sale nulls the dollar measures; no sale history nulls the flips. See \"National AcqTrack\" in the API guide.","operationId":"acq_regions_v1_acqtrack_regions_get","parameters":[{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"county","title":"Scope"}},{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Months"}},{"name":"use","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma list of use words; default all.","title":"Use"},"description":"Comma list of use words; default all."},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"dollars","title":"Sort"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"series","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Series"}},{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"YYYY-MM: that one month instead of the window.","title":"Month"},"description":"YYYY-MM: that one month instead of the window."},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma list of fields to keep; `key` always.","title":"Fields"},"description":"Comma list of fields to keep; `key` always."}],"responses":{"200":{"description":"Regions, ranked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcqRegionList"},"example":{"scope":"county","months":12,"from":"2025-11","to":"2026-10","use":["residential","commercial","agricultural","industrial","exempt","vacant","unknown"],"state":"GA","sort":"dollars","total":159,"items":[{"key":"13153","name":"Houston County","state":"GA","lat":32.46,"lng":-83.66,"latest_sale":"2026-09-30","all_sales":1480,"sales":1210,"parcels":1198,"priced_sales":1205,"dollars":281000000,"dollars_per_lot":288000000,"avg_price":233195,"avg_price_per_lot":239004,"buyers":904,"buyers_exact":true,"acres":2110.5,"distressed":31,"occupied":610,"absentee":402,"package_lots":12,"with_history":1102,"flips_known":true,"flips":84,"flip_days":17976,"avg_hold_days":214.0,"rated_flips":80,"flip_gain":2465000,"rated_days":17275,"per_day":142.69}],"built_at":"2026-10-14T03:10:00+00:00","counts_age_s":412}}}},"400":{"description":"An unknown `scope`, `use`, `sort` or field, `months` outside 1-48, a `month` not YYYY-MM or outside the last 60, a `state` that is not two letters, or `limit` too large."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/acqtrack/regions/{scope}/{key}":{"get":{"tags":["AcqTrack"],"summary":"One region's months and top buyers","description":"One county (FIPS), state (two letters) or ZIP with its full monthly series for the window (`months`, default 48) and `buyers_top`: the ten buyers with the most purchases in it (`buyer_id`, `name`, `purchases`, `dollars`) - the Local Buyers list for a whole county. A state's, or a ZIP crossing counties', merges its counties' lists.","operationId":"acq_region_v1_acqtrack_regions__scope___key__get","parameters":[{"name":"scope","in":"path","required":true,"schema":{"type":"string","title":"Scope"}},{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":48,"title":"Months"}},{"name":"use","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use"}}],"responses":{"200":{"description":"The region.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcqRegion"},"example":{"key":"13153","name":"Houston County","state":"GA","lat":32.46,"lng":-83.66,"latest_sale":"2026-09-30","all_sales":1480,"sales":1210,"parcels":1198,"priced_sales":1205,"dollars":281000000,"dollars_per_lot":288000000,"avg_price":233195,"avg_price_per_lot":239004,"buyers":904,"buyers_exact":true,"acres":2110.5,"distressed":31,"occupied":610,"absentee":402,"package_lots":12,"with_history":1102,"flips_known":true,"flips":84,"flip_days":17976,"avg_hold_days":214.0,"rated_flips":80,"flip_gain":2465000,"rated_days":17275,"per_day":142.69,"series":[{"month":"2025-11","sales":98,"dollars":23100000}],"buyers_top":[{"buyer_id":"BID-000123","name":"OAKPOINT HOLDINGS LLC","purchases":14,"dollars":3150000}]}}}},"400":{"description":"An unknown `scope` or `use`, or `months` outside 1-48."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No such region built."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/acqtrack/spots":{"get":{"tags":["AcqTrack"],"summary":"The best 1/4-, 1/2- and 1-mile circles","description":"Neighborhood AcqTrack: circles of `radius` 0.25, 0.5 or 1 mile wherever the sales are, ranked by `sort` (`dollars`, `dollars_per_lot`, `sales`, `all_sales`, `parcels`, `buyers`, `acres`, `distressed`, `flip`, `fliprate`), never overlapping, so the Top 100 are 100 different places. Nationwide (top 500) or `state=GA` (top 100) from the nightly lists, for `months` 3, 6, 12, 18, 24, 36, 48 and `use` all or `residential`; with `bbox=w,s,e,n` ranked live for any `months` 1-48 and any `use`. `flip` and `fliprate` need 3 flips in a circle. Each circle's `key` opens it at `/acqtrack/spots/{key}`. See \"Neighborhood AcqTrack\" in the API guide.","operationId":"acq_spots_v1_acqtrack_spots_get","parameters":[{"name":"radius","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Miles: 0.25, 0.5 or 1.","default":"0.5","title":"Radius"},"description":"Miles: 0.25, 0.5 or 1."},{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Months"}},{"name":"use","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma list; default all.","title":"Use"},"description":"Comma list; default all."},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"w,s,e,n","title":"Bbox"},"description":"w,s,e,n"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"dollars","title":"Sort"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Circles, ranked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcqSpotList"},"example":{"radius_m":805,"radius":0.5,"months":12,"from":"2025-11","to":"2026-10","use":["residential"],"state":"GA","sort":"fliprate","total":100,"items":[{"key":"s805:5070:3739:3647","rank":1,"lat":32.6102,"lng":-83.6405,"radius_m":805,"zip":"31088","city":"Warner Robins","county_fips":"13153","state":"GA","all_sales":212,"sales":198,"parcels":190,"priced_sales":195,"dollars":48100000,"dollars_per_lot":48100000,"avg_price":246667,"buyers":161,"buyers_exact":false,"acres":61.2,"distressed":2,"occupied":88,"absentee":102,"package_lots":0,"flips_known":true,"flips":31,"avg_hold_days":188.4,"rated_flips":29,"per_day":301.2}],"built_at":"2026-10-24T04:10:00+00:00","counts_age_s":600}}}},"400":{"description":"A `radius`, `use`, `sort` or `months` it cannot answer (without a bbox: the seven stops and all or residential only), `state` with `bbox`, or a bbox too large."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/acqtrack/spots/{key}":{"get":{"tags":["AcqTrack"],"summary":"One circle: months, buyers and lots","description":"One circle by its `key` (from `/acqtrack/spots`): its measures over `months` (default 48) and `use`, `series` (its months), `buyers_top` (the ten owners with the most purchases in it) and `parcel_ids` (every lot whose own last sale in the window puts its pin inside it), so the lot-by-lot circle can be drawn straight from it.","operationId":"acq_spot_v1_acqtrack_spots__key__get","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}},{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":48,"title":"Months"}},{"name":"use","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use"}}],"responses":{"200":{"description":"The circle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcqSpot"},"example":{"key":"s805:5070:3739:3647","rank":1,"lat":32.6102,"lng":-83.6405,"radius_m":805,"zip":"31088","city":"Warner Robins","county_fips":"13153","state":"GA","all_sales":212,"sales":198,"parcels":190,"priced_sales":195,"dollars":48100000,"dollars_per_lot":48100000,"avg_price":246667,"buyers":161,"buyers_exact":false,"acres":61.2,"distressed":2,"occupied":88,"absentee":102,"package_lots":0,"flips_known":true,"flips":31,"avg_hold_days":188.4,"rated_flips":29,"per_day":301.2,"series":[{"month":"2026-09","sales":18,"dollars":4400000}],"buyers_top":[{"buyer_id":"BID-000123","name":"OAKPOINT HOLDINGS LLC","purchases":6,"dollars":1310000}],"parcel_ids":["13153-0W050J11C000"]}}}},"400":{"description":"An unknown `use`, or `months` outside 1-48."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"Not a circle key."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/acqtrack/cells":{"get":{"tags":["AcqTrack"],"summary":"The 1,000-ft grid squares in a box","description":"Every 1,000-ft grid square with a deed in the window inside `bbox=w,s,e,n` (up to about 300 km a side), with the AcqTrack measures summed over `months` (1-48) and `use`, its centre and its majority ZIP and city: a heat map, or any area's totals with county lines disregarded. Busiest first; `limit` (default 5000, up to 20000) and `offset`.","operationId":"acq_cells_v1_acqtrack_cells_get","parameters":[{"name":"bbox","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"w,s,e,n (required)","title":"Bbox"},"description":"w,s,e,n (required)"},{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Months"}},{"name":"use","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":5000,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Grid squares.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcqCellList"},"example":{"zone":"5070","cell_m":304.8,"months":12,"total":1,"items":[{"key":"c:5070:3739:3647","lat":32.6102,"lng":-83.6405,"zip":"31088","city":"Warner Robins","county_fips":"13153","state":"GA","all_sales":212,"sales":198,"parcels":190,"priced_sales":195,"dollars":48100000,"dollars_per_lot":48100000,"avg_price":246667,"buyers":161,"buyers_exact":false,"acres":61.2,"distressed":2,"occupied":88,"absentee":102,"package_lots":0,"flips_known":true,"flips":31,"avg_hold_days":188.4,"rated_flips":29,"per_day":301.2}]}}}},"400":{"description":"No bbox, a bbox too large, an unknown `use`, or `months` outside 1-48."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/outlines":{"get":{"tags":["AcqTrack"],"summary":"One state's county or ZIP outlines, simplified","description":"The county (`level=county`) or ZIP (`level=zip`) outlines of one `state` (two letters; `US` for every county in the country), simplified for the zoom they are drawn at: `detail=low` (lines within about 500 m, for a whole state) or `high` (about 60 m, for a county or a city). A GeoJSON FeatureCollection whose feature `id` is the county FIPS or the 5-digit ZIP - the `key` of `/acqtrack/regions`, so its values join by id. A ZIP is the Census's ZIP Code Tabulation Area; one crossing a state line is in both states' files. Gzipped when the caller accepts it; `ETag`; cached a day. Source: Census cartographic boundary files (counties 2021, ZIPs 2020).","operationId":"outlines_v1_outlines_get","parameters":[{"name":"level","in":"query","required":false,"schema":{"type":"string","description":"county or zip","default":"county","title":"Level"},"description":"county or zip"},{"name":"state","in":"query","required":true,"schema":{"type":"string","description":"Two letters, or US for every county.","title":"State"},"description":"Two letters, or US for every county."},{"name":"detail","in":"query","required":false,"schema":{"type":"string","description":"low or high","default":"low","title":"Detail"},"description":"low or high"}],"responses":{"200":{"description":"The outlines, a GeoJSON FeatureCollection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureCollection"},"example":{"type":"FeatureCollection","features":[{"type":"Feature","id":"12086","properties":{"name":"Miami-Dade","state":"FL"},"geometry":{"type":"Polygon","coordinates":[[[-80.873,25.805],[-80.118,25.976],[-80.873,25.805]]]}}]}}}},"400":{"description":"An unknown `level` or `detail`, a `state` that is not two letters, or `level=zip` with `state=US`."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No outlines built for that state."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/home-types":{"get":{"tags":["Parcels"],"summary":"Count a county's parcels by home type","description":"How many of the county's parcels are each home type (`home_type` on every parcel row; parcel/hometype.py), as of the county's last classification, with how many of each were `inferred` (or decided by a linked Zillow home) rather than read from the county's own words or codes. `classified_at` is when; null and an empty list for a county not classified yet. `homes` is the sum of the kinds of home (not lots, farms or businesses).","operationId":"county_home_types_v1_counties__fips__home_types_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","title":"Fips"}}],"responses":{"200":{"description":"The counts, biggest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HomeTypeCounts"},"example":{"county_fips":"13153","classified_at":"2026-10-20T08:00:00+00:00","parcels":70412,"homes":61230,"items":[{"home_type":"single_family","label":"Single family","parcels":58110,"inferred":1204}]}}}},"400":{"description":"`fips` is not five digits."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/gis-links":{"get":{"tags":["Counties"],"summary":"List every county's GIS link","description":"Where a person goes to look up each county's parcels: one row per county (3,235, the Census county file).\n\nEach county is `{fips, state, county, gis_link, link_type, link_source, property_site, property_site_source, parcel_map, parcel_layer, layer_covers, tax_roll, data_download}`.\n\n* `gis_link` is the best link the county has, `link_type` which kind it is, best first: `property_site` (the county's own property-record or map site - qPublic, VGSI, Flagship, iasWorld, EagleWeb and the rest), `parcel_map` (the county's ArcGIS parcel layer in ArcGIS's free map viewer), `tax_roll` (a treasurer's tax roll), `data_download` (a bulk parcel file, no map). Null when PARCEL knows of none for the county.\n* `link_source` is the PARCEL collector the link came from.\n* `layer_covers` is `county` for a county's own layer and `statewide` for one several counties share; the map then opens on the whole state.\n\nBuilt from the collectors PARCEL runs for each county, so the list stays as current as they are (rebuilt at most every ten minutes).\n\n`state=GA` keeps one state, `link_type=` one kind of link. `format=csv` answers the same rows as a CSV file with the spreadsheet's columns (FIPS, State, County, GIS link, Link type, Parcel map, Parcel layer (ArcGIS REST), Layer covers, Property site, Data download) - the copy to keep beside your own list.","operationId":"gis_links_v1_gis_links_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Two-letter state code, any case.","title":"State"},"description":"Two-letter state code, any case."},{"name":"link_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only counties whose `gis_link` is this kind: property_site, parcel_map, tax_roll, data_download, or `none`.","title":"Link Type"},"description":"Only counties whose `gis_link` is this kind: property_site, parcel_map, tax_roll, data_download, or `none`."},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`csv` for a CSV file; JSON otherwise.","title":"Format"},"description":"`csv` for a CSV file; JSON otherwise."}],"responses":{"200":{"description":"Every county's links, ordered by FIPS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountyGisLinkList"},"example":{"items":[{"fips":"13153","state":"GA","county":"Houston County","gis_link":"https://qpublic.schneidercorp.com/Application.aspx?App=HoustonCountyGA","link_type":"property_site","link_source":"qpublic","property_site":"https://qpublic.schneidercorp.com/Application.aspx?App=HoustonCountyGA","property_site_source":"qpublic","parcel_map":"https://www.arcgis.com/apps/mapviewer/index.html?url=https%3A%2F%2Fgis.example.gov%2Farcgis%2Frest%2Fservices%2FParcels%2FMapServer%2F0","parcel_layer":"https://gis.example.gov/arcgis/rest/services/Parcels/MapServer/0","layer_covers":"county"}],"count":1,"with_link":1}}}},"400":{"description":"`link_type` or `format` was not one of the listed values."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/gis-links":{"get":{"tags":["Counties"],"summary":"Show one county's GIS link","description":"Where a person goes to look up this county's parcels.\n\nEach county is `{fips, state, county, gis_link, link_type, link_source, property_site, property_site_source, parcel_map, parcel_layer, layer_covers, tax_roll, data_download}`.\n\n* `gis_link` is the best link the county has, `link_type` which kind it is, best first: `property_site` (the county's own property-record or map site - qPublic, VGSI, Flagship, iasWorld, EagleWeb and the rest), `parcel_map` (the county's ArcGIS parcel layer in ArcGIS's free map viewer), `tax_roll` (a treasurer's tax roll), `data_download` (a bulk parcel file, no map). Null when PARCEL knows of none for the county.\n* `link_source` is the PARCEL collector the link came from.\n* `layer_covers` is `county` for a county's own layer and `statewide` for one several counties share; the map then opens on the whole state.\n\nBuilt from the collectors PARCEL runs for each county, so the list stays as current as they are (rebuilt at most every ten minutes).\n\nThe parcel's full record (`GET /parcels/{property_id}`) carries the same links as `county_gis`, with `parcel_map_here`: the county's parcel layer opened on that parcel.","operationId":"county_gis_links_v1_counties__fips__gis_links_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."}],"responses":{"200":{"description":"The county's links.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountyGisLinks"},"example":{"fips":"13153","state":"GA","county":"Houston County","gis_link":"https://qpublic.schneidercorp.com/Application.aspx?App=HoustonCountyGA","link_type":"property_site","link_source":"qpublic","property_site":"https://qpublic.schneidercorp.com/Application.aspx?App=HoustonCountyGA","property_site_source":"qpublic","parcel_map":"https://www.arcgis.com/apps/mapviewer/index.html?url=https%3A%2F%2Fgis.example.gov%2Farcgis%2Frest%2Fservices%2FParcels%2FMapServer%2F0","parcel_layer":"https://gis.example.gov/arcgis/rest/services/Parcels/MapServer/0","layer_covers":"county"}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No county with that FIPS code."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties":{"get":{"tags":["Counties"],"summary":"List counties","description":"Every US county we know of (3,235 loaded from the Census county file), each with its centroid, land area, how many parcels we hold for it, when one of those was last updated, and which collectors are enabled for it.\n\n`parcels` is `0` for a county nothing has been collected from yet, so `with_data=1` is the filter that answers \"what do we actually have?\". `sources` lists the enabled rows in `county_sources` and is `{}` when the county has never been configured. Ordered by state, then county name.\n\nThe counts come from the county copy the API rebuilds in the background every few minutes and after each finished run; `counts_age_s` says how old it is. Answers carry an `ETag` and `Cache-Control: private, max-age=60`, and a matching `If-None-Match` is answered `304`.","operationId":"counties_v1_counties_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Two-letter state code, any case (`GA`). Omit for every state.","title":"State"},"description":"Two-letter state code, any case (`GA`). Omit for every state."},{"name":"with_data","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`1` keeps only counties that already hold at least one parcel. Any other value is ignored.","title":"With Data"},"description":"`1` keeps only counties that already hold at least one parcel. Any other value is ignored."}],"responses":{"200":{"description":"The county registry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountyList"},"example":{"items":[{"fips":"13153","state":"GA","name":"Houston County","latitude":32.4587,"longitude":-83.6674,"land_area_sqmi":376.9,"parcels":67544,"last_updated":"2026-09-14T03:21:55+00:00","sources":["arcgis","qpublic"]},{"fips":"13001","state":"GA","name":"Appling County","latitude":31.7488,"longitude":-82.2887,"land_area_sqmi":507.4,"parcels":0,"sources":[]}],"counts_age_s":42}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}":{"get":{"tags":["Counties"],"summary":"Show one county","description":"Everything we know about one county on one page: its registry row, the collectors configured for it, how many parcels we hold and how many of those carry photos or coordinates, what each source has fetched into `raw_records`, how many images are stored and how many bytes that is, and its ten most recent runs.\n\n`counts.from_qpublic` and `counts.from_arcgis` overlap - a parcel merged from both sources is in both - so they do not add up to `parcels`. For the same numbers as percentages, plus an ETA while a run is in flight, use `/counties/{fips}/coverage`.","operationId":"county_detail_v1_counties__fips__get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."}],"responses":{"200":{"description":"The county, its sources, its counts and its last ten runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountyDetail"},"example":{"fips":"13153","state":"GA","name":"Houston County","sources":[{"source":"qpublic","config":{"app_id":1046},"enabled":true,"created_at":"2026-09-04T11:02:00+00:00"}],"counts":{"parcels":67544,"from_qpublic":44012,"from_arcgis":67544,"with_photos":21870,"with_location":67544,"last_updated":"2026-09-14T03:21:55+00:00"},"raw":[{"source":"qpublic","records":44012,"keys":44012,"last_fetched":"2026-09-14T03:21:55+00:00"}],"images":{"images":43740,"bytes":5821440112},"runs":[{"id":391,"source":"qpublic","started_at":"2026-09-18T02:10:04+00:00","status":"running","stats":{"stored":1240}}]}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No county with that FIPS code."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/parcels":{"get":{"tags":["Parcels"],"summary":"List parcels in a county","description":"Search and filter the parcels of one county.\n\nReturns `{items, count, total, next_cursor, next_offset}`. `count` is the size of\nthis page, `total` is the whole filtered set (a second `COUNT(*)` over the same\n`WHERE`, reused for two minutes for the same filters so paging does not recount\nthe set on every page), and the two `next_*` fields drive paging. `next_cursor` is an opaque\npaging token - feed it straight back as `cursor=` and do not store it; the\nidentifier on a parcel is `property_id`.\n\n### Filters\n\nAll are optional and combine with AND. Booleans accept `1/true/yes` and\n`0/false/no`. Dates are `YYYY-MM-DD`. A value that cannot be parsed is ignored.\n\n**Text and identity**\n\n| Parameter | Matches |\n|---|---|\n| `q` | Situs address, parsed into street / city / state / ZIP and matched piece by piece. Required on `GET /parcels` unless `near` is given. |\n| `address` | Substring of `situs_address`. |\n| `parcel_id` | The county parcel number in **any** spelling - normalized, then matched exactly on `parcel_id_norm`. A search filter, not an identifier: it is the half of `property_id` after the dash, without the county. |\n| `city` | `situs_city`, case-insensitive, whole value. |\n| `zip` | `situs_zip`, exact. |\n| `owner` | An owner **entry id** (`13153_SMITH_JOHN_A`, from `/owners`) is the resolved owner and matches `owner_id` exactly. Anything else is a substring of `owner_name` **or** of any co-owner in `owner_names[]`. The two cannot be confused: no county owner line looks like an entry id. |\n| `owner_id` | Resolved owner **identity** - the same owner across every county, every spelling. A number, from `/owners/{entry_id}`. Prefer `owner=`; this stays for one release. |\n| `owner_address` | Substring of the owner's mailing address. |\n| `owner_state` | Owner's mailing state, exact, upper-cased for you. |\n| `owner_zip` | Owner's mailing ZIP, exact. |\n| `absentee` | `1` = the owner's mailing state differs from the property's state; `0` = it does not (or is unknown). |\n| `owner_occupied` | The county's own owner-occupancy flag. |\n| `source` | `qpublic` or `arcgis` - the parcel must carry that source. |\n| `has_photos` | `1` = `photo_count > 0`, `0` = none. |\n| `homestead` | The county's homestead-exemption flag. |\n| `reason` | Substring of any sale reason on the parcel (deed / qualification text from `parcel_sales`). |\n| `class` | Comma-separated list of `property_class` **prefixes**, OR'd (`class=R,C`). |\n| `use` | `property_use`, exact. |\n| `home_type` | Comma-separated home types, OR'd, the way a home search filters: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other`, `unknown`. The search words work too: `houses`, `townhomes`, `condos`, `lots`, `multi-family`, and `homes` for every kind of home. Unknown word → **400**. |\n| `home_type_strict` | `1` = only types read from the county's own words or use codes, leaving out the `inferred` ones (a class that says \"residential\" and nothing finer, read as single family) and the `zillow` ones (written before 0.52.0: the county says nothing finer and a Zillow sitemap home decided; gone after the next full reclassification). |\n| `zillow_status` | Admin keys only (**403** otherwise). The status of the Zillow home page that names the parcel (only parcels whose page has been read have one), comma-separated, OR'd: `for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`; `listed` = for sale, `sold` = recently sold. Unknown word → **400**. |\n| `zillow_sold_after` | Admin keys only. The newest sale in that page's price history is on or after this date (`zillow.sold_seen`). |\n| `messy_title` | `1` = the title is likely messy (`messy_title_likely`: any reason below but a lone quit-claim); `0` = not. |\n| `messy_title_reason` | Comma-separated, OR'd: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims`, `owner_estate`. The plain words work too: `estate` (both estate reasons), `probate`, `heirs`, `sheriff`, `trustee`, `tax`, `quitclaim`. Unknown word → **400**. |\n\n**Home type.** Every row carries `home_type` and `home_type_basis` (`text`, `code`,\n`use`, `inferred`, or `zillow` on rows from before 0.52.0). It is read from `property_class`, `building_style` and\n`property_use` with each state's own code table - Florida `001` is single family and\n`008` multi-family, Texas `A1` single family and `B2` a duplex, Ohio `520` two family\n- and is null for a county not classified yet. Where the county's columns say nothing\nfiner than \"residential\", it is single family, or land when the record says there is\nno building (`inferred`). `GET /counties/{fips}/home-types` counts them.\n\n**Messy title.** Every row carries `messy_title_likely` and `messy_title_reasons`,\nread from the deeds on file: `estate_deed` (an estate, probate, executor's or\npersonal representative's deed for nothing, or a grantor that is an estate - the\nestate selling at a price is a purchase), `foreclosure` (a\nforeclosure, sheriff's or referee's deed, a deed in lieu, a public or substitute\ntrustee's deed, a trustee's deed in a deed-of-trust state, a deed to HUD, Fannie Mae,\nFreddie Mac or the VA), `tax_deed` (a tax deed, or a deed from a treasurer or tax\ncollector), `quit_claim`, `quit_claims` (two or more within three years of each\nother) and `owner_estate` (the owner line says \"estate of\", \"heirs\", \"deceased\", or\nnames an executor). `messy_title_likely` is any of these but a lone quit-claim. A\ndeed counts only when it was recorded in the last ten years and no purchase came\nafter it (a $0 quit-claim the same day as a priced sale is that sale's). Most rolls\nrecord no deed type, so there only the parties and the owner line can flag a lot:\n`false` means \"nothing on file says so\", not \"clean\". Null until the county has\nbeen checked. Liens and unpaid taxes are not read. On the customer surface a\nuse-restricted county's rows carry null, and the two filters skip those counties.\n\n**Ranges** - `min_value` / `max_value` (`total_value`), `min_acres` / `max_acres`\n(`land_acres`), `min_sale_price` / `max_sale_price` (`last_sale_price`),\n`min_year_built` / `max_year_built`, `min_sqft` / `max_sqft` (`heated_sqft`),\n`min_beds` / `max_beds` (`bedrooms`; `beds` is the older spelling of `min_beds`\nand still means **at least**), `min_baths` / `max_baths` (full baths plus half a\nbath for each half bath, so `min_baths=1.5` keeps 1 full + 1 half and up),\n`sold_after` / `sold_before` (`last_sale_date`), `updated_after` (`updated_at`).\nAll bounds are inclusive. Zero bedrooms, baths or square feet is \"not recorded\",\nso a `max_` bound never matches a row that records none, and a bath bound never\nmatches a row with no full bath.\n\nEvery row whose `last_sale_price` and `heated_sqft` are both selected carries\n**`price_per_sqft`**: the price over the square feet, to the cent, null when the\nprice is at or under $1,000 (a transfer, not a sale) or the size is not recorded.\n\nEvery row with `situs_address` (and `owner_address`) carries it as two lines too:\n**`situs_address_line1`** and **`situs_address_line2`** - the unit, as written:\n`STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`; null when the line names none - and\n`owner_address_line1` / `owner_address_line2` for the mailing address.\n\n**Geography**\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `bbox=w,s,e,n` in decimal degrees, `w < e` and `s < n`. Malformed → **400**. |\n| `near` | `near=lat,lng`, a centre point. Adds `distance_m` to every row and makes `order=distance` the default. Malformed → **400**. |\n| `radius_m` | Metres around `near`, 1-50000, default 1000. Out of range → **400**. Ignored without `near`. On the routes with no county in the path (`GET /parcels`, `GET /parcels.geojson`) at most 8047 (five miles); wider → **422** `radius_too_large`. |\n\nDistance is a great-circle calculation in plain SQL over a bounding box first\n(there is no PostGIS on the box), so both `near` and `radius_m` only ever see\nparcels that carry coordinates.\n\n**Where a coordinate came from.** Every row carries `geocode_source` and\n`geocode_precision` beside `latitude`/`longitude`, because a parcel centroid and a\nstreet-interpolated point are not the same claim.\n\n| `geocode_source` | `geocode_precision` | What the point is |\n|---|---|---|\n| `gis` | `parcel` | The county GIS layer's own centroid for this parcel. |\n| `census` | `street` | The US Census geocoder matched the situs address and interpolated along that street segment. |\n| `census` | `centroid` | The Census geocoder matched something near the address rather than it (`geocode_match: \"Non_Exact\"`). |\n| `null` | `null` | No coordinate, or one located before we recorded where it came from. |\n\nBoth are `null` whenever `latitude` is, and `geocode_precision` is `null` for a\ncoordinate whose origin was never recorded. `rooftop` is reserved and nothing\nproduces it today: no source we read returns a rooftop point.\n\n**Shape of each row**\n\n| Parameter | Meaning |\n|---|---|\n| `fields` | Comma-separated subset of the parcel columns; `property_id` is always included. `geometry`, `record_url`, `geocode_precision`, `price_per_sqft`, `owner_display` and the address lines (`situs_address_line1`, `situs_address_line2`, `owner_address_line1`, `owner_address_line2`) are allowed. An unknown name → **400**. |\n| `geometry` | `1` adds the GeoJSON `geometry` column, which is excluded by default because it is large. |\n\n### Paging\n\n| Parameter | Meaning |\n|---|---|\n| `limit` | Rows per page, 1-500 (default 100). |\n| `order` | `id` (default), `value_desc`, `sale_date_desc`, `updated_desc`, `sqft_desc`, `acres_desc`, `year_built_desc`, `ppsf_desc` (sale price ÷ heated sqft), `distance` (only with `near=`). An unknown value falls back to `id`. |\n| `cursor` | **`order=id` only.** Returns rows with `id >` this. Feed back `next_cursor`. |\n| `offset` | **Every other order.** 0-50000. Feed back `next_offset`. |\n\nSo there are two paging modes and the response tells you which one you are in:\n`order=id` fills `next_cursor` (stable while rows are being written underneath\nyou), any other order fills `next_offset`. The other field is `null`, and both\nare `null` on the last page.","operationId":"parcels_v1_counties__fips__parcels_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."}],"responses":{"200":{"description":"One page of parcels plus the size of the whole filtered set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelList"},"example":{"items":[{"property_id":"13153-0W050J08B000","county_fips":"13153","state":"GA","parcel_id_norm":"0W050J08B000","parcel_id_raw":"0W050J    08B000","account_number":"13554","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_state":"GA","situs_zip":"31088","owner_name":"SMITH JOHN A","owner_names":["SMITH JOHN A","SMITH MARY B"],"owner_address":"109 FREEMAN DR","owner_city":"WARNER ROBINS","owner_state":"GA","owner_zip":"31088","owner_occupied":true,"owner_id":"13153_SMITH_JOHN_A","owner_verified":true,"owner_display":"SMITH, JOHN A","property_class":"R3","property_use":"Residential","zoning":"R-1","tax_district":"COUNTY","homestead":true,"land_acres":0.46,"building_count":1,"building_style":"RANCH","year_built":1978,"heated_sqft":1684,"bedrooms":3,"full_baths":2,"half_baths":0,"condition":"AVERAGE","last_sale_date":"2019-06-14","last_sale_price":132000,"assessed_year":2025,"land_value":18000,"improvement_value":141200,"total_value":159200,"est_annual_tax":1234.5,"latitude":32.6105,"longitude":-83.6219,"geocode_source":"gis","geocode_precision":"parcel","photo_count":2,"sketch_count":1,"sources":["arcgis","qpublic"],"source_urls":{"qpublic":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000"},"record_url":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000","last_seen_at":"2026-09-14T03:21:55+00:00","updated_at":"2026-09-14T03:21:55+00:00","home_type":"single_family","home_type_basis":"inferred","zillow":{"zpid":35956751,"status":"recently_sold","status_at":"2026-09-30","sold_seen":"2026-09-30","price":214000,"url":"https://www.zillow.com/homedetails/109-Freeman-Dr-Warner-Robins-GA-31088/35956751_zpid/"},"messy_title_likely":false,"messy_title_reasons":[]}],"count":1,"total":67544,"next_cursor":4812}}}},"400":{"description":"A geo parameter was malformed or `fields` named an unknown column."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/parcels/count":{"get":{"tags":["Parcels"],"summary":"Count parcels in a county","description":"`{total}` for exactly the same filters as `GET /counties/{fips}/parcels`, without fetching any rows - for sizing a query, driving a facet count, or checking a filter before you page through it. Paging parameters (`limit`, `offset`, `cursor`, `order`) are accepted and ignored; the count is of the whole filtered set.\n\n### Filters\n\nAll are optional and combine with AND. Booleans accept `1/true/yes` and\n`0/false/no`. Dates are `YYYY-MM-DD`. A value that cannot be parsed is ignored.\n\n**Text and identity**\n\n| Parameter | Matches |\n|---|---|\n| `q` | Situs address, parsed into street / city / state / ZIP and matched piece by piece. Required on `GET /parcels` unless `near` is given. |\n| `address` | Substring of `situs_address`. |\n| `parcel_id` | The county parcel number in **any** spelling - normalized, then matched exactly on `parcel_id_norm`. A search filter, not an identifier: it is the half of `property_id` after the dash, without the county. |\n| `city` | `situs_city`, case-insensitive, whole value. |\n| `zip` | `situs_zip`, exact. |\n| `owner` | An owner **entry id** (`13153_SMITH_JOHN_A`, from `/owners`) is the resolved owner and matches `owner_id` exactly. Anything else is a substring of `owner_name` **or** of any co-owner in `owner_names[]`. The two cannot be confused: no county owner line looks like an entry id. |\n| `owner_id` | Resolved owner **identity** - the same owner across every county, every spelling. A number, from `/owners/{entry_id}`. Prefer `owner=`; this stays for one release. |\n| `owner_address` | Substring of the owner's mailing address. |\n| `owner_state` | Owner's mailing state, exact, upper-cased for you. |\n| `owner_zip` | Owner's mailing ZIP, exact. |\n| `absentee` | `1` = the owner's mailing state differs from the property's state; `0` = it does not (or is unknown). |\n| `owner_occupied` | The county's own owner-occupancy flag. |\n| `source` | `qpublic` or `arcgis` - the parcel must carry that source. |\n| `has_photos` | `1` = `photo_count > 0`, `0` = none. |\n| `homestead` | The county's homestead-exemption flag. |\n| `reason` | Substring of any sale reason on the parcel (deed / qualification text from `parcel_sales`). |\n| `class` | Comma-separated list of `property_class` **prefixes**, OR'd (`class=R,C`). |\n| `use` | `property_use`, exact. |\n| `home_type` | Comma-separated home types, OR'd, the way a home search filters: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other`, `unknown`. The search words work too: `houses`, `townhomes`, `condos`, `lots`, `multi-family`, and `homes` for every kind of home. Unknown word → **400**. |\n| `home_type_strict` | `1` = only types read from the county's own words or use codes, leaving out the `inferred` ones (a class that says \"residential\" and nothing finer, read as single family) and the `zillow` ones (written before 0.52.0: the county says nothing finer and a Zillow sitemap home decided; gone after the next full reclassification). |\n| `zillow_status` | Admin keys only (**403** otherwise). The status of the Zillow home page that names the parcel (only parcels whose page has been read have one), comma-separated, OR'd: `for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`; `listed` = for sale, `sold` = recently sold. Unknown word → **400**. |\n| `zillow_sold_after` | Admin keys only. The newest sale in that page's price history is on or after this date (`zillow.sold_seen`). |\n| `messy_title` | `1` = the title is likely messy (`messy_title_likely`: any reason below but a lone quit-claim); `0` = not. |\n| `messy_title_reason` | Comma-separated, OR'd: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims`, `owner_estate`. The plain words work too: `estate` (both estate reasons), `probate`, `heirs`, `sheriff`, `trustee`, `tax`, `quitclaim`. Unknown word → **400**. |\n\n**Home type.** Every row carries `home_type` and `home_type_basis` (`text`, `code`,\n`use`, `inferred`, or `zillow` on rows from before 0.52.0). It is read from `property_class`, `building_style` and\n`property_use` with each state's own code table - Florida `001` is single family and\n`008` multi-family, Texas `A1` single family and `B2` a duplex, Ohio `520` two family\n- and is null for a county not classified yet. Where the county's columns say nothing\nfiner than \"residential\", it is single family, or land when the record says there is\nno building (`inferred`). `GET /counties/{fips}/home-types` counts them.\n\n**Messy title.** Every row carries `messy_title_likely` and `messy_title_reasons`,\nread from the deeds on file: `estate_deed` (an estate, probate, executor's or\npersonal representative's deed for nothing, or a grantor that is an estate - the\nestate selling at a price is a purchase), `foreclosure` (a\nforeclosure, sheriff's or referee's deed, a deed in lieu, a public or substitute\ntrustee's deed, a trustee's deed in a deed-of-trust state, a deed to HUD, Fannie Mae,\nFreddie Mac or the VA), `tax_deed` (a tax deed, or a deed from a treasurer or tax\ncollector), `quit_claim`, `quit_claims` (two or more within three years of each\nother) and `owner_estate` (the owner line says \"estate of\", \"heirs\", \"deceased\", or\nnames an executor). `messy_title_likely` is any of these but a lone quit-claim. A\ndeed counts only when it was recorded in the last ten years and no purchase came\nafter it (a $0 quit-claim the same day as a priced sale is that sale's). Most rolls\nrecord no deed type, so there only the parties and the owner line can flag a lot:\n`false` means \"nothing on file says so\", not \"clean\". Null until the county has\nbeen checked. Liens and unpaid taxes are not read. On the customer surface a\nuse-restricted county's rows carry null, and the two filters skip those counties.\n\n**Ranges** - `min_value` / `max_value` (`total_value`), `min_acres` / `max_acres`\n(`land_acres`), `min_sale_price` / `max_sale_price` (`last_sale_price`),\n`min_year_built` / `max_year_built`, `min_sqft` / `max_sqft` (`heated_sqft`),\n`min_beds` / `max_beds` (`bedrooms`; `beds` is the older spelling of `min_beds`\nand still means **at least**), `min_baths` / `max_baths` (full baths plus half a\nbath for each half bath, so `min_baths=1.5` keeps 1 full + 1 half and up),\n`sold_after` / `sold_before` (`last_sale_date`), `updated_after` (`updated_at`).\nAll bounds are inclusive. Zero bedrooms, baths or square feet is \"not recorded\",\nso a `max_` bound never matches a row that records none, and a bath bound never\nmatches a row with no full bath.\n\nEvery row whose `last_sale_price` and `heated_sqft` are both selected carries\n**`price_per_sqft`**: the price over the square feet, to the cent, null when the\nprice is at or under $1,000 (a transfer, not a sale) or the size is not recorded.\n\nEvery row with `situs_address` (and `owner_address`) carries it as two lines too:\n**`situs_address_line1`** and **`situs_address_line2`** - the unit, as written:\n`STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`; null when the line names none - and\n`owner_address_line1` / `owner_address_line2` for the mailing address.\n\n**Geography**\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `bbox=w,s,e,n` in decimal degrees, `w < e` and `s < n`. Malformed → **400**. |\n| `near` | `near=lat,lng`, a centre point. Adds `distance_m` to every row and makes `order=distance` the default. Malformed → **400**. |\n| `radius_m` | Metres around `near`, 1-50000, default 1000. Out of range → **400**. Ignored without `near`. On the routes with no county in the path (`GET /parcels`, `GET /parcels.geojson`) at most 8047 (five miles); wider → **422** `radius_too_large`. |\n\nDistance is a great-circle calculation in plain SQL over a bounding box first\n(there is no PostGIS on the box), so both `near` and `radius_m` only ever see\nparcels that carry coordinates.\n\n**Where a coordinate came from.** Every row carries `geocode_source` and\n`geocode_precision` beside `latitude`/`longitude`, because a parcel centroid and a\nstreet-interpolated point are not the same claim.\n\n| `geocode_source` | `geocode_precision` | What the point is |\n|---|---|---|\n| `gis` | `parcel` | The county GIS layer's own centroid for this parcel. |\n| `census` | `street` | The US Census geocoder matched the situs address and interpolated along that street segment. |\n| `census` | `centroid` | The Census geocoder matched something near the address rather than it (`geocode_match: \"Non_Exact\"`). |\n| `null` | `null` | No coordinate, or one located before we recorded where it came from. |\n\nBoth are `null` whenever `latitude` is, and `geocode_precision` is `null` for a\ncoordinate whose origin was never recorded. `rooftop` is reserved and nothing\nproduces it today: no source we read returns a rooftop point.\n\n**Shape of each row**\n\n| Parameter | Meaning |\n|---|---|\n| `fields` | Comma-separated subset of the parcel columns; `property_id` is always included. `geometry`, `record_url`, `geocode_precision`, `price_per_sqft`, `owner_display` and the address lines (`situs_address_line1`, `situs_address_line2`, `owner_address_line1`, `owner_address_line2`) are allowed. An unknown name → **400**. |\n| `geometry` | `1` adds the GeoJSON `geometry` column, which is excluded by default because it is large. |","operationId":"parcels_count_v1_counties__fips__parcels_count_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."}],"responses":{"200":{"description":"How many parcels match.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelCount"},"example":{"total":1284}}}},"400":{"description":"A geo parameter was malformed or `fields` named an unknown column."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/counties/{fips}/parcels.geojson":{"get":{"tags":["Parcels"],"summary":"Get a map layer of parcels","description":"A GeoJSON `FeatureCollection` of the parcels inside a bounding box, with their polygons - the map layer.\n\n**`bbox=w,s,e,n` is required** (400 without it): geometry is large, and an unbounded request would try to serve a whole county's polygons. The default and the maximum `limit` are both 5000 here, and `geometry` is forced on. Every other filter below works as it does on the list route.\n\nEach feature is `{type, id, geometry, properties}` where `id` is the parcel's `property_id` and `properties` holds every non-geometry column of the row. The collection also carries `count` (features returned) and `total` (parcels matching the filter), so `total > count` tells you the viewport was capped - zoom in rather than paging. `truncated` says the same thing as a boolean.\n\n**`count=0`** skips the second query that produces `total`: `total` is then the feature count when the window is not capped and `null` when it is. A map that only draws should send it. The default, `count=1`, keeps `total` exact.\n\n**Shapes are simplified by default.** `simplify=<metres>` sets the tolerance exactly as on `GET /parcels.geojson`; without it the tolerance is the window's east-west width in metres divided by 2000, clamped to 0.5-5 m - about one screen pixel. `simplify=0` returns full fidelity.\n\nThe same window asked again within ten minutes is answered from memory (the bbox rounded to four decimals, about 11 m, and every other parameter as sent). A finished run for the county, or a rebuild of the county copy, drops those answers.\n\n### Filters\n\nAll are optional and combine with AND. Booleans accept `1/true/yes` and\n`0/false/no`. Dates are `YYYY-MM-DD`. A value that cannot be parsed is ignored.\n\n**Text and identity**\n\n| Parameter | Matches |\n|---|---|\n| `q` | Situs address, parsed into street / city / state / ZIP and matched piece by piece. Required on `GET /parcels` unless `near` is given. |\n| `address` | Substring of `situs_address`. |\n| `parcel_id` | The county parcel number in **any** spelling - normalized, then matched exactly on `parcel_id_norm`. A search filter, not an identifier: it is the half of `property_id` after the dash, without the county. |\n| `city` | `situs_city`, case-insensitive, whole value. |\n| `zip` | `situs_zip`, exact. |\n| `owner` | An owner **entry id** (`13153_SMITH_JOHN_A`, from `/owners`) is the resolved owner and matches `owner_id` exactly. Anything else is a substring of `owner_name` **or** of any co-owner in `owner_names[]`. The two cannot be confused: no county owner line looks like an entry id. |\n| `owner_id` | Resolved owner **identity** - the same owner across every county, every spelling. A number, from `/owners/{entry_id}`. Prefer `owner=`; this stays for one release. |\n| `owner_address` | Substring of the owner's mailing address. |\n| `owner_state` | Owner's mailing state, exact, upper-cased for you. |\n| `owner_zip` | Owner's mailing ZIP, exact. |\n| `absentee` | `1` = the owner's mailing state differs from the property's state; `0` = it does not (or is unknown). |\n| `owner_occupied` | The county's own owner-occupancy flag. |\n| `source` | `qpublic` or `arcgis` - the parcel must carry that source. |\n| `has_photos` | `1` = `photo_count > 0`, `0` = none. |\n| `homestead` | The county's homestead-exemption flag. |\n| `reason` | Substring of any sale reason on the parcel (deed / qualification text from `parcel_sales`). |\n| `class` | Comma-separated list of `property_class` **prefixes**, OR'd (`class=R,C`). |\n| `use` | `property_use`, exact. |\n| `home_type` | Comma-separated home types, OR'd, the way a home search filters: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other`, `unknown`. The search words work too: `houses`, `townhomes`, `condos`, `lots`, `multi-family`, and `homes` for every kind of home. Unknown word → **400**. |\n| `home_type_strict` | `1` = only types read from the county's own words or use codes, leaving out the `inferred` ones (a class that says \"residential\" and nothing finer, read as single family) and the `zillow` ones (written before 0.52.0: the county says nothing finer and a Zillow sitemap home decided; gone after the next full reclassification). |\n| `zillow_status` | Admin keys only (**403** otherwise). The status of the Zillow home page that names the parcel (only parcels whose page has been read have one), comma-separated, OR'd: `for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`; `listed` = for sale, `sold` = recently sold. Unknown word → **400**. |\n| `zillow_sold_after` | Admin keys only. The newest sale in that page's price history is on or after this date (`zillow.sold_seen`). |\n| `messy_title` | `1` = the title is likely messy (`messy_title_likely`: any reason below but a lone quit-claim); `0` = not. |\n| `messy_title_reason` | Comma-separated, OR'd: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims`, `owner_estate`. The plain words work too: `estate` (both estate reasons), `probate`, `heirs`, `sheriff`, `trustee`, `tax`, `quitclaim`. Unknown word → **400**. |\n\n**Home type.** Every row carries `home_type` and `home_type_basis` (`text`, `code`,\n`use`, `inferred`, or `zillow` on rows from before 0.52.0). It is read from `property_class`, `building_style` and\n`property_use` with each state's own code table - Florida `001` is single family and\n`008` multi-family, Texas `A1` single family and `B2` a duplex, Ohio `520` two family\n- and is null for a county not classified yet. Where the county's columns say nothing\nfiner than \"residential\", it is single family, or land when the record says there is\nno building (`inferred`). `GET /counties/{fips}/home-types` counts them.\n\n**Messy title.** Every row carries `messy_title_likely` and `messy_title_reasons`,\nread from the deeds on file: `estate_deed` (an estate, probate, executor's or\npersonal representative's deed for nothing, or a grantor that is an estate - the\nestate selling at a price is a purchase), `foreclosure` (a\nforeclosure, sheriff's or referee's deed, a deed in lieu, a public or substitute\ntrustee's deed, a trustee's deed in a deed-of-trust state, a deed to HUD, Fannie Mae,\nFreddie Mac or the VA), `tax_deed` (a tax deed, or a deed from a treasurer or tax\ncollector), `quit_claim`, `quit_claims` (two or more within three years of each\nother) and `owner_estate` (the owner line says \"estate of\", \"heirs\", \"deceased\", or\nnames an executor). `messy_title_likely` is any of these but a lone quit-claim. A\ndeed counts only when it was recorded in the last ten years and no purchase came\nafter it (a $0 quit-claim the same day as a priced sale is that sale's). Most rolls\nrecord no deed type, so there only the parties and the owner line can flag a lot:\n`false` means \"nothing on file says so\", not \"clean\". Null until the county has\nbeen checked. Liens and unpaid taxes are not read. On the customer surface a\nuse-restricted county's rows carry null, and the two filters skip those counties.\n\n**Ranges** - `min_value` / `max_value` (`total_value`), `min_acres` / `max_acres`\n(`land_acres`), `min_sale_price` / `max_sale_price` (`last_sale_price`),\n`min_year_built` / `max_year_built`, `min_sqft` / `max_sqft` (`heated_sqft`),\n`min_beds` / `max_beds` (`bedrooms`; `beds` is the older spelling of `min_beds`\nand still means **at least**), `min_baths` / `max_baths` (full baths plus half a\nbath for each half bath, so `min_baths=1.5` keeps 1 full + 1 half and up),\n`sold_after` / `sold_before` (`last_sale_date`), `updated_after` (`updated_at`).\nAll bounds are inclusive. Zero bedrooms, baths or square feet is \"not recorded\",\nso a `max_` bound never matches a row that records none, and a bath bound never\nmatches a row with no full bath.\n\nEvery row whose `last_sale_price` and `heated_sqft` are both selected carries\n**`price_per_sqft`**: the price over the square feet, to the cent, null when the\nprice is at or under $1,000 (a transfer, not a sale) or the size is not recorded.\n\nEvery row with `situs_address` (and `owner_address`) carries it as two lines too:\n**`situs_address_line1`** and **`situs_address_line2`** - the unit, as written:\n`STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`; null when the line names none - and\n`owner_address_line1` / `owner_address_line2` for the mailing address.\n\n**Geography**\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `bbox=w,s,e,n` in decimal degrees, `w < e` and `s < n`. Malformed → **400**. |\n| `near` | `near=lat,lng`, a centre point. Adds `distance_m` to every row and makes `order=distance` the default. Malformed → **400**. |\n| `radius_m` | Metres around `near`, 1-50000, default 1000. Out of range → **400**. Ignored without `near`. On the routes with no county in the path (`GET /parcels`, `GET /parcels.geojson`) at most 8047 (five miles); wider → **422** `radius_too_large`. |\n\nDistance is a great-circle calculation in plain SQL over a bounding box first\n(there is no PostGIS on the box), so both `near` and `radius_m` only ever see\nparcels that carry coordinates.\n\n**Where a coordinate came from.** Every row carries `geocode_source` and\n`geocode_precision` beside `latitude`/`longitude`, because a parcel centroid and a\nstreet-interpolated point are not the same claim.\n\n| `geocode_source` | `geocode_precision` | What the point is |\n|---|---|---|\n| `gis` | `parcel` | The county GIS layer's own centroid for this parcel. |\n| `census` | `street` | The US Census geocoder matched the situs address and interpolated along that street segment. |\n| `census` | `centroid` | The Census geocoder matched something near the address rather than it (`geocode_match: \"Non_Exact\"`). |\n| `null` | `null` | No coordinate, or one located before we recorded where it came from. |\n\nBoth are `null` whenever `latitude` is, and `geocode_precision` is `null` for a\ncoordinate whose origin was never recorded. `rooftop` is reserved and nothing\nproduces it today: no source we read returns a rooftop point.\n\n**Shape of each row**\n\n| Parameter | Meaning |\n|---|---|\n| `fields` | Comma-separated subset of the parcel columns; `property_id` is always included. `geometry`, `record_url`, `geocode_precision`, `price_per_sqft`, `owner_display` and the address lines (`situs_address_line1`, `situs_address_line2`, `owner_address_line1`, `owner_address_line2`) are allowed. An unknown name → **400**. |\n| `geometry` | `1` adds the GeoJSON `geometry` column, which is excluded by default because it is large. |","operationId":"parcels_geojson_v1_counties__fips__parcels_geojson_get","parameters":[{"name":"fips","in":"path","required":true,"schema":{"type":"string","description":"Five-digit county FIPS code (`13153` = Houston County, GA).","title":"Fips"},"description":"Five-digit county FIPS code (`13153` = Houston County, GA)."}],"responses":{"200":{"description":"A GeoJSON FeatureCollection of the parcels in the box.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureCollection"},"example":{"type":"FeatureCollection","features":[{"type":"Feature","id":"13153-0W050J08B000","geometry":{"type":"Polygon","coordinates":[[[-83.622,32.61],[-83.621,32.61],[-83.621,32.611],[-83.622,32.61]]]},"properties":{"property_id":"13153-0W050J08B000","situs_address":"109 FREEMAN DR","owner_name":"SMITH JOHN A","total_value":159200}}],"count":1,"total":1}}}},"400":{"description":"`bbox=w,s,e,n` is missing or malformed."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parcels.geojson":{"get":{"tags":["Parcels"],"summary":"Get a map layer of parcels across counties","description":"The map layer with no county in the path: a GeoJSON `FeatureCollection` of every parcel inside a bounding box or a circle, whichever counties it crosses. A map window does not know where county lines are, and at a metro boundary one window covers three counties - this is the route to draw from.\n\nIdentical to `GET /counties/{fips}/parcels.geojson` in everything but the county filter and the limits below. **`bbox=w,s,e,n` or `near=lat,lng` is required** (`radius_m` sets the circle, default 1000, at most five miles), `geometry` is forced on, and each feature is `{type, id, geometry, properties}` with `id` the parcel's `property_id`.\n\n### What stops a window from being too big\n\n| Guard | Answer |\n|---|---|\n| Neither `bbox` nor `near`, or either malformed | **400** |\n| `bbox` area over **0.03 square degrees** (about 18 x 18 km at Georgia's latitude, room for the box around a five-mile circle) | **422**, `code: \"bbox_too_large\"`, naming the maximum and the area you asked for |\n| `near` with `radius_m` over **8047 metres** (five miles) | **422**, `code: \"radius_too_large\"`, naming the maximum |\n| More than **5000** parcels in the window | The first 5000, plus `truncated: true` and the real `total` |\n\n### Points only\n\n`geometry=point` answers each parcel as a GeoJSON `Point` at its `latitude` /\n`longitude` instead of its polygon - every property the same, a fraction of the\nbytes. The window may then be up to **0.1 square degrees** (about 33 x 33\nkm at Georgia's latitude) and hold **20,000** features. A parcel with no\npoint on file comes back with `geometry: null`. `simplify` does not apply.\n\n### A circle instead of a box\n\n`near=lat,lng&radius_m=` draws every parcel inside a circle rather than a box -\nthe five-mile picture around one property in one call. The features come nearest\nfirst and each carries `distance_m`, so when the cap bites you hold the closest\n5000. A circle is bounded by its radius and is not area-checked.\n`bbox` and `near` together keep what is inside both, and the circle is then the\nbound: the box beside it is not area-checked.\n\n`count`, `total` and `truncated` sit beside `features` on the collection.\n`truncated` is the field to read: when it is true you are looking at an arbitrary\n5000 of `total` parcels, and the fix is to zoom in, not to page -\nthere is no paging on a map layer.\n\n### Simplifying the shapes\n\n`simplify=<metres>` thins each polygon with Ramer-Douglas-Peucker, dropping every\nposition closer than that to the line its neighbours already describe. The\ntolerance is converted to degrees at the centre latitude of your window (the\n`bbox`, or the `near` point), so the same number means the same distance north and\nsouth.\n\nThis happens **in Python**, not in PostGIS: parcel geometry is stored as GeoJSON in\na `jsonb` column and there is no PostGIS extension on this box, so there is no\n`ST_SimplifyPreserveTopology` to call. Two consequences worth knowing. Shared edges\nbetween neighbouring parcels are simplified independently and can pull apart by up\nto the tolerance, so slivers appear between polygons at large tolerances - fine for\ndrawing, not for area arithmetic. And a ring that would fall below four positions\nis left exactly as it was rather than shipped invalid.\n\nSensible values are a fraction of what a pixel covers: 1-5 m at street zoom, 10-25 m\nat city zoom. `simplify=0` or no `simplify` returns full fidelity.\n\nIf this layer ever becomes the bottleneck the answer is vector tiles\n(`/tiles/parcels/{z}/{x}/{y}.mvt`), which make the cap, the simplification and\nthe area limit all disappear into the tile grid. It is not built.\n\n### Filters\n\nAll are optional and combine with AND. Booleans accept `1/true/yes` and\n`0/false/no`. Dates are `YYYY-MM-DD`. A value that cannot be parsed is ignored.\n\n**Text and identity**\n\n| Parameter | Matches |\n|---|---|\n| `q` | Situs address, parsed into street / city / state / ZIP and matched piece by piece. Required on `GET /parcels` unless `near` is given. |\n| `address` | Substring of `situs_address`. |\n| `parcel_id` | The county parcel number in **any** spelling - normalized, then matched exactly on `parcel_id_norm`. A search filter, not an identifier: it is the half of `property_id` after the dash, without the county. |\n| `city` | `situs_city`, case-insensitive, whole value. |\n| `zip` | `situs_zip`, exact. |\n| `owner` | An owner **entry id** (`13153_SMITH_JOHN_A`, from `/owners`) is the resolved owner and matches `owner_id` exactly. Anything else is a substring of `owner_name` **or** of any co-owner in `owner_names[]`. The two cannot be confused: no county owner line looks like an entry id. |\n| `owner_id` | Resolved owner **identity** - the same owner across every county, every spelling. A number, from `/owners/{entry_id}`. Prefer `owner=`; this stays for one release. |\n| `owner_address` | Substring of the owner's mailing address. |\n| `owner_state` | Owner's mailing state, exact, upper-cased for you. |\n| `owner_zip` | Owner's mailing ZIP, exact. |\n| `absentee` | `1` = the owner's mailing state differs from the property's state; `0` = it does not (or is unknown). |\n| `owner_occupied` | The county's own owner-occupancy flag. |\n| `source` | `qpublic` or `arcgis` - the parcel must carry that source. |\n| `has_photos` | `1` = `photo_count > 0`, `0` = none. |\n| `homestead` | The county's homestead-exemption flag. |\n| `reason` | Substring of any sale reason on the parcel (deed / qualification text from `parcel_sales`). |\n| `class` | Comma-separated list of `property_class` **prefixes**, OR'd (`class=R,C`). |\n| `use` | `property_use`, exact. |\n| `home_type` | Comma-separated home types, OR'd, the way a home search filters: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other`, `unknown`. The search words work too: `houses`, `townhomes`, `condos`, `lots`, `multi-family`, and `homes` for every kind of home. Unknown word → **400**. |\n| `home_type_strict` | `1` = only types read from the county's own words or use codes, leaving out the `inferred` ones (a class that says \"residential\" and nothing finer, read as single family) and the `zillow` ones (written before 0.52.0: the county says nothing finer and a Zillow sitemap home decided; gone after the next full reclassification). |\n| `zillow_status` | Admin keys only (**403** otherwise). The status of the Zillow home page that names the parcel (only parcels whose page has been read have one), comma-separated, OR'd: `for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`; `listed` = for sale, `sold` = recently sold. Unknown word → **400**. |\n| `zillow_sold_after` | Admin keys only. The newest sale in that page's price history is on or after this date (`zillow.sold_seen`). |\n| `messy_title` | `1` = the title is likely messy (`messy_title_likely`: any reason below but a lone quit-claim); `0` = not. |\n| `messy_title_reason` | Comma-separated, OR'd: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims`, `owner_estate`. The plain words work too: `estate` (both estate reasons), `probate`, `heirs`, `sheriff`, `trustee`, `tax`, `quitclaim`. Unknown word → **400**. |\n\n**Home type.** Every row carries `home_type` and `home_type_basis` (`text`, `code`,\n`use`, `inferred`, or `zillow` on rows from before 0.52.0). It is read from `property_class`, `building_style` and\n`property_use` with each state's own code table - Florida `001` is single family and\n`008` multi-family, Texas `A1` single family and `B2` a duplex, Ohio `520` two family\n- and is null for a county not classified yet. Where the county's columns say nothing\nfiner than \"residential\", it is single family, or land when the record says there is\nno building (`inferred`). `GET /counties/{fips}/home-types` counts them.\n\n**Messy title.** Every row carries `messy_title_likely` and `messy_title_reasons`,\nread from the deeds on file: `estate_deed` (an estate, probate, executor's or\npersonal representative's deed for nothing, or a grantor that is an estate - the\nestate selling at a price is a purchase), `foreclosure` (a\nforeclosure, sheriff's or referee's deed, a deed in lieu, a public or substitute\ntrustee's deed, a trustee's deed in a deed-of-trust state, a deed to HUD, Fannie Mae,\nFreddie Mac or the VA), `tax_deed` (a tax deed, or a deed from a treasurer or tax\ncollector), `quit_claim`, `quit_claims` (two or more within three years of each\nother) and `owner_estate` (the owner line says \"estate of\", \"heirs\", \"deceased\", or\nnames an executor). `messy_title_likely` is any of these but a lone quit-claim. A\ndeed counts only when it was recorded in the last ten years and no purchase came\nafter it (a $0 quit-claim the same day as a priced sale is that sale's). Most rolls\nrecord no deed type, so there only the parties and the owner line can flag a lot:\n`false` means \"nothing on file says so\", not \"clean\". Null until the county has\nbeen checked. Liens and unpaid taxes are not read. On the customer surface a\nuse-restricted county's rows carry null, and the two filters skip those counties.\n\n**Ranges** - `min_value` / `max_value` (`total_value`), `min_acres` / `max_acres`\n(`land_acres`), `min_sale_price` / `max_sale_price` (`last_sale_price`),\n`min_year_built` / `max_year_built`, `min_sqft` / `max_sqft` (`heated_sqft`),\n`min_beds` / `max_beds` (`bedrooms`; `beds` is the older spelling of `min_beds`\nand still means **at least**), `min_baths` / `max_baths` (full baths plus half a\nbath for each half bath, so `min_baths=1.5` keeps 1 full + 1 half and up),\n`sold_after` / `sold_before` (`last_sale_date`), `updated_after` (`updated_at`).\nAll bounds are inclusive. Zero bedrooms, baths or square feet is \"not recorded\",\nso a `max_` bound never matches a row that records none, and a bath bound never\nmatches a row with no full bath.\n\nEvery row whose `last_sale_price` and `heated_sqft` are both selected carries\n**`price_per_sqft`**: the price over the square feet, to the cent, null when the\nprice is at or under $1,000 (a transfer, not a sale) or the size is not recorded.\n\nEvery row with `situs_address` (and `owner_address`) carries it as two lines too:\n**`situs_address_line1`** and **`situs_address_line2`** - the unit, as written:\n`STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`; null when the line names none - and\n`owner_address_line1` / `owner_address_line2` for the mailing address.\n\n**Geography**\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `bbox=w,s,e,n` in decimal degrees, `w < e` and `s < n`. Malformed → **400**. |\n| `near` | `near=lat,lng`, a centre point. Adds `distance_m` to every row and makes `order=distance` the default. Malformed → **400**. |\n| `radius_m` | Metres around `near`, 1-50000, default 1000. Out of range → **400**. Ignored without `near`. On the routes with no county in the path (`GET /parcels`, `GET /parcels.geojson`) at most 8047 (five miles); wider → **422** `radius_too_large`. |\n\nDistance is a great-circle calculation in plain SQL over a bounding box first\n(there is no PostGIS on the box), so both `near` and `radius_m` only ever see\nparcels that carry coordinates.\n\n**Where a coordinate came from.** Every row carries `geocode_source` and\n`geocode_precision` beside `latitude`/`longitude`, because a parcel centroid and a\nstreet-interpolated point are not the same claim.\n\n| `geocode_source` | `geocode_precision` | What the point is |\n|---|---|---|\n| `gis` | `parcel` | The county GIS layer's own centroid for this parcel. |\n| `census` | `street` | The US Census geocoder matched the situs address and interpolated along that street segment. |\n| `census` | `centroid` | The Census geocoder matched something near the address rather than it (`geocode_match: \"Non_Exact\"`). |\n| `null` | `null` | No coordinate, or one located before we recorded where it came from. |\n\nBoth are `null` whenever `latitude` is, and `geocode_precision` is `null` for a\ncoordinate whose origin was never recorded. `rooftop` is reserved and nothing\nproduces it today: no source we read returns a rooftop point.\n\n**Shape of each row**\n\n| Parameter | Meaning |\n|---|---|\n| `fields` | Comma-separated subset of the parcel columns; `property_id` is always included. `geometry`, `record_url`, `geocode_precision`, `price_per_sqft`, `owner_display` and the address lines (`situs_address_line1`, `situs_address_line2`, `owner_address_line1`, `owner_address_line2`) are allowed. An unknown name → **400**. |\n| `geometry` | `1` adds the GeoJSON `geometry` column, which is excluded by default because it is large. |","operationId":"parcels_geojson_all_v1_parcels_geojson_get","responses":{"200":{"description":"A GeoJSON FeatureCollection of the parcels in the box or the circle, from every county it crosses.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureCollection"},"example":{"type":"FeatureCollection","features":[{"type":"Feature","id":"13153-0W050J08B000","geometry":{"type":"Polygon","coordinates":[[[-83.622,32.61],[-83.621,32.61],[-83.621,32.611],[-83.622,32.61]]]},"properties":{"property_id":"13153-0W050J08B000","county_fips":"13153","situs_address":"109 FREEMAN DR","owner_name":"SMITH JOHN A","total_value":159200}}],"count":1,"total":1,"truncated":false}}}},"400":{"description":"Neither `bbox=w,s,e,n` nor `near=lat,lng` was given, or one is malformed."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"The `bbox` covers more than the maximum area (`code: \"bbox_too_large\"`), or `radius_m` is over five miles (`code: \"radius_too_large\"`); the body carries the maximum."}}}},"/v1/parcels":{"get":{"tags":["Parcels"],"summary":"Search parcels by address or radius across counties","description":"Search **every** county we hold, for when you have a street address or a point on a map and no FIPS code. This is the usual way in.\n\n**`q` or `near` is required** (400 with neither) - that guard is what stops this route from dumping the whole table.\n\n**By address.** `q` must contain a street. It is parsed into street / city / state / ZIP and each piece is matched separately, so `q=109 Freeman Dr, Warner Robins GA 31088` narrows four ways.\n\n**By radius.** `near=lat,lng&radius_m=` returns every parcel inside the circle, whichever counties it crosses, nearest first (`order=distance` is the default, and each row carries `distance_m`). On this route `radius_m` is capped at **8047 metres (five miles)**: wider is a **422** with `code: \"radius_too_large\"` and `max_radius_m`. With `near` a page may hold up to **5000** rows (`limit`), and `total` counts the circle only. `q` and `near` combine: an address search inside a circle.\n\nEvery other filter below applies on top, and `county` is not a parameter here: use `GET /counties/{fips}/parcels` when you know the county.\n\nReturns `{items, count, total, next_cursor, next_offset}`. `count` is the size of\nthis page, `total` is the whole filtered set (a second `COUNT(*)` over the same\n`WHERE`, reused for two minutes for the same filters so paging does not recount\nthe set on every page), and the two `next_*` fields drive paging. `next_cursor` is an opaque\npaging token - feed it straight back as `cursor=` and do not store it; the\nidentifier on a parcel is `property_id`.\n\n### Filters\n\nAll are optional and combine with AND. Booleans accept `1/true/yes` and\n`0/false/no`. Dates are `YYYY-MM-DD`. A value that cannot be parsed is ignored.\n\n**Text and identity**\n\n| Parameter | Matches |\n|---|---|\n| `q` | Situs address, parsed into street / city / state / ZIP and matched piece by piece. Required on `GET /parcels` unless `near` is given. |\n| `address` | Substring of `situs_address`. |\n| `parcel_id` | The county parcel number in **any** spelling - normalized, then matched exactly on `parcel_id_norm`. A search filter, not an identifier: it is the half of `property_id` after the dash, without the county. |\n| `city` | `situs_city`, case-insensitive, whole value. |\n| `zip` | `situs_zip`, exact. |\n| `owner` | An owner **entry id** (`13153_SMITH_JOHN_A`, from `/owners`) is the resolved owner and matches `owner_id` exactly. Anything else is a substring of `owner_name` **or** of any co-owner in `owner_names[]`. The two cannot be confused: no county owner line looks like an entry id. |\n| `owner_id` | Resolved owner **identity** - the same owner across every county, every spelling. A number, from `/owners/{entry_id}`. Prefer `owner=`; this stays for one release. |\n| `owner_address` | Substring of the owner's mailing address. |\n| `owner_state` | Owner's mailing state, exact, upper-cased for you. |\n| `owner_zip` | Owner's mailing ZIP, exact. |\n| `absentee` | `1` = the owner's mailing state differs from the property's state; `0` = it does not (or is unknown). |\n| `owner_occupied` | The county's own owner-occupancy flag. |\n| `source` | `qpublic` or `arcgis` - the parcel must carry that source. |\n| `has_photos` | `1` = `photo_count > 0`, `0` = none. |\n| `homestead` | The county's homestead-exemption flag. |\n| `reason` | Substring of any sale reason on the parcel (deed / qualification text from `parcel_sales`). |\n| `class` | Comma-separated list of `property_class` **prefixes**, OR'd (`class=R,C`). |\n| `use` | `property_use`, exact. |\n| `home_type` | Comma-separated home types, OR'd, the way a home search filters: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other`, `unknown`. The search words work too: `houses`, `townhomes`, `condos`, `lots`, `multi-family`, and `homes` for every kind of home. Unknown word → **400**. |\n| `home_type_strict` | `1` = only types read from the county's own words or use codes, leaving out the `inferred` ones (a class that says \"residential\" and nothing finer, read as single family) and the `zillow` ones (written before 0.52.0: the county says nothing finer and a Zillow sitemap home decided; gone after the next full reclassification). |\n| `zillow_status` | Admin keys only (**403** otherwise). The status of the Zillow home page that names the parcel (only parcels whose page has been read have one), comma-separated, OR'd: `for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`; `listed` = for sale, `sold` = recently sold. Unknown word → **400**. |\n| `zillow_sold_after` | Admin keys only. The newest sale in that page's price history is on or after this date (`zillow.sold_seen`). |\n| `messy_title` | `1` = the title is likely messy (`messy_title_likely`: any reason below but a lone quit-claim); `0` = not. |\n| `messy_title_reason` | Comma-separated, OR'd: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims`, `owner_estate`. The plain words work too: `estate` (both estate reasons), `probate`, `heirs`, `sheriff`, `trustee`, `tax`, `quitclaim`. Unknown word → **400**. |\n\n**Home type.** Every row carries `home_type` and `home_type_basis` (`text`, `code`,\n`use`, `inferred`, or `zillow` on rows from before 0.52.0). It is read from `property_class`, `building_style` and\n`property_use` with each state's own code table - Florida `001` is single family and\n`008` multi-family, Texas `A1` single family and `B2` a duplex, Ohio `520` two family\n- and is null for a county not classified yet. Where the county's columns say nothing\nfiner than \"residential\", it is single family, or land when the record says there is\nno building (`inferred`). `GET /counties/{fips}/home-types` counts them.\n\n**Messy title.** Every row carries `messy_title_likely` and `messy_title_reasons`,\nread from the deeds on file: `estate_deed` (an estate, probate, executor's or\npersonal representative's deed for nothing, or a grantor that is an estate - the\nestate selling at a price is a purchase), `foreclosure` (a\nforeclosure, sheriff's or referee's deed, a deed in lieu, a public or substitute\ntrustee's deed, a trustee's deed in a deed-of-trust state, a deed to HUD, Fannie Mae,\nFreddie Mac or the VA), `tax_deed` (a tax deed, or a deed from a treasurer or tax\ncollector), `quit_claim`, `quit_claims` (two or more within three years of each\nother) and `owner_estate` (the owner line says \"estate of\", \"heirs\", \"deceased\", or\nnames an executor). `messy_title_likely` is any of these but a lone quit-claim. A\ndeed counts only when it was recorded in the last ten years and no purchase came\nafter it (a $0 quit-claim the same day as a priced sale is that sale's). Most rolls\nrecord no deed type, so there only the parties and the owner line can flag a lot:\n`false` means \"nothing on file says so\", not \"clean\". Null until the county has\nbeen checked. Liens and unpaid taxes are not read. On the customer surface a\nuse-restricted county's rows carry null, and the two filters skip those counties.\n\n**Ranges** - `min_value` / `max_value` (`total_value`), `min_acres` / `max_acres`\n(`land_acres`), `min_sale_price` / `max_sale_price` (`last_sale_price`),\n`min_year_built` / `max_year_built`, `min_sqft` / `max_sqft` (`heated_sqft`),\n`min_beds` / `max_beds` (`bedrooms`; `beds` is the older spelling of `min_beds`\nand still means **at least**), `min_baths` / `max_baths` (full baths plus half a\nbath for each half bath, so `min_baths=1.5` keeps 1 full + 1 half and up),\n`sold_after` / `sold_before` (`last_sale_date`), `updated_after` (`updated_at`).\nAll bounds are inclusive. Zero bedrooms, baths or square feet is \"not recorded\",\nso a `max_` bound never matches a row that records none, and a bath bound never\nmatches a row with no full bath.\n\nEvery row whose `last_sale_price` and `heated_sqft` are both selected carries\n**`price_per_sqft`**: the price over the square feet, to the cent, null when the\nprice is at or under $1,000 (a transfer, not a sale) or the size is not recorded.\n\nEvery row with `situs_address` (and `owner_address`) carries it as two lines too:\n**`situs_address_line1`** and **`situs_address_line2`** - the unit, as written:\n`STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`; null when the line names none - and\n`owner_address_line1` / `owner_address_line2` for the mailing address.\n\n**Geography**\n\n| Parameter | Meaning |\n|---|---|\n| `bbox` | `bbox=w,s,e,n` in decimal degrees, `w < e` and `s < n`. Malformed → **400**. |\n| `near` | `near=lat,lng`, a centre point. Adds `distance_m` to every row and makes `order=distance` the default. Malformed → **400**. |\n| `radius_m` | Metres around `near`, 1-50000, default 1000. Out of range → **400**. Ignored without `near`. On the routes with no county in the path (`GET /parcels`, `GET /parcels.geojson`) at most 8047 (five miles); wider → **422** `radius_too_large`. |\n\nDistance is a great-circle calculation in plain SQL over a bounding box first\n(there is no PostGIS on the box), so both `near` and `radius_m` only ever see\nparcels that carry coordinates.\n\n**Where a coordinate came from.** Every row carries `geocode_source` and\n`geocode_precision` beside `latitude`/`longitude`, because a parcel centroid and a\nstreet-interpolated point are not the same claim.\n\n| `geocode_source` | `geocode_precision` | What the point is |\n|---|---|---|\n| `gis` | `parcel` | The county GIS layer's own centroid for this parcel. |\n| `census` | `street` | The US Census geocoder matched the situs address and interpolated along that street segment. |\n| `census` | `centroid` | The Census geocoder matched something near the address rather than it (`geocode_match: \"Non_Exact\"`). |\n| `null` | `null` | No coordinate, or one located before we recorded where it came from. |\n\nBoth are `null` whenever `latitude` is, and `geocode_precision` is `null` for a\ncoordinate whose origin was never recorded. `rooftop` is reserved and nothing\nproduces it today: no source we read returns a rooftop point.\n\n**Shape of each row**\n\n| Parameter | Meaning |\n|---|---|\n| `fields` | Comma-separated subset of the parcel columns; `property_id` is always included. `geometry`, `record_url`, `geocode_precision`, `price_per_sqft`, `owner_display` and the address lines (`situs_address_line1`, `situs_address_line2`, `owner_address_line1`, `owner_address_line2`) are allowed. An unknown name → **400**. |\n| `geometry` | `1` adds the GeoJSON `geometry` column, which is excluded by default because it is large. |\n\n### Paging\n\n| Parameter | Meaning |\n|---|---|\n| `limit` | Rows per page, 1-500 (default 100). |\n| `order` | `id` (default), `value_desc`, `sale_date_desc`, `updated_desc`, `sqft_desc`, `acres_desc`, `year_built_desc`, `ppsf_desc` (sale price ÷ heated sqft), `distance` (only with `near=`). An unknown value falls back to `id`. |\n| `cursor` | **`order=id` only.** Returns rows with `id >` this. Feed back `next_cursor`. |\n| `offset` | **Every other order.** 0-50000. Feed back `next_offset`. |\n\nSo there are two paging modes and the response tells you which one you are in:\n`order=id` fills `next_cursor` (stable while rows are being written underneath\nyou), any other order fills `next_offset`. The other field is `null`, and both\nare `null` on the last page.","operationId":"parcels_search_v1_parcels_get","responses":{"200":{"description":"Matching parcels from every county.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelList"},"example":{"items":[{"property_id":"13153-0W050J08B000","county_fips":"13153","state":"GA","parcel_id_norm":"0W050J08B000","parcel_id_raw":"0W050J    08B000","account_number":"13554","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_state":"GA","situs_zip":"31088","owner_name":"SMITH JOHN A","owner_names":["SMITH JOHN A","SMITH MARY B"],"owner_address":"109 FREEMAN DR","owner_city":"WARNER ROBINS","owner_state":"GA","owner_zip":"31088","owner_occupied":true,"owner_id":"13153_SMITH_JOHN_A","owner_verified":true,"owner_display":"SMITH, JOHN A","property_class":"R3","property_use":"Residential","zoning":"R-1","tax_district":"COUNTY","homestead":true,"land_acres":0.46,"building_count":1,"building_style":"RANCH","year_built":1978,"heated_sqft":1684,"bedrooms":3,"full_baths":2,"half_baths":0,"condition":"AVERAGE","last_sale_date":"2019-06-14","last_sale_price":132000,"assessed_year":2025,"land_value":18000,"improvement_value":141200,"total_value":159200,"est_annual_tax":1234.5,"latitude":32.6105,"longitude":-83.6219,"geocode_source":"gis","geocode_precision":"parcel","photo_count":2,"sketch_count":1,"sources":["arcgis","qpublic"],"source_urls":{"qpublic":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000"},"record_url":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000","last_seen_at":"2026-09-14T03:21:55+00:00","updated_at":"2026-09-14T03:21:55+00:00","home_type":"single_family","home_type_basis":"inferred","zillow":{"zpid":35956751,"status":"recently_sold","status_at":"2026-09-30","sold_seen":"2026-09-30","price":214000,"url":"https://www.zillow.com/homedetails/109-Freeman-Dr-Warner-Robins-GA-31088/35956751_zpid/"},"messy_title_likely":false,"messy_title_reasons":[]}],"count":1,"total":1}}}},"400":{"description":"Neither `q` (with a street) nor `near` was given, a geo parameter was malformed, or `fields` named an unknown column."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"422":{"description":"`radius_m` is over five miles; the body carries `code: \"radius_too_large\"` and the maximum."}}}},"/v1/parcels/{property_id}":{"get":{"tags":["Parcels"],"summary":"Get one parcel","description":"The full record for one parcel, by its property id.\n\n`property_id` is `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`. It is derived from the county's own parcel number, so it survives re-imports, rebuilds and moves between machines, and it is the only identifier a parcel object carries. The parcel-number half is normalized for you, so any spelling of it resolves.\n\nA malformed id and an unknown one are both a **404**: either way there is no such property.\n\nBeyond the typed columns of the parcel row, a full record carries:\n\n| Field | What it holds |\n|---|---|\n| `record_url` | The county's own property-record page for this parcel (the qPublic report URL where that source captured one). `null` for counties that expose none. |\n| `sales[]` | Every recorded sale, newest first: date, price, grantor, grantee, deed and plat book/page, and the `reason` the county gave - which is what `reason=` filters on. |\n| `buildings[]` | Each structure: year built, heated sqft, value, and the county's own attribute list. |\n| `values[]` | The assessment history, newest year first. |\n| `images[]` | Photo and sketch metadata with a `url` to fetch each. `stored` is authoritative - only `stored: true` images have bytes here. |\n| `owners[]` | Each owner line resolved to its clustered identity: `{identity_id, canonical_name, kind, key, method}`. Feed `identity_id` to `?owner_id=` to pull up everything else that owner holds, or to `/owners/{id}`. Empty on a database that predates the owner tables rather than failing the record. |\n| `permits[]` | The Permits module, typed to `{date, number, type, raw}`. |\n| `sections[]` | **Every** module of the source page, verbatim - Summary, Owner, Land, Rural Land, Permits, Mobile Homes, Conservation Use, whatever that county publishes - as `{name, fields[], grids[], images[]}`. This is the \"nothing is dropped\" guarantee: a value with no typed column of its own is still here. |\n| `no_data_modules[]` | Modules the page listed but left empty for this parcel. |\n\n`sections[]` and `permits[]` come from the most recent parsed qPublic capture, so\nthey are empty for a parcel only ArcGIS has reached.","operationId":"parcel_v1_parcels__property_id__get","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","description":"The property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`. The parcel-number half is normalized, so any spelling of it resolves.","title":"Property Id"},"description":"The property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`. The parcel-number half is normalized, so any spelling of it resolves."}],"responses":{"200":{"description":"The full parcel record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelDetail"},"example":{"property_id":"13153-0W050J08B000","county_fips":"13153","state":"GA","parcel_id_norm":"0W050J08B000","parcel_id_raw":"0W050J    08B000","account_number":"13554","situs_address":"109 FREEMAN DR","situs_city":"WARNER ROBINS","situs_state":"GA","situs_zip":"31088","owner_name":"SMITH JOHN A","owner_names":["SMITH JOHN A","SMITH MARY B"],"owner_address":"109 FREEMAN DR","owner_city":"WARNER ROBINS","owner_state":"GA","owner_zip":"31088","owner_occupied":true,"owner_id":"13153_SMITH_JOHN_A","owner_verified":true,"owner_display":"SMITH, JOHN A","property_class":"R3","property_use":"Residential","zoning":"R-1","tax_district":"COUNTY","homestead":true,"land_acres":0.46,"building_count":1,"building_style":"RANCH","year_built":1978,"heated_sqft":1684,"bedrooms":3,"full_baths":2,"half_baths":0,"condition":"AVERAGE","last_sale_date":"2019-06-14","last_sale_price":132000,"assessed_year":2025,"land_value":18000,"improvement_value":141200,"total_value":159200,"est_annual_tax":1234.5,"latitude":32.6105,"longitude":-83.6219,"geocode_source":"gis","geocode_precision":"parcel","photo_count":2,"sketch_count":1,"sources":["arcgis","qpublic"],"source_urls":{"qpublic":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000"},"record_url":"https://qpublic.schneidercorp.com/Application.aspx?AppID=1046&KeyValue=0W050J++++08B000","last_seen_at":"2026-09-14T03:21:55+00:00","updated_at":"2026-09-14T03:21:55+00:00","home_type":"single_family","home_type_basis":"inferred","zillow":{"zpid":35956751,"status":"recently_sold","status_at":"2026-09-30","sold_seen":"2026-09-30","price":214000,"url":"https://www.zillow.com/homedetails/109-Freeman-Dr-Warner-Robins-GA-31088/35956751_zpid/"},"messy_title_likely":false,"messy_title_reasons":[],"messy_title":{"likely":false,"reasons":[],"evidence":[],"checked_at":"2026-10-21T04:31:10+00:00"},"source_keys":{"qpublic":"0W050J    08B000","arcgis":"0W050J    08B000"},"sales":[{"id":9901,"source":"qpublic","sale_date":"2019-06-14","sale_price":132000,"grantor":"JONES ROBERT","grantee":"SMITH JOHN A","deed_book_page":"4412/233","reason":"Fair Market Value"}],"buildings":[{"id":3310,"source":"qpublic","kind":"residential","position":1,"year_built":1978,"sqft":1684,"value":141200,"attributes":{"Exterior Wall":"BRICK","Heat":"CENTRAL"}}],"values":[{"source":"qpublic","year":2025,"land_value":18000,"improvement_value":141200,"accessory_value":0,"total_value":159200,"previous_value":151400}],"images":[{"id":77012,"source":"qpublic","kind":"photo","position":1,"variant":"full","caption":"Property photo","mime":"image/jpeg","byte_size":148221,"fetched_at":"2026-09-14T03:21:55+00:00","stored":true,"has_full":true,"source_url":"https://qpublicimages.blob.core.windows.net/...?sig=expired","source_expires_at":"2026-09-15T03:21:50+00:00","url":"/images/77012"}],"owners":[{"entry_id":"13153_SMITH_JOHN_A","entry_name":"SMITH, JOHN A","verified":true,"identity_id":51204,"canonical_name":"SMITH JOHN","kind":"person","key":"person|smith john a|109 freeman dr|31088","method":"auto"}],"permits":[{"date":"2021-04-02","number":"B21-0417","type":"REROOF","raw":{"Permit Date":"04/02/2021","Permit Number":"B21-0417","Type":"REROOF"}}],"sections":[{"name":"Summary","fields":[{"label":"Parcel Number","value":"0W050J    08B000"}],"grids":[],"images":[]}],"no_data_modules":["Mobile Homes","Conservation Use"]}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel with that property id, or the id is malformed."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/parcels/sales":{"post":{"tags":["Parcels"],"summary":"Sales of many parcels at once","description":"The full sale history of up to **1,000 parcels in one call** - the same `sales[]` each full record carries, without a request per lot.\n\nBody: `{\"property_ids\": [...]}`. Each item comes back in the order asked with its `sales[]` newest first, plus the parcel's own `last_sale_date` and `last_sale_price` - a bulk roll can fill those without a sale row, so `sales` may be empty while a sale is known. `missing` lists the ids that are malformed or not on file; a lot that exists and has no sales is in `items` with `sales: []`. Duplicate ids are answered once. The property-number half of each id is normalized for you, so any spelling resolves.\n\nOne call is one metered request whatever its size. A body over the limit is a **400**, not a truncated answer.","operationId":"parcel_sales_batch_v1_parcels_sales_post","requestBody":{"description":"`property_ids`: 1 to 1,000 property ids, `{county_fips}-{parcel_number}`.","content":{"application/json":{"example":{"property_ids":["13153-0W050J08B000","13153-0W050J08C000"]}}},"required":true},"responses":{"200":{"description":"One entry per parcel on file, in the order asked; `missing` names the rest.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParcelSalesBatch"},"example":{"items":[{"property_id":"13153-0W050J08B000","last_sale_date":"2021-06-30","last_sale_price":285000,"sales":[{"id":9120031,"source":"qpublic","sale_date":"2021-06-30","sale_price":285000,"grantor":"SMITH JOHN","grantee":"DOE JANE","deed_book_page":"4431 / 207","reason":"Fair Market Value"},{"id":9120030,"source":"qpublic","sale_date":"2014-03-12","sale_price":190000,"grantor":"ACME HOMES LLC","grantee":"SMITH JOHN","deed_book_page":"3980 / 15","reason":"Fair Market Value"}]}],"count":1,"missing":["13153-0W050J08C000"]}}}},"400":{"description":"Body was not a JSON object, `property_ids` was not a non-empty list of strings, or it held more than 1,000 ids."},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."}}}},"/v1/parcels/{property_id}/images":{"get":{"tags":["Images"],"summary":"List a parcel's images","description":"Metadata for every image captured for one parcel - photos and sketches, full-size and thumbnail - ordered by kind, then position, then variant.\n\n`stored` is the field that matters: `stored: true` rows have bytes on this box, and `url` (`/images/{id}`) serves them. A `stored: false` row is held as a link only (the collector's `images=urls` setting): the first request to its `url` fetches the bytes from `source_url`, stores them and serves them, while `source_expires_at` has not passed. `caption` is the county page's own text for the picture. `has_full` is the one to read on a thumbnail - it says whether the full-resolution version of the same picture is stored, so a screen can say \"thumbnail only\" rather than enlarging a blurred image. `source_url` is the county's own link the image came from and is **provenance, not a URL to serve** - qPublic hands out signed links that expire roughly 24 hours after the fetch.\n\nTo filter to one variant, or to get an ETag-cached fetch URL alongside each row, use `GET /parcels/{property_id}/images/{variant}`.","operationId":"parcel_images_v1_parcels__property_id__images_get","parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","description":"The property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`. The parcel-number half is normalized, so any spelling of it resolves.","title":"Property Id"},"description":"The property id, `{county_fips}-{parcel_number}` - for example `13153-0W050J08B000`. The parcel-number half is normalized, so any spelling of it resolves."}],"responses":{"200":{"description":"Image metadata for the parcel; `items` is empty when it has none.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageList"},"example":{"items":[{"id":77012,"source":"qpublic","kind":"photo","position":1,"variant":"full","caption":"Property photo","mime":"image/jpeg","byte_size":148221,"fetched_at":"2026-09-14T03:21:55+00:00","stored":true,"has_full":true,"source_url":"https://qpublicimages.blob.core.windows.net/...?sig=expired","source_expires_at":"2026-09-15T03:21:50+00:00","url":"/images/77012"}]}}}},"401":{"description":"Missing, malformed or wrong `Authorization: Bearer <API_TOKEN>` header."},"404":{"description":"No parcel with that property id, or the id is malformed."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/images/{image_id}":{"get":{"tags":["Images"],"summary":"Fetch image bytes","description":"The stored bytes of one image, served with its own content type and `Cache-Control: private, max-age=86400`. This is the `url` each image metadata row carries.\n\n**This route returns image bytes, not JSON** - the one exception in the API. The exceptions to *that* are JSON: a 404 when the row exists but its bytes cannot be had (`{error, stored, source_url, reason}`), and a 503 when its source refused just now. Prefer `GET /images/{image_id}/bytes`, which is the same picture with an ETag and 304 support.\n\n**A link-only image is fetched on the first request.** With the collector on `images=urls` a row holds the county's link and no bytes. The first request fetches the bytes from `source_url` (the collector's User-Agent, the scraper's main proxy, a hard 20 second deadline, one fetch per image however many requests arrive together, four fetches at most at once), stores them, and serves them; every later request is served from storage, and stored bytes are never fetched again. Only a real JPEG, PNG, GIF or WebP is stored, and its content type is the one its bytes say. Only https links on the image hosts the collector records are fetched, from public addresses, following at most three redirects on the same host. If the source refuses - a 403, a 429, a Cloudflare challenge page, anything that is not an image, the deadline - the answer is a **503** with `Retry-After: 900` and a JSON body naming `source_url`, and nothing is stored. That source URL is then remembered for fifteen minutes: a request for it inside them gets the same 503 at once, without asking the source. A 503 whose `Retry-After` is 30 means this server was busy, not the source. A signed link past its expiry, or one outside the image hosts, is not tried: that is the 404 below.","operationId":"image_v1_images__image_id__get","parameters":[{"name":"image_id","in":"path","required":true,"schema":{"type":"integer","description":"`raw_images.id`, as carried by each image metadata row.","title":"Image Id"},"description":"`raw_images.id`, as carried by each image metadata row."}],"responses":{"200":{"description":"The image bytes.","content":{"image/jpeg":{},"image/png":{},"application/octet-stream":{}}},"401":{"description":"Missing, malformed or wrong bearer token."},"404":{"description":"No such image row, or its bytes cannot be had: no link was recorded, the link is not https on one of the image hosts the collector records, or the signed link expired before anybody asked (a JSON body then carries `stored: false`, `source_url` and `reason`; the parcel's next scrape records a fresh link).","content":{"application/json":{"example":{"error":"image bytes not stored","stored":false,"source_url":"https://qpublicimages.blob.core.windows.net/...","reason":"the source link expired at 2026-09-15T03:21:50+00:00; the parcel's next scrape records a fresh one","source_expires_at":"2026-09-15T03:21:50+00:00"}}}},"503":{"description":"The image is held only as a link and its source refused the fetch just now (403, 429, a Cloudflare challenge page, a timeout). Nothing was stored; `Retry-After` says when to ask again, and the next request tries the source again.","content":{"application/json":{"example":{"detail":"the image could not be fetched from its source: the source answered 403","stored":false,"source_url":"https://qpublicimages.blob.core.windows.net/...","reason":"the source answered 403","retry_after_s":900,"error":{"code":"unavailable","message":"the image could not be fetched from its source: the source answered 403","request_id":"6f1c4e0a9b2d4c1e8f3a7b5d2e9c1a40"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AcqCellList":{"properties":{"zone":{"type":"string","title":"Zone","description":"5070 (lower 48), 3338 (Alaska) or 26904 (Hawaii).","examples":["5070"]},"cell_m":{"type":"number","title":"Cell M","default":304.8},"months":{"type":"integer","title":"Months"},"total":{"type":"integer","title":"Total"},"items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Items","default":[]},"built_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Built At"}},"additionalProperties":true,"type":"object","required":["zone","months","total"],"title":"AcqCellList","description":"`GET /acqtrack/cells`: the 1,000-ft grid squares in a box."},"AcqMonth":{"properties":{"month":{"type":"string","title":"Month","examples":["2026-09"]},"all_sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"All Sales"},"sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sales"},"parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parcels"},"dollars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dollars"},"buyers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Buyers","description":"Distinct owners that month."},"flips":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Flips"}},"additionalProperties":true,"type":"object","required":["month"],"title":"AcqMonth","description":"One month of a region (`series=1`)."},"AcqRegion":{"properties":{"key":{"type":"string","title":"Key","description":"The FIPS, the 2-letter state or the 5-digit ZIP.","examples":["13153"]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"use_restriction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use Restriction","examples":["ks-45-230"]},"latest_sale":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Latest Sale","description":"The newest sale counted: 'data through'."},"all_sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"All Sales","description":"Every recorded deed in the window."},"sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sales","description":"The arm's-length deeds."},"parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parcels","description":"Lots whose arm's-length last sale is in the window."},"priced_sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Priced Sales"},"dollars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dollars","description":"Sale dollars, a package deed counted once."},"dollars_per_lot":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dollars Per Lot","description":"Every lot's own price summed, as the circle does."},"avg_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Price"},"avg_price_per_lot":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Price Per Lot"},"buyers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Buyers","description":"Distinct owners over the window."},"buyers_exact":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Buyers Exact","description":"False where distinct owners had to be added across months, uses or counties."},"acres":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Acres"},"distressed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Distressed"},"occupied":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Occupied"},"absentee":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Absentee"},"package_lots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Package Lots"},"flips_known":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Flips Known"},"flips":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Flips"},"avg_hold_days":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Hold Days"},"rated_flips":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rated Flips"},"per_day":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Per Day","description":"Flip gain over held days, summed."},"series":{"anyOf":[{"items":{"$ref":"#/components/schemas/AcqMonth"},"type":"array"},{"type":"null"}],"title":"Series"}},"additionalProperties":true,"type":"object","required":["key"],"title":"AcqRegion","description":"One county, state or ZIP of National AcqTrack (`GET /acqtrack/regions`). Every\nmeasure is null for a use-restricted region; the dollar measures are null where no\nsale carries a price; the flip measures are null where no lot has an earlier sale\non file (`flips_known: false`)."},"AcqRegionList":{"properties":{"scope":{"type":"string","title":"Scope"},"months":{"type":"integer","title":"Months"},"total":{"type":"integer","title":"Total","description":"Regions matching, before `limit`."},"items":{"items":{"$ref":"#/components/schemas/AcqRegion"},"type":"array","title":"Items","default":[]},"built_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Built At"},"counts_age_s":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Counts Age S"}},"additionalProperties":true,"type":"object","required":["scope","months","total"],"title":"AcqRegionList","description":"`GET /acqtrack/regions`: regions ranked by one measure."},"AcqSpot":{"properties":{"key":{"type":"string","title":"Key","description":"s<radius_m>:<zone>:<cx>:<cy>.","examples":["s805:5070:3739:3647"]},"rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rank"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat","description":"The centre square's centre, WGS84."},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"radius_m":{"type":"integer","title":"Radius M","description":"402, 805 or 1609 (1/4, 1/2 or 1 mile).","examples":[805]},"zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip","description":"The centre square's lots' majority ZIP."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"county_fips":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Fips"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"all_sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"All Sales"},"sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sales"},"parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parcels"},"priced_sales":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Priced Sales"},"dollars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dollars"},"dollars_per_lot":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dollars Per Lot"},"avg_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Price"},"buyers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Buyers"},"buyers_exact":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Buyers Exact"},"acres":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Acres"},"distressed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Distressed"},"occupied":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Occupied"},"absentee":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Absentee"},"package_lots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Package Lots"},"flips_known":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Flips Known"},"flips":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Flips"},"avg_hold_days":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Hold Days"},"rated_flips":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rated Flips"},"per_day":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Per Day"},"series":{"anyOf":[{"items":{"$ref":"#/components/schemas/AcqMonth"},"type":"array"},{"type":"null"}],"title":"Series","description":"`/acqtrack/spots/{key}` only."},"buyers_top":{"anyOf":[{"items":{"$ref":"#/components/schemas/AcqSpotBuyer"},"type":"array"},{"type":"null"}],"title":"Buyers Top","description":"`/acqtrack/spots/{key}` only."},"parcel_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Parcel Ids","description":"`/acqtrack/spots/{key}` only: every lot whose own last sale in the window is inside the circle."}},"additionalProperties":true,"type":"object","required":["key","radius_m"],"title":"AcqSpot","description":"One Neighborhood AcqTrack circle (`GET /acqtrack/spots`): the AcqTrack measures\nover the 1,000-ft grid squares within `radius_m` of its centre square. `buyers`\nadds each square's and month's distinct owners (`buyers_exact` is false)."},"AcqSpotBuyer":{"properties":{"buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"purchases":{"type":"integer","title":"Purchases"},"dollars":{"type":"integer","title":"Dollars"}},"additionalProperties":true,"type":"object","required":["purchases","dollars"],"title":"AcqSpotBuyer","description":"One of a circle's biggest buyers."},"AcqSpotList":{"properties":{"radius_m":{"type":"integer","title":"Radius M"},"months":{"type":"integer","title":"Months"},"total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total","description":"Circles in the list, before `limit`."},"items":{"items":{"$ref":"#/components/schemas/AcqSpot"},"type":"array","title":"Items","default":[]},"built_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Built At"},"counts_age_s":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Counts Age S"}},"additionalProperties":true,"type":"object","required":["radius_m","months"],"title":"AcqSpotList","description":"`GET /acqtrack/spots`: disjoint circles ranked by one measure."},"BuyerDetail":{"properties":{"buyer_id":{"type":"string","title":"Buyer Id"},"requested":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested","description":"What you asked for, when an alias resolved to a different id."},"retired":{"type":"boolean","title":"Retired","default":false},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"identity_ids":{"items":{"type":"integer"},"type":"array","title":"Identity Ids","default":[]},"entries":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Entries","default":[]},"stats":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Stats"},"purchases":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Purchases","default":[]}},"additionalProperties":true,"type":"object","required":["buyer_id"],"title":"BuyerDetail","description":"One investor: its entities, its measured profile and its purchases."},"BuyerList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BuyerSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"additionalProperties":true,"type":"object","required":["items","total"],"title":"BuyerList"},"BuyerMatch":{"properties":{"rank":{"type":"integer","title":"Rank"},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Id"},"entry_ids":{"items":{"type":"string"},"type":"array","title":"Entry Ids","default":[]},"score":{"type":"number","title":"Score","description":"0-100: `points` over the sum of the weights in force."},"points":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Points","description":"The raw weighted sum of `components`; the ranking sorts on it."},"components":{"additionalProperties":true,"type":"object","title":"Components","description":"Per-signal `{value, weight, points}`, `human_signal` among them.","default":{}},"votes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Votes","description":"This property's weighted `up`, `down`, `net`, and `mine`: the asking `voter_id`'s own vote."},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"`verified`, `rejected` or `auto`, from the weighted net against the threshold.","examples":["auto"]},"pinned":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pinned"},"owned_ever":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Owned Ever","description":"Lots a qualifying deed on file shows them buying, plus the lots on the roll in their name no such deed covers."},"owned_now":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Owned Now","description":"Parcels on the current roll in this buyer's name, every county."},"absentee":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Absentee","description":"Bought one of these lots to hold, not to live in; null when there is no address to compare."}},"additionalProperties":true,"type":"object","required":["rank","score"],"title":"BuyerMatch","description":"One ranked buyer, with the arithmetic that produced the score."},"BuyerMatchResult":{"properties":{"target":{"additionalProperties":true,"type":"object","title":"Target","description":"The property the ranking was computed for.","default":{}},"radius_miles":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Radius Miles"},"widened":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Widened"},"candidates":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Candidates"},"excluded_flagged":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Excluded Flagged"},"excluded_by_rule":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Excluded By Rule"},"excluded_by_filters":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Excluded By Filters","description":"Buyers the Local Buyers requirements removed."},"filters":{"additionalProperties":true,"type":"object","title":"Filters","description":"The Local Buyers filters applied: `bought_after`, `same_type`, `type_bucket`, `min_owned_ever`, `min_owned_now`, `absentee`.","default":{}},"include_gov":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Include Gov"},"weights":{"additionalProperties":true,"type":"object","title":"Weights","default":{}},"generated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Generated At"},"buyers":{"items":{"$ref":"#/components/schemas/BuyerMatch"},"type":"array","title":"Buyers","default":[]},"hidden":{"items":{"$ref":"#/components/schemas/BuyerMatch"},"type":"array","title":"Hidden","default":[]},"rematch":{"anyOf":[{"$ref":"#/components/schemas/Rematch"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"BuyerMatchResult","description":"Who is most likely to buy this property, and why."},"BuyerSummary":{"properties":{"buyer_id":{"type":"string","title":"Buyer Id","examples":["BID-000123"]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"purchases":{"type":"integer","title":"Purchases","default":0},"last_purchase":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Last Purchase"},"counties":{"items":{"type":"string"},"type":"array","title":"Counties","default":[]}},"additionalProperties":true,"type":"object","required":["buyer_id"],"title":"BuyerSummary"},"ChangeFeed":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ChangeItem"},"type":"array","title":"Items"},"count":{"type":"integer","title":"Count"},"since":{"type":"string","format":"date-time","title":"Since","description":"The instant this page started after."},"next_since":{"type":"string","format":"date-time","title":"Next Since","description":"The timestamp watermark. Safe, but ambiguous at a tie - prefer `next_cursor`."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"The opaque cursor for the next page. Feed it back as `cursor=`. An empty page echoes the cursor you sent, so it is only null when the feed has never handed you an item."},"limit":{"type":"integer","title":"Limit"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State","description":"Only on the cross-county feed, echoing `state=`."}},"additionalProperties":true,"type":"object","required":["items","count","since","next_since","limit"],"title":"ChangeFeed","description":"One page of changes, oldest first."},"ChangeItem":{"properties":{"property_id":{"type":"string","title":"Property Id","examples":["13153-0W050J08B000"]},"op":{"type":"string","enum":["upsert","delete"],"title":"Op"},"at":{"type":"string","format":"date-time","title":"At","description":"`parcels.updated_at` for an upsert, `parcel_tombstones.deleted_at` for a delete."}},"additionalProperties":true,"type":"object","required":["property_id","op","at"],"title":"ChangeItem","description":"One change in the feed. Fetch the record with `GET /parcels/{property_id}`;\nan `op` of `delete` means the parcel is gone and there is nothing to fetch."},"Comp":{"properties":{"property_id":{"type":"string","title":"Property Id"},"county_fips":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Fips"},"situs_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address"},"situs_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs City"},"situs_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Zip"},"sale_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Sale Date"},"sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Price","description":"Always over the transfer line (1,000)."},"price_per_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Sqft","description":"`sale_price` / `heated_sqft`."},"sale_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sale Reason","description":"The county's transfer reason for this sale, verbatim. Null where the county records none."},"arms_length":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Arms Length","description":"True when `sale_reason` is a purchase, false when it is not (only with `arms_length=0`), null when there was no reason to judge."},"sale_flags":{"items":{"type":"string"},"type":"array","title":"Sale Flags","description":"`distressed`, `multi_parcel`, `unvalidated`: labels on a sale that still counts."},"distance_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance M","description":"Metres from the subject's point."},"similarity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Similarity","description":"0-1: 1 at the subject's figures, 0 at the edges of the ranges, averaged over the ranges in force."},"bedrooms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bedrooms"},"baths":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Baths","description":"Full baths plus half a bath per half bath."},"full_baths":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Full Baths"},"half_baths":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Half Baths"},"heated_sqft":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heated Sqft"},"land_acres":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Land Acres"},"year_built":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year Built"},"type_bucket":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type Bucket","description":"`sfr`, `multifamily`, `land`, `mobile_home`, `commercial` or `other`.","examples":["sfr"]},"property_use":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Use"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"geometry":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Geometry","description":"Only with `geometry=1`."}},"additionalProperties":true,"type":"object","required":["property_id"],"title":"Comp","description":"One comparable sale (`GET /parcels/{property_id}/comps`): the sale, how far\nit is, the parcel's key facts and how similar it is. A measure the county did\nnot record is null, never 0. `fields=` narrows it; `property_id` stays."},"CompsResult":{"properties":{"subject":{"additionalProperties":true,"type":"object","title":"Subject","description":"The property's own facts: `property_id`, situs, point, `type_bucket`, the five measures, last sale."},"ranges":{"additionalProperties":true,"type":"object","title":"Ranges","description":"What a comp had to fit: `radius_m` (after any widening), `radius_requested_m`, `months`, `sold_after`, `sold_before`, `sale_price_over`, `arms_length`, `{min, max}` per measure (null when off), `type_bucket`, and `off` (measure -> why)."},"items":{"items":{"$ref":"#/components/schemas/Comp"},"type":"array","title":"Items"},"count":{"type":"integer","title":"Count","description":"Comps returned."},"matched":{"type":"integer","title":"Matched","description":"Comps that passed every filter, before `limit`."},"widened":{"type":"boolean","title":"Widened","description":"The radius doubled to reach `limit`."},"capped":{"type":"boolean","title":"Capped","description":"More candidates than the pool holds; `matched` is a floor."},"order":{"type":"string","title":"Order","description":"`distance`, `similarity` or `recent`.","examples":["distance"]},"summary":{"$ref":"#/components/schemas/CompsSummary"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note","description":"Why there are no comps, when the subject has no coordinates."}},"additionalProperties":true,"type":"object","required":["subject","ranges","items","count","matched","widened","capped","order","summary"],"title":"CompsResult","description":"Comparable recent sales around one property, with what was applied."},"CompsSummary":{"properties":{"comps":{"type":"integer","title":"Comps","description":"Comps the medians are over: `count`."},"median_sale_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Median Sale Price","description":"Null with no comps."},"median_price_per_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Median Price Per Sqft","description":"Over the comps with a recorded size only."},"with_sale_price":{"type":"integer","title":"With Sale Price","description":"Comps the price median is over."},"with_price_per_sqft":{"type":"integer","title":"With Price Per Sqft","description":"Comps the per-square-foot median is over."}},"additionalProperties":true,"type":"object","required":["comps","with_sale_price","with_price_per_sqft"],"title":"CompsSummary","description":"The medians over the comps returned (`items`), not over `matched`."},"County":{"properties":{"fips":{"type":"string","title":"Fips","examples":["13153"]},"state":{"type":"string","title":"State"},"name":{"type":"string","title":"Name"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"land_area_sqmi":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Land Area Sqmi"},"parcels":{"type":"integer","title":"Parcels","description":"Rows in `parcels` for this county. 0 when nothing has run."},"last_updated":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Updated","description":"Newest `updated_at` in the county. Null when we hold no parcels."},"sources":{"items":{"type":"string"},"type":"array","title":"Sources","description":"Enabled collectors. Empty means nothing is configured, so nothing will ever run here."}},"additionalProperties":true,"type":"object","required":["fips","state","name","parcels","sources"],"title":"County","description":"One county in the registry, with how much of it we hold."},"CountyCoverage":{"properties":{"parcels":{"type":"integer","title":"Parcels"},"from_qpublic":{"type":"integer","title":"From Qpublic"},"from_arcgis":{"type":"integer","title":"From Arcgis"},"with_photos":{"type":"integer","title":"With Photos"},"with_location":{"type":"integer","title":"With Location"},"with_sales":{"type":"integer","title":"With Sales"},"with_buildings":{"type":"integer","title":"With Buildings"},"pct_qpublic":{"type":"number","title":"Pct Qpublic"},"pct_arcgis":{"type":"number","title":"Pct Arcgis"},"pct_photos":{"type":"number","title":"Pct Photos"},"pct_sales":{"type":"number","title":"Pct Sales"},"pct_buildings":{"type":"number","title":"Pct Buildings"},"pct_location":{"type":"number","title":"Pct Location"},"fields_pct":{"additionalProperties":{"type":"number"},"type":"object","title":"Fields Pct","description":"Share of parcels carrying each detail column: `owner`, `mailing`, `value`, `sale_date`, `sale_price`, `year_built`, `sqft`, `beds`.","default":{}},"detail_status":{"type":"string","enum":["full","partial","none"],"title":"Detail Status","description":"`full`: nothing missing. `partial`: some kind of detail is under 10% of the parcels. `none`: every kind the state can publish is - the parcels carry little beyond the map shape.","default":"none"},"missing":{"items":{"type":"string"},"type":"array","title":"Missing","description":"The kinds of detail under 10% of the parcels carry: `owners`, `sale prices`, `buildings`, `values` - leaving out what is `not_published`.","default":[]},"not_published":{"items":{"type":"string"},"type":"array","title":"Not Published","description":"The kinds no free official source publishes for this county (non-disclosure prices, withheld owner names). Never counted as missing.","default":[]},"not_published_why":{"additionalProperties":{"type":"string"},"type":"object","title":"Not Published Why","description":"The reason per `not_published` kind.","default":{}},"last_good_run":{"additionalProperties":true,"type":"object","title":"Last Good Run","description":"`{source: {id, finished_at}}` for the newest run that reached `done`. A source that never succeeded is absent.","default":{}},"eta":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Eta","description":"Projected from the running collector's own throughput. Null unless a qPublic run is running and has stored something."},"counted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Counted At","description":"When this county's numbers were read. A county is recounted when a run on it finishes, so this can be fresher than the national copy."},"counts_age_s":{"type":"integer","title":"Counts Age S","description":"Seconds since `counted_at`.","default":0}},"additionalProperties":true,"type":"object","required":["parcels","from_qpublic","from_arcgis","with_photos","with_location","with_sales","with_buildings","pct_qpublic","pct_arcgis","pct_photos","pct_sales","pct_buildings","pct_location"],"title":"CountyCoverage","description":"How complete one county is: the raw counts, the same numbers as percentages,\nthe newest good run per source, and an ETA while a qPublic run is in flight."},"CountyDetail":{"properties":{"fips":{"type":"string","title":"Fips"},"state":{"type":"string","title":"State"},"name":{"type":"string","title":"Name"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"land_area_sqmi":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Land Area Sqmi"},"sources":{"items":{"$ref":"#/components/schemas/CountySourceConfig"},"type":"array","title":"Sources","default":[]},"counts":{"additionalProperties":true,"type":"object","title":"Counts","description":"`parcels`, `from_qpublic`, `from_arcgis`, `with_photos`, `with_location`, `last_updated`. The source counts overlap.","default":{}},"raw":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Raw","default":[]},"images":{"additionalProperties":true,"type":"object","title":"Images","default":{}},"runs":{"items":{"$ref":"#/components/schemas/CountyRun"},"type":"array","title":"Runs","default":[]}},"additionalProperties":true,"type":"object","required":["fips","state","name"],"title":"CountyDetail","description":"One county on one page: its registry row, its collectors, its counts, what\neach source captured, its stored images and its ten most recent runs."},"CountyGisLinkList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CountyGisLinks"},"type":"array","title":"Items","default":[]},"count":{"type":"integer","title":"Count","default":0},"with_link":{"type":"integer","title":"With Link","description":"How many of `items` have a `gis_link`.","default":0}},"additionalProperties":true,"type":"object","title":"CountyGisLinkList","description":"`GET /gis-links`: every county's links, ordered by FIPS."},"CountyGisLinks":{"properties":{"fips":{"type":"string","title":"Fips","examples":["13153"]},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State","examples":["GA"]},"county":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County","examples":["Houston County"]},"gis_link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gis Link","description":"The best link: the first of `property_site`, `parcel_map`, `tax_roll`, `data_download`. Null when none is known."},"link_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link Type","description":"`property_site`, `parcel_map`, `tax_roll` or `data_download`.","examples":["property_site"]},"link_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link Source","description":"The collector the link came from."},"property_site":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Site","description":"The county's own property-record or map site."},"property_site_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Site Source"},"parcel_map":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parcel Map","description":"The county's parcel layer in a free web map viewer."},"parcel_layer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parcel Layer","description":"That layer's REST URL."},"layer_covers":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Layer Covers","description":"`county`, or `statewide` for a layer several counties share."},"tax_roll":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax Roll"},"data_download":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data Download"}},"additionalProperties":true,"type":"object","required":["fips"],"title":"CountyGisLinks","description":"`GET /counties/{fips}/gis-links`: where a person looks the county's parcels up."},"CountyList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/County"},"type":"array","title":"Items"}},"additionalProperties":true,"type":"object","required":["items"],"title":"CountyList"},"CountyRun":{"properties":{"id":{"type":"integer","title":"Id"},"source":{"type":"string","title":"Source"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"},"status":{"type":"string","title":"Status"},"stats":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Stats"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"additionalProperties":true,"type":"object","required":["id","source","status"],"title":"CountyRun"},"CountySourceConfig":{"properties":{"source":{"type":"string","title":"Source"},"config":{"additionalProperties":true,"type":"object","title":"Config","default":{}},"enabled":{"type":"boolean","title":"Enabled"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"additionalProperties":true,"type":"object","required":["source","enabled"],"title":"CountySourceConfig"},"Coverage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CoverageRow"},"type":"array","title":"Items"},"generated_at":{"type":"string","format":"date-time","title":"Generated At","description":"When this answer was assembled."},"counts_age_s":{"type":"integer","title":"Counts Age S","description":"How many seconds old the oldest parcel counts in the answer are. They come from one copy counted in the background, in full on a timer and county by county as runs finish; a county recounted after a run is fresher than this says."}},"additionalProperties":true,"type":"object","required":["items","generated_at","counts_age_s"],"title":"Coverage","description":"The national coverage table: one row per county we have a source for or\nparcels in."},"CoverageRow":{"properties":{"fips":{"type":"string","title":"Fips","examples":["13153"]},"state":{"type":"string","title":"State"},"name":{"type":"string","title":"Name"},"status":{"type":"string","enum":["ok","degraded","none"],"title":"Status"},"parcel_count":{"type":"integer","title":"Parcel Count"},"depth_pct":{"type":"number","title":"Depth Pct","description":"Share of parcels with a full record: opened by a detail collector, or carrying an owner, a value, a sale date and a year built or living area."},"owner_pct":{"type":"number","title":"Owner Pct","description":"Share of parcels with an owner name.","default":0.0},"mailing_pct":{"type":"number","title":"Mailing Pct","description":"Share with the owner's mailing address.","default":0.0},"value_pct":{"type":"number","title":"Value Pct","description":"Share with a total value.","default":0.0},"sale_price_pct":{"type":"number","title":"Sale Price Pct","description":"Share with a last sale price. Never public in a non-disclosure state.","default":0.0},"year_built_pct":{"type":"number","title":"Year Built Pct","description":"Share with a year built.","default":0.0},"sqft_pct":{"type":"number","title":"Sqft Pct","description":"Share with a living area.","default":0.0},"beds_pct":{"type":"number","title":"Beds Pct","description":"Share with a bedroom count.","default":0.0},"photos_pct":{"type":"number","title":"Photos Pct"},"sales_pct":{"type":"number","title":"Sales Pct"},"sale_date_pct":{"type":"number","title":"Sale Date Pct","description":"Share of parcels with a last sale date, from any source. Zero: nothing here can be found by sale date.","default":0.0},"located_pct":{"type":"number","title":"Located Pct"},"detail_status":{"type":"string","enum":["full","partial","none"],"title":"Detail Status","description":"How much detail the records carry, apart from whether they collect: `full` (nothing missing), `partial`, or `none` (every kind of detail the state can publish is under 10% of the parcels - little beyond the map shape).","default":"none"},"missing":{"items":{"type":"string"},"type":"array","title":"Missing","description":"The kinds of detail under 10% of the parcels carry, from `owners`, `sale prices`, `buildings` (a year built or a living area) and `values`, leaving out what is `not_published`. Empty when nothing is missing.","default":[]},"not_published":{"items":{"type":"string"},"type":"array","title":"Not Published","description":"The kinds no free official bulk source publishes for this county, as far as we have looked: sale prices in the twelve non-disclosure states, and the state and county findings in the API's not-published list (California prices, withheld owner names). Never counted as missing; `reason` names them.","default":[]},"last_good_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Good Run At","description":"Null when no run ever finished."},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error","description":"The most recent run that did not finish, in words. Null when the latest run of every source finished."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Why the status is what it is, in words, and after a semicolon what detail is missing. Always present."}},"additionalProperties":true,"type":"object","required":["fips","state","name","status","parcel_count","depth_pct","photos_pct","sales_pct","located_pct"],"title":"CoverageRow","description":"One county's line in the national coverage table - the row that colours a\ncounty map by how good the data is.\n\n`status` separates three things a single \"no data\" would merge: `ok` (records\ncollect cleanly), `degraded` (we get records, but collection has problems -\nblocked, partial, stale, or a source that changed shape) and `none` (no\nrecords, and `last_error` / `reason` says why)."},"Deed":{"properties":{"county_fips":{"type":"string","title":"County Fips"},"deed_book_page":{"type":"string","title":"Deed Book Page","description":"The deed reference as the county writes it.","examples":["12348 1"]},"sale_date":{"type":"string","format":"date","title":"Sale Date"},"price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price","description":"The price when every priced parcel carries the same one (the package price written on each lot); null when they differ or none has one."},"prices_differ":{"type":"boolean","title":"Prices Differ","default":false},"parcel_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parcel Count","description":"Parcels on the deed; null when `truncated`."},"multi_parcel":{"type":"boolean","title":"Multi Parcel","description":"The deed covers two or more parcels.","default":false},"truncated":{"type":"boolean","title":"Truncated","description":"A reference over 200 parcels: a county's placeholder, not a deed; no parcels are listed.","default":false},"parcels":{"items":{"$ref":"#/components/schemas/DeedParcel"},"type":"array","title":"Parcels","default":[]}},"additionalProperties":true,"type":"object","required":["county_fips","deed_book_page","sale_date"],"title":"Deed","description":"One recorded deed: county, reference, date, price and every parcel on it."},"DeedList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Deed"},"type":"array","title":"Items","default":[]},"count":{"type":"integer","title":"Count","default":0}},"additionalProperties":true,"type":"object","title":"DeedList","description":"`GET /counties/{fips}/deeds`: one deed reference, one record per day it was recorded."},"DeedParcel":{"properties":{"property_id":{"type":"string","title":"Property Id"},"situs_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address"},"situs_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs City"},"sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Price","description":"The price the county recorded on this parcel."},"sale_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Id","description":"The sale row; null where the deed is the parcel's own last sale (`source: last_sale`)."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"additionalProperties":true,"type":"object","required":["property_id"],"title":"DeedParcel","description":"One parcel a recorded deed covers."},"DeedSibling":{"properties":{"property_id":{"type":"string","title":"Property Id"},"situs_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address"},"situs_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs City"},"sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Price","description":"The price the county recorded on this parcel - often the whole package's."},"deed_book_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Book Page"},"via":{"items":{"type":"string"},"type":"array","title":"Via","description":"`deed` (same deed reference, same day) and/or the name of the key that flagged the parcels together (`client` for another customer's).","default":[],"examples":[["deed"]]}},"additionalProperties":true,"type":"object","required":["property_id"],"title":"DeedSibling","description":"Another parcel on the same deed (`GET /parcels/{property_id}/sales/siblings`)."},"DeedSiblings":{"properties":{"property_id":{"type":"string","title":"Property Id"},"sale_date":{"type":"string","format":"date","title":"Sale Date"},"deed_book_page":{"items":{"type":"string"},"type":"array","title":"Deed Book Page","description":"The sale's deed references that name a deed.","default":[]},"siblings":{"items":{"$ref":"#/components/schemas/DeedSibling"},"type":"array","title":"Siblings","default":[]},"count":{"type":"integer","title":"Count","default":0},"truncated":{"type":"boolean","title":"Truncated","description":"True when the reference is shared by more parcels than a deed covers - a county's placeholder - and nothing is listed for it.","default":false}},"additionalProperties":true,"type":"object","required":["property_id","sale_date"],"title":"DeedSiblings","description":"`GET /parcels/{property_id}/sales/siblings`: the other parcels of one sale's deed."},"Feature":{"properties":{"type":{"type":"string","const":"Feature","title":"Type","default":"Feature"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"geometry":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Geometry","description":"Null for a parcel we hold no polygon for."},"properties":{"additionalProperties":true,"type":"object","title":"Properties","description":"Every non-geometry column of the row - a `ParcelSummary` narrowed by `fields=`."}},"additionalProperties":true,"type":"object","required":["properties"],"title":"Feature","description":"One parcel as a GeoJSON Feature. `id` is the `property_id`."},"FeatureCollection":{"properties":{"type":{"type":"string","const":"FeatureCollection","title":"Type","default":"FeatureCollection"},"features":{"items":{"$ref":"#/components/schemas/Feature"},"type":"array","title":"Features"},"count":{"type":"integer","title":"Count","description":"Features returned."},"total":{"type":"integer","title":"Total","description":"Parcels matching the filter. `total > count` means the window was capped - zoom in rather than paging."},"truncated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Truncated","description":"True when the `limit` cap cut the answer. Only on the cross-county layer."}},"additionalProperties":true,"type":"object","required":["features","count","total"],"title":"FeatureCollection","description":"The map layer: a GeoJSON FeatureCollection with the counts beside it."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HomeTypeCount":{"properties":{"home_type":{"type":"string","title":"Home Type","examples":["single_family"]},"label":{"type":"string","title":"Label","examples":["Single family"]},"parcels":{"type":"integer","title":"Parcels","description":"Parcels of this type."},"inferred":{"type":"integer","title":"Inferred","description":"Of them, read as this type only because the class says \"residential\" and nothing finer, or from the parcel's linked Zillow home where the class says nothing."}},"additionalProperties":true,"type":"object","required":["home_type","label","parcels","inferred"],"title":"HomeTypeCount","description":"One home type's share of a county."},"HomeTypeCounts":{"properties":{"county_fips":{"type":"string","title":"County Fips","examples":["13153"]},"classified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Classified At","description":"When the county was last classified; null if never."},"parcels":{"type":"integer","title":"Parcels","default":0},"homes":{"type":"integer","title":"Homes","description":"Parcels of the home types (not lots, farms or businesses).","default":0},"items":{"items":{"$ref":"#/components/schemas/HomeTypeCount"},"type":"array","title":"Items","default":[]}},"additionalProperties":true,"type":"object","required":["county_fips"],"title":"HomeTypeCounts","description":"`GET /counties/{fips}/home-types`: the county counted by home type."},"IdentifierGuide":{"properties":{"stable_key":{"type":"string","title":"Stable Key"},"property_id_format":{"type":"string","title":"Property Id Format"},"property_id_example":{"type":"string","title":"Property Id Example"},"fields":{"additionalProperties":true,"type":"object","title":"Fields"},"lookups":{"additionalProperties":true,"type":"object","title":"Lookups"}},"additionalProperties":true,"type":"object","required":["stable_key","property_id_format","property_id_example","fields","lookups"],"title":"IdentifierGuide","description":"What each identifier on a parcel means, and which route resolves it."},"ImageList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ImageRef"},"type":"array","title":"Items"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant","description":"Only on the per-variant listing, echoing the path segment."}},"additionalProperties":true,"type":"object","required":["items"],"title":"ImageList","description":"Image metadata for one parcel. `items` is empty when it has none."},"ImageRef":{"properties":{"id":{"type":"integer","title":"Id"},"source":{"type":"string","title":"Source"},"kind":{"type":"string","title":"Kind","description":"`photo` or `sketch`."},"position":{"type":"integer","title":"Position"},"variant":{"type":"string","title":"Variant","description":"`full` or `thumb`."},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption","description":"The county page's own caption (alt text) for the picture, when it gave one."},"mime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime"},"byte_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Byte Size"},"sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sha256","description":"Only on `/parcels/{property_id}/images/{variant}`; it is the ETag of the bytes route."},"fetched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Fetched At","description":"When the bytes were stored. Null while only the link is held."},"stored":{"type":"boolean","title":"Stored","description":"True when the bytes of THIS row are on this box. False means the first request to `url` fetches them from `source_url`, while that link is alive."},"has_full":{"type":"boolean","title":"Has Full","description":"True when the full-resolution version of this same photo is stored. On a `thumb` row, false means the thumbnail is all there is - unless `full_id` is set, which means the full size is held as a link and is fetched on its first request."},"full_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Full Id","description":"The id of the full-size row of this same picture, stored or not (a full row names itself). `/images/{full_id}/bytes` serves it, fetching it first when only its link is held. Null when the county gave no full size."},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url","description":"The county's own URL the image was captured from. Provenance, not a URL to serve: it expires about 24 hours after the fetch."},"source_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Expires At","description":"When `source_url` stops working (its signed expiry). A `stored: false` row past it answers 404 until the parcel's next scrape. Null when the link carries no expiry."},"url":{"type":"string","title":"Url","description":"Where the bytes are served from.","examples":["/images/77012"]},"bytes_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bytes Url","description":"The ETag-cached fetch route. Only on the per-variant listing."}},"additionalProperties":true,"type":"object","required":["id","source","kind","position","variant","stored","has_full","url"],"title":"ImageRef","description":"One photo or sketch (`raw_images`), metadata only.\n\n`stored` is authoritative for this row: only `stored: true` rows have bytes on\nthis box. `has_full` is about the picture rather than the row - whether the\nfull-resolution version of the same photo is stored - which is what lets a\nscreen showing a thumbnail say \"thumbnail only\" instead of enlarging a blur.\n`source_url` is the county's own link and is provenance, not a URL to serve -\nqPublic signs those and they expire roughly 24 hours after the fetch.\n\nA `stored: false` row whose link has not expired is fetched, stored and served\nby the first request to `url` (`images=urls` records links only)."},"MatchVote":{"properties":{"id":{"type":"integer","title":"Id"},"property_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Id"},"buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Id","examples":["BID-000123"]},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id"},"voter_id":{"type":"string","title":"Voter Id"},"voter_role":{"type":"string","title":"Voter Role","description":"`user` (weight 1) or `admin` (2).","examples":["user"]},"weight":{"type":"integer","title":"Weight"},"key_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Key Id","description":"The API key that sent it; null for the master token."},"vote":{"type":"string","title":"Vote","description":"`up` or `down`.","examples":["up"]},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"voted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Voted At"}},"additionalProperties":true,"type":"object","required":["id","voter_id","voter_role","weight","vote"],"title":"MatchVote","description":"One stored vote."},"MatchVoteList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MatchVote"},"type":"array","title":"Items","default":[]},"by_buyer":{"additionalProperties":true,"type":"object","title":"By Buyer","description":"Keyed by `buyer_id` (`identity:<id>` without one): weighted `up`, `down`, `net` and `status` across every voter.","default":{}},"total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total","description":"Admin keys: the size of the filtered set."},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Limit"},"offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Offset"}},"additionalProperties":true,"type":"object","title":"MatchVoteList","description":"Votes, and the totals per buyer on the property."},"MatchVoteResult":{"properties":{"ok":{"type":"boolean","title":"Ok"},"vote":{"anyOf":[{"$ref":"#/components/schemas/MatchVote"},{"type":"null"}],"description":"Null once the vote was withdrawn."},"totals":{"$ref":"#/components/schemas/VoteTotals"},"status":{"type":"string","title":"Status","description":"`verified`, `rejected` or `auto`.","examples":["verified"]},"crossed":{"type":"boolean","title":"Crossed","description":"True when this vote changed the pair's status."},"rematch":{"anyOf":[{"$ref":"#/components/schemas/Rematch"},{"type":"null"}]}},"additionalProperties":true,"type":"object","required":["ok","totals","status","crossed"],"title":"MatchVoteResult","description":"What `POST /match/votes` answers: the stored vote and what the pair adds up to."},"OwnerDetail":{"properties":{"entry_id":{"type":"string","title":"Entry Id"},"county_fips":{"type":"string","title":"County Fips"},"county_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Name"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"last":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last"},"first":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First"},"middle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Middle"},"suffix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suffix"},"seq_n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seq N"},"mailing_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Address"},"mailing_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing City"},"mailing_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing State"},"mailing_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Zip"},"mailing_addresses":{"items":{"type":"string"},"type":"array","title":"Mailing Addresses","default":[]},"parcel_count":{"type":"integer","title":"Parcel Count","default":0},"buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Id"},"verified":{"type":"boolean","title":"Verified","default":false},"verified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verified By"},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"verified_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verified Note"},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id"},"identity_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity Name"},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key"},"first_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"parcels":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Parcels","default":[]},"same_owner_elsewhere":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Same Owner Elsewhere","default":[]},"keys":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Keys","default":[]}},"additionalProperties":true,"type":"object","required":["entry_id","county_fips"],"title":"OwnerDetail","description":"One owner: what they hold, the same owner elsewhere, and the evidence."},"OwnerList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/OwnerSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"additionalProperties":true,"type":"object","required":["items","total"],"title":"OwnerList"},"OwnerPortfolio":{"properties":{"owner":{"$ref":"#/components/schemas/PortfolioOwner"},"items":{"items":{"$ref":"#/components/schemas/ParcelSummary"},"type":"array","title":"Items"},"count":{"type":"integer","title":"Count","description":"Rows on this page."},"total":{"type":"integer","title":"Total","description":"Distinct parcels on the whole list."},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor","description":"`order=id` only. Feed back as `cursor=`. Null on the last page."},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset","description":"Every other order. Feed back as `offset=`. Null on the last page."}},"additionalProperties":true,"type":"object","required":["owner","items","count","total"],"title":"OwnerPortfolio","description":"One owner and one page of the parcels they hold, every county."},"OwnerRef":{"properties":{"entry_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entry Id"},"entry_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entry Name"},"verified":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Verified"},"buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Id"},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id"},"canonical_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Canonical Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"}},"additionalProperties":true,"type":"object","title":"OwnerRef","description":"One owner line of a parcel, resolved to its entry and its identity."},"OwnerSummary":{"properties":{"entry_id":{"type":"string","title":"Entry Id","examples":["13153_SMITH_JOHN_A"]},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind","description":"`person`, `org`, `trust`, `gov` or `unknown`."},"county_fips":{"type":"string","title":"County Fips"},"county_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Name"},"parcel_count":{"type":"integer","title":"Parcel Count","default":0},"total_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Value","description":"The parcels `parcel_count` counts, their total value added up; null until filled."},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id","description":"The same owner across counties."},"buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buyer Id","description":"Set once that owner has bought something."},"verified":{"type":"boolean","title":"Verified","default":false},"mailing_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Address"},"mailing_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing City"},"mailing_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing State"},"mailing_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Zip"}},"additionalProperties":true,"type":"object","required":["entry_id","county_fips"],"title":"OwnerSummary","description":"One owner entry: one county, one mailing-address-qualified name."},"PageSection":{"properties":{"name":{"type":"string","title":"Name"},"fields":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Fields","default":[]},"grids":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Grids","default":[]},"images":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Images","default":[]}},"additionalProperties":true,"type":"object","required":["name"],"title":"PageSection","description":"One module of the source page, verbatim - the 'nothing is dropped' guarantee."},"ParcelBuilding":{"properties":{"id":{"type":"integer","title":"Id"},"source":{"type":"string","title":"Source"},"kind":{"type":"string","title":"Kind","description":"`residential`, `commercial` or `accessory`."},"position":{"type":"integer","title":"Position"},"year_built":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year Built"},"sqft":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sqft"},"value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Value"},"attributes":{"additionalProperties":true,"type":"object","title":"Attributes","description":"The county's own attribute list, verbatim."}},"additionalProperties":true,"type":"object","required":["id","source","kind","position","attributes"],"title":"ParcelBuilding","description":"One structure (`parcel_buildings`)."},"ParcelCount":{"properties":{"total":{"type":"integer","title":"Total"}},"additionalProperties":true,"type":"object","required":["total"],"title":"ParcelCount","description":"`{total}` for a filter, without fetching rows."},"ParcelDeeds":{"properties":{"property_id":{"type":"string","title":"Property Id"},"deeds":{"items":{"$ref":"#/components/schemas/Deed"},"type":"array","title":"Deeds","default":[]},"count":{"type":"integer","title":"Count","default":0}},"additionalProperties":true,"type":"object","required":["property_id"],"title":"ParcelDeeds","description":"`GET /parcels/{property_id}/deeds`: every deed one parcel is on, newest first."},"ParcelDetail":{"properties":{"property_id":{"type":"string","title":"Property Id","description":"`{county_fips}-{parcel_id_norm}`. The id to store.","examples":["13153-0W050J08B000"]},"county_fips":{"type":"string","title":"County Fips","description":"Five-digit county FIPS code.","examples":["13153"]},"state":{"type":"string","title":"State","description":"Two-letter state code of the county.","examples":["GA"]},"parcel_id_norm":{"type":"string","title":"Parcel Id Norm","description":"The county parcel number, normalized."},"parcel_id_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parcel Id Raw","description":"The parcel number as the source prints it, padding included. Display only."},"account_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Number","description":"The county's alternate id. A label, not a key: its meaning varies."},"situs_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address","description":"The street line as the county writes it, unit included."},"situs_address_line1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address Line1","description":"Address line 1: `situs_address` without its unit.","examples":["5560 CONSTITUTION AVE"]},"situs_address_line2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address Line2","description":"Address line 2: the unit the street line names - `STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`, `UNIT 342 BLDG 3` - as written; null when it names none.","examples":["STE 5552"]},"situs_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs City"},"situs_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs State"},"situs_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Zip"},"owner_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Name","description":"The first owner line, exactly as the county prints it."},"owner_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Owner Names","description":"Every owner line the page listed."},"owner_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Address"},"owner_address_line1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Address Line1","description":"The mailing address's line 1: `owner_address` without its unit."},"owner_address_line2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Address Line2","description":"The mailing address's line 2: its unit (`STE 255`, `APT 601W`, `PMB 12`), or null."},"owner_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner City"},"owner_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner State"},"owner_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Zip"},"owner_occupied":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Owner Occupied","description":"The county's own owner-occupancy flag."},"owner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Id","description":"The owner **entry** id this parcel resolved to, or null when it has not been resolved.","examples":["13153_SMITH_JOHN_A"]},"owner_verified":{"type":"boolean","title":"Owner Verified","description":"Whether a person has confirmed that owner. Never null: it defaults to false."},"owner_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Display","description":"The display name of the entry on `owner_id`."},"use_restriction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use Restriction","description":"The county's use restriction (`ks-45-230` for Kansas), or null. When set, the owner fields above are null on the customer surface; see \"Use restrictions\" in the API guide.","examples":[null]},"home_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Type","description":"What kind of home it is: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other` or `unknown`. Null until the county has been classified.","examples":["single_family"]},"home_type_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Type Basis","description":"What `home_type` was read from: `text` (the county's words), `code` (its use code), `use`, `inferred` (\"residential\" and nothing finer), or `zillow` (before 0.52.0: the county said nothing finer and a Zillow home decided).","examples":["code"]},"zillow":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Zillow","description":"Admin keys only (null on customer keys). The Zillow home page that names this parcel (its county and parcel number): `zpid`, `status` (`for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`), `status_at` (its newest price-history event), `sold_seen` (its newest sale), `price` and `url`. Null when no page read names the parcel."},"messy_title_likely":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Messy Title Likely","description":"Whether the title is likely messy, read from the deeds on file: an estate or probate deed, a foreclosure, sheriff's, trustee's or tax deed, quit-claims, or an owner line that says \"estate of\", \"heirs\" or \"deceased\" - recorded in the last ten years with no purchase since. A lone quit-claim is listed in `messy_title_reasons` but is not enough on its own. `false` = nothing on file says so (most rolls record no deed type); null until the county has been checked, and on the customer surface for a use-restricted county.","examples":[true]},"messy_title_reasons":{"items":{"type":"string"},"type":"array","title":"Messy Title Reasons","description":"Why, in this order: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims` (two or more within three years), `owner_estate`. Empty when not flagged.","default":[],"examples":[["estate_deed","quit_claim"]]},"property_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Class"},"property_use":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Use"},"zoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zoning"},"tax_district":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax District"},"homestead":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Homestead"},"land_acres":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Land Acres"},"building_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Building Count"},"building_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Building Style"},"year_built":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year Built"},"heated_sqft":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heated Sqft"},"bedrooms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bedrooms"},"full_baths":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Full Baths"},"half_baths":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Half Baths"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"last_sale_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Last Sale Date"},"last_sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Sale Price"},"assessed_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Assessed Year"},"land_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Land Value"},"improvement_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Improvement Value"},"total_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Value"},"est_annual_tax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Annual Tax"},"price_per_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Sqft","description":"`last_sale_price` / `heated_sqft`, to the cent. Null when the price is at or under 1,000 (a transfer) or the size is not recorded."},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude","description":"Null until the parcel is located."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"geocode_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocode Source","description":"Where the coordinate came from: `gis` (the county parcel layer's centroid), `census` (the US Census geocoder from the situs address), or null - no coordinate, or one located before we recorded its origin."},"geocode_match":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocode Match","description":"The Census geocoder's own word for the match (`Exact`, `Non_Exact`). Null unless `geocode_source` is `census`."},"geocode_precision":{"anyOf":[{"type":"string","enum":["parcel","rooftop","street","centroid"]},{"type":"null"}],"title":"Geocode Precision","description":"How close the coordinate is to the property. `parcel` is a GIS parcel centroid; `street` is a Census match interpolated along the street segment; `centroid` is a Census match to something near the address rather than it. Null whenever `latitude` is, and for a coordinate whose origin was never recorded. `rooftop` is reserved: no source we read returns one today."},"geometry":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Geometry","description":"GeoJSON geometry. Only present with `geometry=1` or `fields=...,geometry`."},"distance_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance M","description":"Great-circle metres from `near=`. Only present when `near=` was given."},"photo_count":{"type":"integer","title":"Photo Count","description":"Images of kind `photo` captured for this parcel."},"sketch_count":{"type":"integer","title":"Sketch Count"},"sources":{"items":{"type":"string"},"type":"array","title":"Sources","description":"Which collectors have written this row.","examples":[["arcgis","qpublic"]]},"source_urls":{"additionalProperties":true,"type":"object","title":"Source Urls","description":"`{source: url}` the row was built from."},"record_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Url","description":"The county's own property-record page, derived from `source_urls`. Null for counties that expose none."},"attribution":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Attribution","description":"The credit a source's licence asks for, on every parcel of a county whose data carries one (Pitt County NC: CC BY-SA 4.0) and absent elsewhere: `text`, `source`, `source_url`, `license`, `license_url`, `fields`. Show `text`, linked to `source_url` and `license_url`, wherever those fields are shown."},"last_seen_at":{"type":"string","format":"date-time","title":"Last Seen At","description":"When a source last confirmed this parcel exists."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"When we last wrote this row. The honest answer to 'how old is this?', and what the change feed orders by."},"legal_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Description"},"neighborhood":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Neighborhood"},"millage_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Millage Rate"},"land_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Land Sqft"},"accessory_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Accessory Value"},"previous_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Previous Value"},"last_sale_grantor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sale Grantor"},"last_sale_grantee":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sale Grantee"},"last_sale_deed":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sale Deed"},"last_sale_deed_parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Sale Deed Parcels","description":"`deed_parcels` for the parcel row's own last sale (`last_sale_deed`)."},"last_sale_flags":{"items":{"type":"string"},"type":"array","title":"Last Sale Flags","description":"`sale_flags` for the parcel row's own last sale: `multi_parcel` from a shared deed or a client's flag.","default":[]},"last_sale_flag_sources":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Last Sale Flag Sources","default":{}},"messy_title":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Messy Title","description":"`messy_title_likely` with its evidence: `{likely, reasons, since, evidence, checked_at}`. `since` is the newest flagged deed's date; each `evidence` entry is `{reason, date, read_from, text}`, `read_from` one of `deed` (its type or reason), `grantor`, `grantee`, `owner`. Null until the county has been checked."},"source_keys":{"additionalProperties":true,"type":"object","title":"Source Keys","description":"`{source: key}` - the spelling each source uses for this parcel."},"source_record_ids":{"additionalProperties":true,"type":"object","title":"Source Record Ids","default":{}},"first_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen At"},"sales":{"items":{"$ref":"#/components/schemas/ParcelSale"},"type":"array","title":"Sales","default":[]},"buildings":{"items":{"$ref":"#/components/schemas/ParcelBuilding"},"type":"array","title":"Buildings","default":[]},"values":{"items":{"$ref":"#/components/schemas/ParcelValue"},"type":"array","title":"Values","default":[]},"images":{"items":{"$ref":"#/components/schemas/ImageRef"},"type":"array","title":"Images","default":[]},"owners":{"items":{"$ref":"#/components/schemas/OwnerRef"},"type":"array","title":"Owners","description":"Empty on a database that predates the owner tables rather than failing the record.","default":[]},"permits":{"items":{"$ref":"#/components/schemas/Permit"},"type":"array","title":"Permits","default":[]},"sections":{"items":{"$ref":"#/components/schemas/PageSection"},"type":"array","title":"Sections","default":[]},"county_gis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"County Gis","description":"The county's GIS links (`GET /counties/{fips}/gis-links`) and `parcel_map_here`: the county's ArcGIS parcel layer opened on this parcel, when it has a layer and a point. Null for a county not on file."},"no_data_modules":{"items":{"type":"string"},"type":"array","title":"No Data Modules","description":"Modules the page listed but left empty.","default":[]}},"additionalProperties":true,"type":"object","required":["property_id","county_fips","state","parcel_id_norm","owner_verified","photo_count","sketch_count","sources","source_urls","last_seen_at","updated_at","source_keys"],"title":"ParcelDetail","description":"The full record the three detail routes return: every column of the parcel\nrow, then its sales, buildings, assessments, images, resolved owners, permits\nand every module of the source page.\n\n`sections` and `permits` come from the most recent parsed qPublic capture, so\nthey are empty for a parcel only ArcGIS has reached."},"ParcelList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ParcelSummary"},"type":"array","title":"Items"},"count":{"type":"integer","title":"Count","description":"Rows on this page."},"total":{"type":"integer","title":"Total","description":"Rows matching the filter, ignoring paging."},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor","description":"`order=id` only. Feed back as `cursor=`. Null on the last page."},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset","description":"Every other order. Feed back as `offset=`. Null on the last page."}},"additionalProperties":true,"type":"object","required":["items","count","total"],"title":"ParcelList","description":"One page of parcels, plus the size of the whole filtered set."},"ParcelSale":{"properties":{"id":{"type":"integer","title":"Id"},"source":{"type":"string","title":"Source"},"sale_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Sale Date"},"sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Price"},"grantor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantor"},"grantee":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee"},"deed_book_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Book Page"},"plat_book_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plat Book Page"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"The county's own qualification text. What `reason=` filters on."},"deed_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Type","description":"The county's deed or instrument type where it names one (`WD`, `QC`...); null for most."},"arms_length":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Arms Length","description":"False for a price of $1,000 or less or a reason a transfer rule excludes; true for a reason none excludes; null with no reason."},"sale_flags":{"items":{"type":"string"},"type":"array","title":"Sale Flags","description":"`distressed`, `multi_parcel`, `unvalidated`.","default":[]},"flag_sources":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Flag Sources","description":"Who set each flag: `county` (its sale reason), `deed` (a deed shared with other parcels), or the name of the key that sent it with `POST /sales/flags` (`client` for another customer's).","default":{},"examples":[{"multi_parcel":["county","deed"]}]},"deed_parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Deed Parcels","description":"How many parcels of the county carry a sale that day under this deed reference; 2+ is a package sale. Null when the reference names no deed.","examples":[4]},"qualified":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Qualified","description":"The buyer matcher's verdict on the deed; null until the nightly match build has seen it."},"disqualified_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disqualified Reason","examples":["unpriced"]},"grantee_owner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee Owner Id","description":"The buyer as an owner entry, for `GET /owners/{entry_id}`."},"grantee_buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee Buyer Id","description":"The buyer's investor number, for `GET /buyers/{buyer_id}`."},"grantee_mailing_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee Mailing State","description":"The buyer's mailing state, from their owner entry.","examples":["GA"]}},"additionalProperties":true,"type":"object","required":["id","source"],"title":"ParcelSale","description":"One recorded sale (`parcel_sales`), newest first on a parcel record."},"ParcelSalesBatch":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ParcelSalesEntry"},"type":"array","title":"Items","description":"One per parcel on file, in the order asked."},"count":{"type":"integer","title":"Count","description":"Entries in `items`."},"missing":{"items":{"type":"string"},"type":"array","title":"Missing","description":"Ids that are malformed or not on file."}},"additionalProperties":true,"type":"object","required":["items","count","missing"],"title":"ParcelSalesBatch","description":"`POST /parcels/sales`: the sales of many parcels in one call."},"ParcelSalesEntry":{"properties":{"property_id":{"type":"string","title":"Property Id"},"last_sale_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Last Sale Date","description":"The parcel row's own newest sale date; set by bulk rolls that write no sale row."},"last_sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Sale Price"},"last_sale_deed":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sale Deed"},"last_sale_deed_parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Sale Deed Parcels","description":"`deed_parcels` for the parcel row's own last sale (`last_sale_deed`)."},"last_sale_flags":{"items":{"type":"string"},"type":"array","title":"Last Sale Flags","description":"`sale_flags` for the parcel row's own last sale: `multi_parcel` from a shared deed or a client's flag.","default":[]},"last_sale_flag_sources":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Last Sale Flag Sources","default":{}},"sales":{"items":{"$ref":"#/components/schemas/ParcelSale"},"type":"array","title":"Sales","description":"Newest first. Empty when none is recorded."}},"additionalProperties":true,"type":"object","required":["property_id","sales"],"title":"ParcelSalesEntry","description":"One parcel's sale history inside a `POST /parcels/sales` answer."},"ParcelSummary":{"properties":{"property_id":{"type":"string","title":"Property Id","description":"`{county_fips}-{parcel_id_norm}`. The id to store.","examples":["13153-0W050J08B000"]},"county_fips":{"type":"string","title":"County Fips","description":"Five-digit county FIPS code.","examples":["13153"]},"state":{"type":"string","title":"State","description":"Two-letter state code of the county.","examples":["GA"]},"parcel_id_norm":{"type":"string","title":"Parcel Id Norm","description":"The county parcel number, normalized."},"parcel_id_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parcel Id Raw","description":"The parcel number as the source prints it, padding included. Display only."},"account_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Number","description":"The county's alternate id. A label, not a key: its meaning varies."},"situs_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address","description":"The street line as the county writes it, unit included."},"situs_address_line1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address Line1","description":"Address line 1: `situs_address` without its unit.","examples":["5560 CONSTITUTION AVE"]},"situs_address_line2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address Line2","description":"Address line 2: the unit the street line names - `STE 5552`, `CONDO 242`, `APT 4B`, `# 102-B`, `UNIT 342 BLDG 3` - as written; null when it names none.","examples":["STE 5552"]},"situs_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs City"},"situs_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs State"},"situs_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Zip"},"owner_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Name","description":"The first owner line, exactly as the county prints it."},"owner_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Owner Names","description":"Every owner line the page listed."},"owner_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Address"},"owner_address_line1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Address Line1","description":"The mailing address's line 1: `owner_address` without its unit."},"owner_address_line2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Address Line2","description":"The mailing address's line 2: its unit (`STE 255`, `APT 601W`, `PMB 12`), or null."},"owner_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner City"},"owner_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner State"},"owner_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Zip"},"owner_occupied":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Owner Occupied","description":"The county's own owner-occupancy flag."},"owner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Id","description":"The owner **entry** id this parcel resolved to, or null when it has not been resolved.","examples":["13153_SMITH_JOHN_A"]},"owner_verified":{"type":"boolean","title":"Owner Verified","description":"Whether a person has confirmed that owner. Never null: it defaults to false."},"owner_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Display","description":"The display name of the entry on `owner_id`."},"use_restriction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Use Restriction","description":"The county's use restriction (`ks-45-230` for Kansas), or null. When set, the owner fields above are null on the customer surface; see \"Use restrictions\" in the API guide.","examples":[null]},"home_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Type","description":"What kind of home it is: `single_family`, `multi_family` (2-4 units), `apartments` (5+), `condo`, `townhouse`, `manufactured`, `land`, `farm`, `commercial`, `industrial`, `exempt`, `other` or `unknown`. Null until the county has been classified.","examples":["single_family"]},"home_type_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Home Type Basis","description":"What `home_type` was read from: `text` (the county's words), `code` (its use code), `use`, `inferred` (\"residential\" and nothing finer), or `zillow` (before 0.52.0: the county said nothing finer and a Zillow home decided).","examples":["code"]},"zillow":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Zillow","description":"Admin keys only (null on customer keys). The Zillow home page that names this parcel (its county and parcel number): `zpid`, `status` (`for_sale`, `pending`, `recently_sold`, `for_rent`, `off_market`, `other`), `status_at` (its newest price-history event), `sold_seen` (its newest sale), `price` and `url`. Null when no page read names the parcel."},"messy_title_likely":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Messy Title Likely","description":"Whether the title is likely messy, read from the deeds on file: an estate or probate deed, a foreclosure, sheriff's, trustee's or tax deed, quit-claims, or an owner line that says \"estate of\", \"heirs\" or \"deceased\" - recorded in the last ten years with no purchase since. A lone quit-claim is listed in `messy_title_reasons` but is not enough on its own. `false` = nothing on file says so (most rolls record no deed type); null until the county has been checked, and on the customer surface for a use-restricted county.","examples":[true]},"messy_title_reasons":{"items":{"type":"string"},"type":"array","title":"Messy Title Reasons","description":"Why, in this order: `estate_deed`, `foreclosure`, `tax_deed`, `quit_claim`, `quit_claims` (two or more within three years), `owner_estate`. Empty when not flagged.","default":[],"examples":[["estate_deed","quit_claim"]]},"property_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Class"},"property_use":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Use"},"zoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zoning"},"tax_district":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax District"},"homestead":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Homestead"},"land_acres":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Land Acres"},"building_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Building Count"},"building_style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Building Style"},"year_built":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year Built"},"heated_sqft":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heated Sqft"},"bedrooms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bedrooms"},"full_baths":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Full Baths"},"half_baths":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Half Baths"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"last_sale_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Last Sale Date"},"last_sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Sale Price"},"assessed_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Assessed Year"},"land_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Land Value"},"improvement_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Improvement Value"},"total_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Value"},"est_annual_tax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Est Annual Tax"},"price_per_sqft":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Sqft","description":"`last_sale_price` / `heated_sqft`, to the cent. Null when the price is at or under 1,000 (a transfer) or the size is not recorded."},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude","description":"Null until the parcel is located."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"geocode_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocode Source","description":"Where the coordinate came from: `gis` (the county parcel layer's centroid), `census` (the US Census geocoder from the situs address), or null - no coordinate, or one located before we recorded its origin."},"geocode_match":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Geocode Match","description":"The Census geocoder's own word for the match (`Exact`, `Non_Exact`). Null unless `geocode_source` is `census`."},"geocode_precision":{"anyOf":[{"type":"string","enum":["parcel","rooftop","street","centroid"]},{"type":"null"}],"title":"Geocode Precision","description":"How close the coordinate is to the property. `parcel` is a GIS parcel centroid; `street` is a Census match interpolated along the street segment; `centroid` is a Census match to something near the address rather than it. Null whenever `latitude` is, and for a coordinate whose origin was never recorded. `rooftop` is reserved: no source we read returns one today."},"geometry":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Geometry","description":"GeoJSON geometry. Only present with `geometry=1` or `fields=...,geometry`."},"distance_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance M","description":"Great-circle metres from `near=`. Only present when `near=` was given."},"photo_count":{"type":"integer","title":"Photo Count","description":"Images of kind `photo` captured for this parcel."},"sketch_count":{"type":"integer","title":"Sketch Count"},"sources":{"items":{"type":"string"},"type":"array","title":"Sources","description":"Which collectors have written this row.","examples":[["arcgis","qpublic"]]},"source_urls":{"additionalProperties":true,"type":"object","title":"Source Urls","description":"`{source: url}` the row was built from."},"record_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Url","description":"The county's own property-record page, derived from `source_urls`. Null for counties that expose none."},"attribution":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Attribution","description":"The credit a source's licence asks for, on every parcel of a county whose data carries one (Pitt County NC: CC BY-SA 4.0) and absent elsewhere: `text`, `source`, `source_url`, `license`, `license_url`, `fields`. Show `text`, linked to `source_url` and `license_url`, wherever those fields are shown."},"last_seen_at":{"type":"string","format":"date-time","title":"Last Seen At","description":"When a source last confirmed this parcel exists."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"When we last wrote this row. The honest answer to 'how old is this?', and what the change feed orders by."}},"additionalProperties":true,"type":"object","required":["property_id","county_fips","state","parcel_id_norm","owner_verified","photo_count","sketch_count","sources","source_urls","last_seen_at","updated_at"],"title":"ParcelSummary","description":"One parcel as the list routes, the GeoJSON layer and the NDJSON export\nreturn it: the typed columns of `parcels`, minus the internal row number.\n\n`fields=` narrows this to the columns you name (plus `property_id`), so a\nresponse may hold a subset of what is written here. Nothing is ever renamed."},"ParcelValue":{"properties":{"source":{"type":"string","title":"Source"},"year":{"type":"integer","title":"Year"},"land_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Land Value"},"improvement_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Improvement Value"},"accessory_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Accessory Value"},"total_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Value"},"previous_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Previous Value"}},"additionalProperties":true,"type":"object","required":["source","year"],"title":"ParcelValue","description":"One assessment year (`parcel_values`), newest year first."},"Permit":{"properties":{"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"},"number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Number"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"raw":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Raw"}},"additionalProperties":true,"type":"object","title":"Permit","description":"One row of the source page's Permits module, typed."},"PortfolioEntry":{"properties":{"entry_id":{"type":"string","title":"Entry Id"},"county_fips":{"type":"string","title":"County Fips"},"county_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Name"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"parcel_count":{"type":"integer","title":"Parcel Count","default":0},"total_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Value"},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id"},"mailing_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Address"},"mailing_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing City"},"mailing_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing State"},"mailing_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Zip"}},"additionalProperties":true,"type":"object","required":["entry_id","county_fips"],"title":"PortfolioEntry","description":"One owner entry of a portfolio: the owner in one county."},"PortfolioOwner":{"properties":{"entry_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entry Id","description":"Null when the path was an identity id."},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"county_fips":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Fips"},"identity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Identity Id"},"identity_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity Name"},"scope":{"type":"string","title":"Scope","description":"`identity`, `entry` or `mailing`: the scope used."},"mailing_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Address"},"mailing_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing City"},"mailing_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing State"},"mailing_zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailing Zip"},"parcel_count":{"type":"integer","title":"Parcel Count","description":"The entries' parcel counts added up.","default":0},"total_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Value","description":"The entries' total values added up."},"entries_total":{"type":"integer","title":"Entries Total","default":0},"entries":{"items":{"$ref":"#/components/schemas/PortfolioEntry"},"type":"array","title":"Entries","default":[]}},"additionalProperties":true,"type":"object","required":["scope"],"title":"PortfolioOwner","description":"Who a portfolio is, and what each county of it holds."},"Rematch":{"properties":{"at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"At"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind","examples":["verified"]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":true,"type":"object","title":"Rematch","description":"The newest vote event on a property: when, and why the ranking changed."},"SaleFlagResult":{"properties":{"group_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Group Id"},"flag":{"type":"string","title":"Flag","examples":["multi_parcel"]},"flagged_by":{"type":"string","title":"Flagged By","description":"The name of the key that sent the flag."},"sale_date":{"type":"string","format":"date","title":"Sale Date"},"deed_book_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Book Page"},"marked":{"items":{"type":"string"},"type":"array","title":"Marked","description":"Parcels flagged by this call.","default":[]},"already":{"items":{"type":"string"},"type":"array","title":"Already","description":"Parcels this key had already flagged for that sale.","default":[]},"missing":{"items":{"type":"string"},"type":"array","title":"Missing","description":"Ids that are malformed or not on file.","default":[]},"removed":{"type":"integer","title":"Removed","description":"With `remove: true`: how many flags were taken back.","default":0}},"additionalProperties":true,"type":"object","required":["flag","flagged_by","sale_date"],"title":"SaleFlagResult","description":"`POST /sales/flags`: what was flagged."},"SaleRow":{"properties":{"property_id":{"type":"string","title":"Property Id"},"county_fips":{"type":"string","title":"County Fips"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"situs_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs Address"},"situs_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Situs City"},"property_use":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Property Use","examples":["residential"]},"sale_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Id","description":"Null for a parcel's own last sale where its county records nothing more (`source: last_sale`)."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"sale_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Sale Date"},"sale_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sale Price"},"grantor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantor"},"grantee":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee"},"deed_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Type"},"deed_book_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deed Book Page"},"plat_book_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plat Book Page"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"arms_length":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Arms Length"},"sale_flags":{"items":{"type":"string"},"type":"array","title":"Sale Flags","default":[]},"flag_sources":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Flag Sources","default":{}},"deed_parcels":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Deed Parcels"},"qualified":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Qualified"},"disqualified_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disqualified Reason"},"grantee_owner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee Owner Id"},"grantee_buyer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee Buyer Id"},"grantee_mailing_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grantee Mailing State","examples":["GA"]}},"additionalProperties":true,"type":"object","required":["property_id","county_fips"],"title":"SaleRow","description":"One sale in an area (`GET /sales`): the deed and its parcel."},"SalesBucket":{"properties":{"start":{"type":"string","format":"date","title":"Start"},"end":{"type":"string","format":"date","title":"End"},"sales":{"type":"integer","title":"Sales","default":0},"priced":{"type":"integer","title":"Priced","default":0},"median_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Price"},"total_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Price"}},"additionalProperties":true,"type":"object","required":["start","end"],"title":"SalesBucket","description":"One period of `GET /sales/histogram`."},"SalesHistogram":{"properties":{"bucket":{"type":"string","title":"Bucket","examples":["week"]},"buckets":{"items":{"$ref":"#/components/schemas/SalesBucket"},"type":"array","title":"Buckets","default":[]},"sales":{"type":"integer","title":"Sales","default":0},"priced":{"type":"integer","title":"Priced","default":0},"median_price":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Price"},"filters":{"additionalProperties":true,"type":"object","title":"Filters","default":{}}},"additionalProperties":true,"type":"object","required":["bucket"],"title":"SalesHistogram","description":"`GET /sales/histogram`: the sales in an area counted per period."},"SalesPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SaleRow"},"type":"array","title":"Items","default":[]},"count":{"type":"integer","title":"Count","default":0},"truncated":{"type":"boolean","title":"Truncated","default":false},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset"},"filters":{"additionalProperties":true,"type":"object","title":"Filters","default":{}}},"additionalProperties":true,"type":"object","title":"SalesPage","description":"`GET /sales`: the sales in an area and window, newest first."},"Usage":{"properties":{"key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key"},"key_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Key Id"},"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"},"month":{"type":"string","title":"Month","examples":["2026-09"]},"quota":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Quota","description":"Null when the key has no monthly ceiling."},"used":{"type":"integer","title":"Used"},"remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining"},"resets_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resets At"},"rate_limit_per_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Limit Per Min"},"by_day":{"items":{"$ref":"#/components/schemas/UsageDay"},"type":"array","title":"By Day","default":[]},"by_family":{"items":{"$ref":"#/components/schemas/UsageFamily"},"type":"array","title":"By Family","default":[]},"totals":{"additionalProperties":true,"type":"object","title":"Totals","default":{}}},"additionalProperties":true,"type":"object","required":["month","used"],"title":"Usage","description":"This key's own meter for the calendar month."},"UsageDay":{"properties":{"day":{"type":"string","format":"date","title":"Day"},"requests":{"type":"integer","title":"Requests"},"errors":{"type":"integer","title":"Errors"}},"additionalProperties":true,"type":"object","required":["day","requests","errors"],"title":"UsageDay"},"UsageFamily":{"properties":{"family":{"type":"string","title":"Family"},"requests":{"type":"integer","title":"Requests"},"errors":{"type":"integer","title":"Errors"}},"additionalProperties":true,"type":"object","required":["family","requests","errors"],"title":"UsageFamily"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VoteTotals":{"properties":{"up":{"type":"integer","title":"Up","default":0},"down":{"type":"integer","title":"Down","default":0},"net":{"type":"integer","title":"Net","default":0}},"additionalProperties":true,"type":"object","title":"VoteTotals","description":"What the votes on one buyer for one property add up to, weighted."},"Tombstone":{"additionalProperties":true,"description":"A `parcel_tombstones` row: a parcel that vanished from every source.\n\nThe change feed reports these as `{property_id, op: \"delete\", at}`. This is the\nfull row, published for a downstream copy that mirrors the table itself. Rows\nare kept `TOMBSTONE_RETENTION_DAYS` (90) days; see the change feed section of\n`docs/API.md`.","properties":{"property_id":{"title":"Property Id","type":"string"},"county_fips":{"title":"County Fips","type":"string"},"deleted_at":{"format":"date-time","title":"Deleted At","type":"string"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Why the collector tombstoned it, when it said.","title":"Reason"}},"required":["property_id","county_fips","deleted_at"],"title":"Tombstone","type":"object"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your API key, `pk_…`, exactly as it was issued. Swagger adds the `Bearer ` prefix for you."}}},"tags":[{"name":"Counties","description":"The county registry: what exists, what is configured to be collected, and how much of it we hold."},{"name":"Parcels","description":"The properties themselves - search, filter, one full record, and the id you should store (`property_id`)."},{"name":"Images","description":"Photos and sketches captured from the county page: metadata first, then the stored bytes."},{"name":"Owners","description":"Identity resolution - every spelling of a name clustered into one owner, plus the verdict list where the machine's verdict on a pair is confirmed or overridden."},{"name":"Links / buyer matching","description":"Given a property, who is most likely to buy it. Ranked from real nearby purchases, with the arithmetic and the evidence left visible. The UI calls this feature **Links**."},{"name":"AcqTrack","description":"National AcqTrack: what AcqTrack draws for one circle - sales, dollars, unique buyers, acres, flips and $/day - for every county, state and ZIP at once, by month and property use, to rank and map the country."},{"name":"Export & sync","description":"Bulk out: a whole county as CSV or NDJSON, and an incremental feed of upserts and deletes for keeping a downstream copy in step."},{"name":"Keys & usage","description":"Your own meter: what this key has spent this calendar month, broken down by day and by product area, and what it is allowed to spend."}],"security":[{"bearerAuth":[]}]}