Washington Surplus Funds Scraper
Pricing
from $1.00 / 1,000 tenders
Washington Surplus Funds Scraper
Extract washington state surplus funds expenditures records: every column the portal publishes, with server-side keyword, date and amount filters. Export data, run via API, schedule and monitor runs, or integrate with other tools.
Pricing
from $1.00 / 1,000 tenders
Rating
5.0
(1)
Developer
Public Money
Maintained by ApifyActor stats
0
Bookmarked
3
Total users
2
Monthly active users
21 hours ago
Last modified
Categories
Share
This Actor reads Washington State Surplus Funds Expenditures. It returns one record per payment, filtered server-side by keyword, date range and amount so a run returns what you asked for rather than everything. The portal itself is built for someone reading one payment at a time, which is what makes a pipeline over it painful. Every column the portal publishes comes through unchanged, so the field names are the portal's own rather than ours.
What it does
- Returns one record per payment, with
idas the first column. - Filters at the source, not after it. Keyword, date range and amount are passed to the portal, so a narrow query costs less rather than the same.
- Handles the pagination. The portal serves payments a page at a time and the Actor walks them until your Max items cap is reached.
- Passes the portal's columns through unchanged, which means you get everything it publishes and the names match its own documentation.
- Needs no API key. The source is open data and the Actor reads it unauthenticated.
Use cases
| You need to | How this Actor does it |
|---|---|
| See where the money goes | Group by the payee column and total the amounts |
| Find a vendor relationship | Filter on a supplier name across years |
| Audit a department | Filter on the department and sort by amount |
| Spot the outliers | Set a minimum amount and read what comes back |
| Feed a research agent | Call the Actor over MCP and let the model set the filters |
| Build a history | Schedule the run and let the dataset accumulate |
Quick start
- Click Try for free.
- Put a Keyword in, or leave it empty to take everything the filters allow.
- Set the date window. A scheduled run usually wants the rolling window rather than fixed dates, so it picks up only what is new.
- Set a Minimum amount if the small entries are noise for you.
- Set Max items, which is what caps the cost of the run.
- Click Start, then export as JSON, CSV, Excel or XML, or read the dataset over the API.
Input
| Field | Type | Default | What it controls |
|---|---|---|---|
keyword | string | empty | Matched server-side by the portal, so a narrow keyword cuts the run and the bill rather than filtering after the fact |
dateFrom | string | empty | Only records on or after this date, written YYYY-MM-DD |
dateTo | string | empty | Only records on or before this date, written YYYY-MM-DD |
minAmount | integer | empty | Drops records below this value, so a run can ignore the long tail of small entries |
maxItems | integer | 500 | Caps how many records are returned, and therefore what the run costs |
{"keyword": "bridge","dateFrom": "2026-01-01","dateTo": "2026-09-30","minAmount": 50000,"maxItems": 500}
Output
One dataset item per payment. These are the portal's own column names, passed through unchanged, so they match its documentation rather than a vocabulary we invented, and a column the portal adds appears here without an Actor update.
The run returns id, report_number, origin, filer_id, person_id, type, filer_name, election_year.
{"id": "RFP-2026-0184","report_number": "RFP-2026-0184","filer_id": "RFP-2026-0184","person_id": "RFP-2026-0184"}
Integrations
Run it over the API and get the rows back in one call:
curl -X POST "https://api.apify.com/v2/acts/publicmoney~washington-surplus-funds-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"keyword": "bridge", "dateFrom": "2026-01-01", "dateTo": "2026-09-30", "minAmount": 50000, "maxItems": 500}'
From Python:
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("publicmoney/washington-surplus-funds-scraper").call(run_input={"keyword": "bridge", "dateFrom": "2026-01-01", "dateTo": "2026-09-30", "minAmount": 50000, "maxItems": 500})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Give an AI agent the Actor over MCP:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?actors=publicmoney/washington-surplus-funds-scraper"}}}
Schedules run it on any cron, webhooks fire when a run finishes, and platform integrations push the dataset to Google Sheets, Slack, Airtable, Zapier or your own endpoint.
Cost
Pay per event, so you pay for records rather than compute time.
| Event | Free tier | Top volume tier |
|---|---|---|
| Tender | $0.002 | $0.0007 |
| Actor start | $0.00005 per GB | Same |
Six volume tiers apply, so the per-record price falls with monthly volume. The filters are the lever on cost: a keyword and a date range are applied by the portal before anything is returned, so a narrow run is a cheap run. Max items is the hard cap.
Troubleshooting
| Issue | Solution |
|---|---|
| The run returns nothing | The filters excluded everything. Widen the date range or clear the keyword, and remember the keyword is matched by the portal rather than by us, so it matches the portal's way. |
| Fewer records than the portal shows | Max items caps the run. Raise it, and check the date range covers the period you meant. |
| The run is slower than expected | The portal serves payments a page at a time and the Actor walks the pages. A narrower filter is faster as well as cheaper. |
| Records I expected are missing | Check Minimum amount. A record below it is dropped before it reaches the dataset, including records with no amount published. |
| A column I need is not there | The Actor passes through what the portal publishes, so a missing column means the portal does not publish it for that record. Columns also differ between record types on some portals. |
| The column names look inconsistent | They are the portal's own, kept deliberately so they match its documentation. Normalising them would mean guessing, and a guess that drifts is worse than a name that is ugly but exact. |
| The source changed and the run broke | Open an issue on the Issues tab. A daily test runs every Actor in this fleet against its live source, so a break is usually already known. |
FAQ
Does this source have an API?
Some of these portals publish one and some do not, and where one exists it is usually paginated, rate limited and shaped differently from every other portal. This Actor gives you the same input and the same record shape as the rest of the fleet, so a pipeline over many jurisdictions does not need a special case for each.
Do I need an API key?
No. The source is open data and the Actor reads it unauthenticated. You need an Apify token to call the Actor over the API.
How do I keep the cost down?
Filter. The keyword, date range and amount are applied by the portal before any record is returned, so they cut the bill rather than just the output. Max items is the hard cap if you want a guaranteed ceiling, and a payment that returns no data is not charged.
Can I get history, or only what is current?
As far back as the portal publishes, using the date range. Portals differ: some carry years, some only an open window. To build your own history, schedule the Actor and let the dataset accumulate.
Can an AI agent call this Actor?
Yes. Add it to an MCP client with the config above and the model can set the filters itself. Every record is flat JSON, so no post-processing is needed.
Can I get the data into Excel or Google Sheets?
Yes. Export the dataset as XLSX or CSV, or connect the Google Sheets integration so each run appends to a sheet.
Why are the field names the portal's and not normalised?
Because normalising 150 portals into one vocabulary means guessing what each column means, and a guess that drifts is worse than a name that is exact. The names here match the portal's own documentation.
Is it legal to use this data?
This is public procurement and public spending data that governments publish deliberately, and the Actor reads it as published with no login. Named individuals do appear in some sources, such as a contact on a notice, so handle those under your own obligations. Take your own legal advice for your use case.
Changelog
- 0.0.1 First release.
Feedback
Found a column the portal publishes that this Actor misses, or a filter that does not behave the way the portal documents it? Open an issue on the Issues tab with the input you used and what you expected. A daily test runs every Actor in this fleet against its live source, so parser fixes ship fast.