PlanetBids Scraper – Government Bids & RFPs
Pricing
from $2.40 / 1,000 bids
PlanetBids Scraper – Government Bids & RFPs
PlanetBids bid tracker: open bids, RFPs and RFQs from 272 city, county, school and water district portals (mostly California). Due dates, categories, estimated value, documents, addenda, awards and bid results. No login.
Pricing
from $2.40 / 1,000 bids
Rating
0.0
(0)
Developer
Alexei Pannicov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
PlanetBids scraper and bid tracker: open government bids, RFPs and RFQs from city, county, school district and water district portals on PlanetBids (mostly California), plus bid results and awarded contracts (who won and for how much). Collect every public bid opportunity (bids, RFPs, RFQs, RFIs, qualifications) with due dates, categories, estimated value, documents and addenda, no login needed. PlanetBids hosts procurement portals for hundreds of US public agencies: cities, counties, school districts, water and transit districts. This Actor reads each portal's own JSON API over plain HTTP (no browser), so runs are fast and cheap, and every field comes typed and normalised.
What you get
- Every bid on a portal, with stage (planning, bidding, closed, award pending, awarded, canceled, rejected), type, invitation number, issue and due dates with the agency's time zone offset, and categories with names.
- Bid details (optional): scope and details HTML, estimated value (text and parsed USD), location, department, license requirement, duration, liquidated damages, pre-bid meeting, Q&A cutoff, award date and notes, special notices.
- Extras (optional, one request each): document metadata, addenda with attachments, line items, pre-bid meeting, awards (winning vendor and amount), bid results (all bidders and amounts), prospective bidders.
- A bundled catalog of 272 PlanetBids portals in 12 states (250 in California), so you can scrape every catalog portal in a state without looking up IDs.
- Run records that tell you whether the data is complete:
RUN_SUMMARY(per-portal counts, failures, WAF challenges) andCONTRACT_DRIFT(any change in the PlanetBids API seen during the run).
Use cases
- Find new bids to win: track open bids and RFPs by keyword, category code or bid type across the agencies you sell to, and run it on a schedule.
- Competitive intelligence: with
awardsandbidResults, see who won each contract, for how much, and what every other bidder offered. - Sales and lead generation: list the public agencies that buy what you sell, with departments, locations and estimated contract values.
How to use it
- Pick agencies by name from the catalog, or pick whole states. For a portal that is not in the catalog, enter its ID such as
14319or a portal URL such ashttps://vendors.planetbids.com/portal/14319/bo/bo-search. - Choose filters: stages, bid types, keyword, category codes, due date range, posted-after date.
- Turn on Include bid details and pick extras if you need more than the list data.
- Set Max items (default 100, 0 = unlimited) and run.
The portal ID is the number after /portal/ in any PlanetBids vendor URL.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
portals | list of IDs or URLs | [] | Portals not in the catalog. Combined with the catalog selections. |
catalogPortals | list of catalog portal IDs | [] | Shown as agency names in the input form. |
catalogStates | list of US states | [] | Adds every catalog portal in these states. |
allCatalogPortals | boolean | false | Adds every catalog portal. |
stages | planning, bidding, closed, awardPending, awarded, canceled, rejected | ["bidding"] | Empty = all. One stage is filtered by the API; several are filtered by the Actor after listing everything (slower). |
bidTypes | bid, rfi, rfp, rfq, rfqual, ipwb | [] | Empty = all. Same one-vs-several rule as stages. |
keyword | text | "" | Full-text search by the API. |
categoryCodes | list | [] | Category (NIGP-like) codes, e.g. 91200. Any match. |
dueDateFrom, dueDateTo | YYYY-MM-DD | none | Sent to the API. |
postedAfter | YYYY-MM-DD | none | Filtered by the Actor; with the default sort (issue date, newest first) paging stops early. |
sortBy | issueDate, title, invitationNumber, dueDate, stage | issueDate | Matters with maxItems. |
sortOrder | desc, asc | desc | |
includeDetails | boolean | false | One extra request per bid. |
include | documents, addenda, lineItems, preBidMeeting, awards, bidResults, prospectiveBidders | [] | Needs includeDetails. One request per extra per bid. |
includeContacts | boolean | false | Personal data, see below. |
maxItems | integer | 100 | Total across portals. 0 = unlimited. |
maxRequestsPerMinute | integer | 50 | Keep at 60 or less without a rotating proxy. |
maxWafChallenges | integer | 5 | Stop after this many WAF challenges in a row. |
wafBackoffSecs | integer | 150 | Pause after a WAF challenge (60-280). |
proxyConfiguration | proxy | no proxy | Not needed at the default rate. |
Example:
{"portals": ["14319", "https://vendors.planetbids.com/portal/17950/bo/bo-search"],"stages": ["awarded"],"bidTypes": ["bid", "rfp"],"includeDetails": true,"include": ["awards"],"maxItems": 50}
Extras are only fetched when the agency publishes them
Each bid tells whether its agency publishes awards, bid results and a pre-bid meeting. The Actor requests an extra only when it is published. Otherwise extras.<name> is notAvailable and the field is null. Award amounts are null when the agency publishes the winner but not the amount. Statuses: ok, notAvailable, failed (the request or parsing failed, the item is still saved), skipped.
Output
One dataset item per bid. List fields are always present. Detail fields appear when includeDetails is on and detailStatus is ok. A real item from Kern High School District (portal 14319), shortened:
{"portalId": 14319,"portalName": "Kern High School District","portalState": "California","portalTimeZone": "America/Los_Angeles","bidId": 146762,"url": "https://vendors.planetbids.com/portal/14319/bo/bo-detail/146762","title": "Vista Continuation High School Modernization: Trash Haul-Off","invitationNumber": "Bid No. 6948","stage": "bidding","stageCode": 3,"bidType": "bid","bidTypeCode": 1,"responseFormat": "paper","responseFormatCode": 2,"issuedAt": "2026-09-30T10:19:57-07:00","dueAt": "2026-10-21T14:00:00-07:00","categories": [{ "code": "11111", "name": "Builder's Exchange & Plan Rooms" },{ "code": "91027", "name": "Garbage/Trash Removal, Disposal And/Or Treatment" }],"detailStatus": "ok","scrapedAt": "2026-10-08T14:15:02.252Z","scope": "<p>Provide dumpsters and dumpster haul-off. Dumpsters provided are for the use of all Prime Contractors on site.</p>","estimatedValueText": "$98,000.00","estimatedValueUsd": 98000,"licenseRequirement": "B or C-21 or C-61 and D-63","address": {"line1": "5801 Sundale Avenue","line2": null,"city": "Bakersfield","county": "Kern","zip": "93309","state": "California"},"department": "Business Services Department","duration": "490 Calendar Days","liquidatedDamages": "$2,000.00 per calendar day","preBidMeetingAt": "2026-10-07T10:00:00-07:00","preBidMeetingMandatory": false,"extras": { "documents": "ok", "awards": "notAvailable" },"documents": [{"documentId": 646708,"title": "Specifications","filename": "Specifications.pdf","sizeBytes": 6589621,"uploadedAt": "2026-09-30T08:06:35-07:00","isRecalled": false,"publiclyVisible": false,"downloadUrl": "https://files-prod01.planetbids.com/KHSD/BMfiles/20260930080635007%20Specifications.pdf"}],"awards": null}
Notes on the data:
- Dates are ISO 8601 with the agency's UTC offset (PlanetBids stores local time without a zone). Empty dates are
null. - Codes:
stage,bidTypeandresponseFormatare enums. If PlanetBids adds a new code, the value isunknown, the raw number stays instageCode/bidTypeCode/responseFormatCode, the item is still saved, and the code is listed inCONTRACT_DRIFT. - Stage comes from the bid list. The detail endpoint reports closed bids as stage 3 "Closed", so the list value is the reliable one.
- Estimated value is free text at PlanetBids (
"$150,000.00","N/A").estimatedValueUsdis set only when the text is a plain dollar amount. - Documents are metadata only. The file host is behind a CAPTCHA, so
downloadUrldoes not download with plain HTTP. - HTML fields (
scope,detailsHtml,notesHtml) are returned as published. Escape or sanitise them before rendering.
Run records (key-value store)
RUN_SUMMARY: end reason (completed,maxItemsReached,chargeLimitReached,wafBlocked,aborted), items pushed, failed details, skipped records, failed requests, WAF challenges, failed extras, and per portal: status (ok,notFound,failed, orskippedwhen the run stopped before the portal finished listing, e.g. at Max items), name,totalBidsreported by PlanetBids, listed and pushed counts.CONTRACT_DRIFT: new keys, missing keys, type changes and unknown codes seen in API responses. Empty means the API matched the expected contract.
The run's status message sums it up, for example Done: 1475 bids, 0 details failed, 0 portals not ok, 0 contract drift warnings. When the run collects nothing (no bids pushed and every portal unknown or failing), it ends as failed with a Failed: … message. A run aborted gracefully (the aborting event, API abort?gracefully=true) saves both records and reports Stopped (aborted): …. An immediate abort, the platform default, kills the run at once, so neither the records nor the status message are written.
Personal data
By default the Actor outputs no personal data. With includeContacts on, it adds the bid contact (name, phone, email), bid result respondent names and phones, and the prospective bidders list (contact names, phones, masked emails). prospectiveBidders is ignored without includeContacts. Only enable it if you have a legitimate reason and handle the data according to the laws that apply to you.
Pricing
Pay per event, platform usage included:
bid-list-item: $0.003 per bid ($3 per 1,000) with list data. Also charged when a bid's detail request failed and its list data is saved instead.bid-detail-item: $0.008 per bid ($8 per 1,000) with details and the requested extras.
Each bid is charged once, by one of the two events; extras (documents, addenda, awards…) are not charged separately. Example: 1,000 bids with details cost about $8. Paid Apify plans get lower per-event prices.
Rate limits and reliability
PlanetBids protects its API with an AWS WAF rate rule per IP. About 1 request per second runs clean; about 5 per second gets the IP challenged within half a minute, and the block lifts 1-2 minutes after traffic stops. The Actor:
- spaces every request (including extras) by
60 / maxRequestsPerMinuteseconds and runs one request at a time; - treats a WAF challenge (HTTP 202) as a soft block: pauses
wafBackoffSecs, rotates the session, retries the same request, and stops cleanly aftermaxWafChallengeschallenges in a row, keeping everything pushed so far (endReason: wafBlocked); - retries other failures 3 times; a bid whose detail keeps failing is saved with list data,
detailStatus: failedand the error; - never stops on bad data: a record it cannot identify is skipped and counted, any other field degrades to
nulland is reported inCONTRACT_DRIFT.
Throughput at the default 50 requests per minute: a portal with 1,500 bids lists in about 1 minute; with details, about 30 minutes; each extra adds about the same again. For large jobs, raise maxRequestsPerMinute only together with a rotating proxy.
🔗 Related procurement Actors
- Bonfire / Euna government bids — open RFPs and bids from hundreds of US and Canadian agencies on Bonfire / Euna Procurement. With PlanetBids, it covers two of the largest municipal bid platforms.
- Sourcewell awarded contracts & vendors — the Sourcewell cooperative contract registry with awarded suppliers, categories and an expiring-contracts filter.
- OMNIA Partners / NCPA cooperative contracts — OMNIA Partners, NCPA and US Communities contracts with lead agencies, expiration dates and contract PDFs.
From expiring contract to new bid: when a cooperative contract is about to expire, agencies that bought through it often run their own solicitation. Find contracts ending soon with expiresWithinDays in the Sourcewell or OMNIA Actor, then catch the new bid here or on Bonfire with a keyword filter.
Limitations
- Documents are listed, not downloaded (CAPTCHA on the file host).
- The portal catalog holds the portals found in public web crawls, then verified against the PlanetBids API; it misses portals that were never crawled. Any portal works when given by ID or URL.
- Some codes have no published labels (award type, bond formats, bid template type), so they are not output.
- The API is undocumented and can change without notice;
CONTRACT_DRIFTand a weekly API contract check exist for that reason.