Missouri Public Notices
Missouri newspaper legal notices — trustee's sales, foreclosure and tax sales, probate and hearing notices.
2,745 rows in the dataset
Download the dataset
Get every row this scraper has collected as one CSV or JSONL file. If the data is older than maxAgeHours, the scraper is re-run with its configured settings first. The key needs the datasets:export scope.
DOWNLOAD_ID=$(curl -s -X POST "https://api.pandorlabs.com/v1/datasets/missouri-public-notices/downloads" \ -H "Authorization: Bearer $PANDORLABS_KEY" \ -H "Content-Type: application/json" \ -d '{"maxAgeHours":24,"format":"csv"}' | jq -r '.id')while true; do STATUS=$(curl -s "https://api.pandorlabs.com/v1/downloads/$DOWNLOAD_ID" \ -H "Authorization: Bearer $PANDORLABS_KEY" | jq -r '.status') [ "$STATUS" != "refreshing" ] && break sleep 5donecurl -s "https://api.pandorlabs.com/v1/downloads/$DOWNLOAD_ID/file" \ -H "Authorization: Bearer $PANDORLABS_KEY" \ -o dataset.csvAt its current 2,745 rows, this download costs 28 credits when the data is fresh enough, or 56 credits when it has to be refreshed first.
The rate is 1 credit per 100 rows cached and 2 credits live, charged on the rows in the dataset when the download becomes ready. A failed refresh is not charged. The file stays downloadable for 24 hours. See pricing.
Start a run
To choose the targets yourself, send the parameters below as input. The call returns 202 with the run; the key needs the scrapers:run scope and the account a positive credit balance.
curl -X POST "https://api.pandorlabs.com/v1/scrapers/missouri-public-notices/runs" \ -H "Authorization: Bearer $PANDORLABS_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "keywords": "foreclosure trustee", "keywordMode": "OR", "counties": [ "Buchanan", "Greene", "Jackson" ], "sweepCounties": false } }'A run is billed at the live rate once it finishes: 2 credits per 100 rows it collected. A run that collects nothing costs nothing.
Parameters
Every parameter is optional. Anything you leave out uses the default shown here; an unknown name or an invalid value is rejected with a 400 that lists each problem.
Search
keywordsstring
Keywords
Posted into the portal's own search box — this is the only narrowing the server does. Clear it to sweep every notice type.
- Default
foreclosure trustee- Example
foreclosure trustee
keywordModeenum
Keyword mode
The default list needs "any": a HUD foreclosure notice and a bank trustee sale share no single word.
- Default
OR- Allowed values
ORANDEXACT
excludeKeywordsstring
Exclude keywords
Notices containing these are dropped by the portal before they are counted against the 1,000-result cap.
- Default
- none
countiesstring[]
Counties
Spelled as the site does ("Buchanan", not "Buchanan County"). One search per county, and the only way to get a county onto a row — a statewide search leaves the column blank. Leave empty and set "Sweep every county" to cover all of them.
- Default
- none
- Example
Buchanan, Greene, Jackson
sweepCountiesboolean
Sweep every county
One search per county, over all 116 the form offers. The only way to fill county and city on a statewide sweep, and it costs roughly a hundred extra searches.
- Default
false
fromDatestring
Published from (M/D/YYYY)
Set with a to-date to use the portal's explicit range instead of the lookback.
- Default
- none
- Example
8/1/2026
toDatestring
Published to (M/D/YYYY)
- Default
- none
lookbackDaysnumber
Lookback (days)
Used when no explicit range is set. Papers post late, so a daily run wants overlap.
- Default
30- Range
- 1 to 3650
autoSplitboolean
Split searches past the result cap
The portal never returns more than 1,000 notices for one search. With this on, a search that fills the cap is re-run a day at a time, and a capped single day is re-run county by county, until the window fits.
- Default
true
noticeCategoriesenum[]
Notice categories
Applied after parsing — the portal has no type facet, so it can only discard rows the keyword search already returned, never widen it. Matched against every category a notice fits, not just the first.
- Default
- none
- Allowed values
foreclosuretax-saleprobatehearingbidsordinancename-changestorage-lien
Advanced
maxSearchesnumber
Max searches per run
A ceiling on what auto-splitting may spend. Reaching it raises a warning naming the windows that went unsearched.
- Default
400- Range
- 1 to 5000
resultsPerPagenumber
Results per page
Snapped to one of the grid's own sizes (5, 10, 15, 20, 25, 30, 50). 50 costs one extra postback and saves four in five page fetches.
- Default
50- Range
- 5 to 50
sortOrderenum
Sort order
- Default
DatePublishedDate DESC- Allowed values
DatePublishedDate DESCDatePublishedDate ASCRank DESCPaperName ASCPaperName DESCCityName ASCCityName DESCCountyName ASCCountyName DESC
maxPagesnumber
Max pages per search
The portal caps a result set at 1,000 notices however they are paged, so 20 pages of 50 is the whole of what any one search can yield. Auto-splitting is what gets past that, not this.
- Default
20- Range
- 1 to 100
maxRecordsnumber
Max records per run
- Default
50000- Range
- 1 to 500000
requestDelayMsnumber
Delay between requests (ms)
Every page is a full WebForms postback carrying a ~90 KB viewstate. The default is deliberately unhurried.
- Default
1500- Range
- 0 to 60000
Input as JSON Schema
The same schema the API validates against. Use it as a tool input schema or to generate a typed client.
{ "type": "object", "additionalProperties": false, "properties": { "keywords": { "type": "string", "maxLength": 2000, "title": "Keywords", "description": "Posted into the portal's own search box — this is the only narrowing the server does. Clear it to sweep every notice type.", "default": "foreclosure trustee", "examples": [ "foreclosure trustee" ] }, "keywordMode": { "type": "string", "enum": [ "OR", "AND", "EXACT" ], "title": "Keyword mode", "description": "The default list needs \"any\": a HUD foreclosure notice and a bank trustee sale share no single word.", "default": "OR" }, "excludeKeywords": { "type": "string", "maxLength": 2000, "title": "Exclude keywords", "description": "Notices containing these are dropped by the portal before they are counted against the 1,000-result cap." }, "counties": { "type": "array", "items": { "type": "string" }, "maxItems": 1000, "title": "Counties", "description": "Spelled as the site does (\"Buchanan\", not \"Buchanan County\"). One search per county, and the only way to get a county onto a row — a statewide search leaves the column blank. Leave empty and set \"Sweep every county\" to cover all of them.", "examples": [ "Buchanan, Greene, Jackson" ] }, "sweepCounties": { "type": "boolean", "title": "Sweep every county", "description": "One search per county, over all 116 the form offers. The only way to fill county and city on a statewide sweep, and it costs roughly a hundred extra searches.", "default": false }, "fromDate": { "type": "string", "maxLength": 2000, "title": "Published from (M/D/YYYY)", "description": "Set with a to-date to use the portal's explicit range instead of the lookback.", "examples": [ "8/1/2026" ] }, "toDate": { "type": "string", "maxLength": 2000, "title": "Published to (M/D/YYYY)" }, "lookbackDays": { "type": "number", "minimum": 1, "maximum": 3650, "title": "Lookback (days)", "description": "Used when no explicit range is set. Papers post late, so a daily run wants overlap.", "default": 30 }, "autoSplit": { "type": "boolean", "title": "Split searches past the result cap", "description": "The portal never returns more than 1,000 notices for one search. With this on, a search that fills the cap is re-run a day at a time, and a capped single day is re-run county by county, until the window fits.", "default": true }, "maxSearches": { "type": "number", "minimum": 1, "maximum": 5000, "title": "Max searches per run", "description": "A ceiling on what auto-splitting may spend. Reaching it raises a warning naming the windows that went unsearched.", "default": 400 }, "noticeCategories": { "type": "array", "items": { "type": "string", "enum": [ "foreclosure", "tax-sale", "probate", "hearing", "bids", "ordinance", "name-change", "storage-lien" ] }, "uniqueItems": true, "title": "Notice categories", "description": "Applied after parsing — the portal has no type facet, so it can only discard rows the keyword search already returned, never widen it. Matched against every category a notice fits, not just the first.", "default": [] }, "resultsPerPage": { "type": "number", "minimum": 5, "maximum": 50, "title": "Results per page", "description": "Snapped to one of the grid's own sizes (5, 10, 15, 20, 25, 30, 50). 50 costs one extra postback and saves four in five page fetches.", "default": 50 }, "sortOrder": { "type": "string", "enum": [ "DatePublishedDate DESC", "DatePublishedDate ASC", "Rank DESC", "PaperName ASC", "PaperName DESC", "CityName ASC", "CityName DESC", "CountyName ASC", "CountyName DESC" ], "title": "Sort order", "default": "DatePublishedDate DESC" }, "maxPages": { "type": "number", "minimum": 1, "maximum": 100, "title": "Max pages per search", "description": "The portal caps a result set at 1,000 notices however they are paged, so 20 pages of 50 is the whole of what any one search can yield. Auto-splitting is what gets past that, not this.", "default": 20 }, "maxRecords": { "type": "number", "minimum": 1, "maximum": 500000, "title": "Max records per run", "default": 50000 }, "requestDelayMs": { "type": "number", "minimum": 0, "maximum": 60000, "title": "Delay between requests (ms)", "description": "Every page is a full WebForms postback carrying a ~90 KB viewstate. The default is deliberately unhurried.", "default": 1500 } }}Run, poll, read rows
The run is asynchronous. Poll it until it reaches a terminal status and its billing is paid, then page through its rows. Until then the rows endpoint answers 409 (still queued or running) or 402 (payment required).
RUN_ID=$(curl -s -X POST "https://api.pandorlabs.com/v1/scrapers/missouri-public-notices/runs" \ -H "Authorization: Bearer $PANDORLABS_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "keywords": "foreclosure trustee", "keywordMode": "OR", "counties": [ "Buchanan", "Greene", "Jackson" ], "sweepCounties": false } }' | jq -r '.id')while true; do RUN=$(curl -s "https://api.pandorlabs.com/v1/runs/$RUN_ID" \ -H "Authorization: Bearer $PANDORLABS_KEY") STATUS=$(echo "$RUN" | jq -r '.status') BILLING=$(echo "$RUN" | jq -r '.billing.status') case "$STATUS" in queued|running) ;; *) [ "$BILLING" != "pending" ] && break ;; esac sleep 5doneecho "$RUN" | jq '{status, rowCount, billing}'curl -s "https://api.pandorlabs.com/v1/runs/$RUN_ID/rows?page=1&limit=100" \ -H "Authorization: Bearer $PANDORLABS_KEY"See the API reference for pagination, cancelling and listing runs.
Output fields
Rows have no fixed schema; these are the fields observed in the rows collected so far. Coverage is the share of rows where the field is present.
| Field | Type | Coverage |
|---|---|---|
| body_lines | array | 100% |
| body_text | string | 100% |
| body_truncated | boolean | 100% |
| book_number | string | 24% |
| case_number | string | 6% |
| city | string | 34% |
| county | string | 34% |
| decedent_name | string | 3% |
| deed_of_trust_dated | date | 76% |
| document_number | string | 45% |
| grantor | string | 55% |
| newspaper | string | 100% |
| notice_categories | array | 94% |
| notice_category | string | 94% |
| notice_id | string | 100% |
| notice_type | string | 77% |
| page_number | string | 24% |
| published_date | string | 100% |
| published_on | date | 100% |
| recorded_on | date | 57% |
| search_label | string | 100% |
| state | string | 100% |
| trustee_sale_number | string | 6% |
| created_at | date | 100% |
| first_seen_at | date | 100% |
| last_seen_at | date | 100% |
| updated_at | date | 100% |
| _id | string | 100% |
