# Florida Government Bids & RFPs Scraper (`jedkirby/gov-bids-southeast`) Actor

Scrape open Florida government bids, RFPs, ITBs and ITNs from MyFloridaMarketPlace: state agencies, universities, counties and cities. Get daily new-bid alerts with agency, bid number, due date, UNSPSC codes and document links as JSON, CSV or Excel. $4 per 1,000 bids, no login.

- **URL**: https://apify.com/jedkirby/gov-bids-southeast.md
- **Developed by:** [Jed Kirby](https://apify.com/jedkirby) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 bid results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Florida Government Bids & RFPs Scraper (MyFloridaMarketPlace)

Get **open Florida government bids, RFPs, ITBs, ITNs, RFIs and RSQs** from **MyFloridaMarketPlace (MFMP)** as clean JSON, CSV or Excel. There's no login and no copy-pasting.
Schedule it daily with **"Only new or changed bids"** turned on, and each morning you get just the new and amended solicitations, ready to send to a spreadsheet, Slack, email or your CRM.

- ✅ **Statewide coverage:** every state agency, plus the universities, colleges, water management districts, counties and cities that post on MFMP
- ✅ **One clean row per bid:** agency, title, bid number, type, posted and due dates, UNSPSC commodity codes, location, posting link and **direct document links**
- ✅ **Daily new-bid alerts:** built-in deduplication also catches addenda and due-date changes
- ✅ **Filters:** agency, keyword, advertisement type, posted date and status (including closed bids for research)
- ✅ **Low cost:** $4 per 1,000 bids, so the whole statewide open list costs about $0.50
- ✅ **No personal data:** procurement officers' names, emails and phone numbers are never collected

### Who it's for

- **Contractors and suppliers** (construction, roofing, HVAC, janitorial, IT, staffing, consulting) who want to find Florida state contracts before competitors do
- **Bid-finding services and business development teams** building a Florida government lead feed
- **Analysts and journalists** tracking what Florida agencies buy and when
- **Developers and AI agents** who need a structured Florida procurement API

### What data you get

A typical run on open solicitations returns **about 120–200 bids from 25–40 agencies**. Agencies post about 3–8 new solicitations each business day.

| Field | Description |
|---|---|
| `agency`, `agency_code` | Posting agency, e.g. `Department of Environmental Protection (DEP)`, `DEP` |
| `title` | Solicitation title |
| `solicitation_number` | The agency's own number, e.g. `BDC04-26/27` |
| `ad_number`, `ad_type` | Portal ad number (`ITB-17292`) and type (Invitation to Bid, Request for Proposals, Invitation to Negotiate, ...) |
| `categories`, `category_scheme` | Commodity codes `[{code, name}]`. Florida uses **UNSPSC** |
| `posted_date`, `open_date`, `due_date` | ISO 8601 UTC. `due_date` is the advertisement's End Date/Time |
| `response_open_date` | Public opening date and time, when the agency gives one |
| `status` | `OPEN`, `CLOSED`, `WITHDRAWN` |
| `location`, `location_city`, `location_state`, `location_zip` | Agency response address (city, state and ZIP only) |
| `description` | Plain-text advertisement (up to 4,000 characters) |
| `url` | Public posting page |
| `documents`, `documents_count` | Attached files `[{name, description, posted, url}]` |
| `version`, `last_updated`, `change_type` | Addenda tracking. With dedup turned on, `change_type` is `new` or `updated` |
| `source`, `source_id`, `dedupe_key`, `scraped_at` | Technical fields for joining and deduplicating data |

`naics` and `estimated_value` are always `null` because MFMP doesn't publish them.

#### Sample output (real record, shortened)

```json
{
  "agency": "Department of Environmental Protection (DEP)",
  "agency_code": "DEP",
  "title": "Addendum 2 BDC04-26/27 Suwannee River State Park – Bathhouse Replacement",
  "solicitation_number": "BDC04-26/27",
  "ad_number": "ITB-17292",
  "ad_type": "Invitation to Bid",
  "categories": [
    {"code": "72121100", "name": "Commercial and office building construction services"},
    {"code": "72151201", "name": "HVAC mechanical construction service"}
  ],
  "category_scheme": "UNSPSC",
  "posted_date": "2026-10-21T16:25:45Z",
  "due_date": "2026-10-27T19:30:00Z",
  "status": "OPEN",
  "location": "Tallahassee, FL 32399-3000",
  "url": "https://vendor.myfloridamarketplace.com/search/bids/detail/17292",
  "documents": [
    {"name": "Addendum 2 BDC04-26-27.pdf", "posted": "2026-10-21T16:25:17Z",
     "url": "https://vendor.myfloridamarketplace.com/mfmp/bids/detail/attachment/download?attachmentId=41382"}
  ],
  "documents_count": 1,
  "version": 1,
  "change_type": "new"
}
```

### How to use it

1. Click **Start**. The prefilled input returns the 20 newest open solicitations statewide in about 30 seconds, for about $0.08.
2. Narrow the results:
   - **Agencies:** partial names or short codes, e.g. `FDOT`, `University of South Florida`, `Hillsborough`, `Water Management`
   - **Keywords:** e.g. `roofing`, `HVAC`, `janitorial`, `paving`, `software`. A bid matches if its title, description or commodity-code names contain a word *starting with* a keyword (`roof` matches "roofing" but not "proof")
   - **Advertisement types:** solicitations only, by default. Add *Agency Decision* or *Single Source* to follow awards and intent notices
   - **Posted since:** `2026-10-01` or `7 days`
   - **Statuses:** `OPEN` by default. `CLOSED` and `WITHDRAWN` are for research and need *Posted since* (up to 366 days back)
3. For a daily feed, turn on **Only new or changed bids since last run** and add a **Schedule** in Apify Console. Give each saved search its own *Dedup memory name*.

#### Input examples

**Daily construction leads for the Tampa Bay area:**

```json
{
  "agencies": ["FDOT", "University of South Florida", "Hillsborough", "Southwest Florida Water Management"],
  "keywords": ["construction", "roof", "hvac", "paving"],
  "onlyNewSinceLastRun": true,
  "stateStoreName": "tampa-construction"
}
```

**Every open IT and software solicitation statewide:**

```json
{
  "keywords": ["software", "IT services", "cloud", "cybersecurity", "network"],
  "adTypes": ["Invitation to Negotiate", "Request for Proposals", "Request for Information"]
}
```

**Research: intent-to-award notices from the last 90 days:**

```json
{
  "adTypes": ["Agency Decision"],
  "statuses": ["CLOSED", "OPEN"],
  "postedSince": "90 days",
  "maxResults": 1000
}
```

### Pricing

You pay **$0.004 per bid saved** ($4.00 per 1,000) plus a $0.00005 start fee per run. Apify platform usage is included; there's no extra compute bill.

| What you run | Bids returned | About |
|---|---|---|
| The prefilled test run | 20 | **$0.08** |
| The whole statewide open list | ~120–200 | **$0.50–$0.80** |
| Daily "only new or changed" alert run | ~3–10 a day | **$0.01–$0.04 a day, under $1 a month** |
| Run where nothing changed | 0 | **$0.00005** |

Set **Maximum cost per run** in Apify Console for a hard cap. The Actor stops cleanly when it's reached.

### Integrations and API

- **Google Sheets, Slack, email, Zapier, Make, n8n, webhooks:** use the run's **Integrations** tab to send each run's results wherever you need them.
- **API:** call the Actor from any language with the Apify API or clients, e.g. `run-sync-get-dataset-items` for a single request that returns the bids.
- **AI agents and MCP:** available through the Apify MCP server, so an assistant can look up Florida bids on request.

### Downloading the attached documents

`url` opens the public posting page, where every document is listed. The `documents[].url` links are direct download endpoints. They return the file
to HTTP clients that send `Accept: application/octet-stream`, e.g.
`curl -H "Accept: application/octet-stream" -o file.pdf "<url>"`. If you paste one into a browser tab, you get the portal home page instead,
so download files by hand from the posting `url`.

### FAQ

**Do I need a MyFloridaMarketPlace account?** No, not to get the data. You do need a free MFMP vendor registration to *respond* to state solicitations.

**Does it cover counties and cities?** Only those that post on MFMP, such as Alachua County, City of Winter Haven and many universities and colleges.
Many counties and cities run their own bid portals, and those aren't covered. Federal opportunities (SAM.gov) aren't covered either.

**How fresh is the data?** Each run reads the live portal. A daily schedule catches every new posting well within Florida's usual minimum posting period.

**Will I get the same bid twice?** Not with *Only new or changed bids* turned on. A bid comes back only when the agency publishes an addendum (new version)
or changes its due date or status. Those rows have `change_type = "updated"`.

**Why are there no contract values or NAICS codes?** MFMP doesn't publish them. Any amounts are in the attached documents. Use UNSPSC
commodity codes or keywords to filter instead.

**Is the due date always the deadline?** `due_date` is the advertisement's End Date/Time. Agencies sometimes set other deadlines or move them in addenda.
**Always confirm deadlines in the official solicitation documents.**

**Something's wrong, or you want another source?** Open an issue on the **Issues** tab and include the run ID.

### Responsible scraping

- Reads only the public, no-login search the portal offers to everyone, one request at a time with a delay of at least 1 second, and identifies itself in its User-Agent.
- Collects no personal data. Contact names, emails and phone numbers are left out; read them on the posting page.
- Doesn't log in, solve CAPTCHAs or get around bot protection.
- Not affiliated with or endorsed by the State of Florida or the Department of Management Services. The data is exactly what agencies post.

### Sources and roadmap

| Source | Status |
|---|---|
| Florida MyFloridaMarketPlace Vendor Information Portal (statewide) | ✅ Supported |
| Other Southeast state portals (GA, AL, SC, NC, TN) | Planned, added only where public automated access is allowed |
| PlanetBids and Bonfire agency portals | Not supported: bot protection or terms that forbid automated extraction |

# Actor input Schema

## `maxResults` (type: `integer`):

Stop after this many bids are saved (newest first). This also caps your cost: you pay $0.004 per saved bid, so 20 bids cost $0.08 and the whole open list (about 120-200 bids) costs about $0.50-$0.80.

## `agencies` (type: `array`):

Limit to specific agencies. Partial, case-insensitive match on the agency name or short code, e.g. "FDOT", "University of South Florida", "Hillsborough", "Water Management". Leave empty for all agencies.

## `keywords` (type: `array`):

Keep only bids whose title, description or commodity-code names contain a word starting with one of these (case-insensitive): "roof" matches "roofing". Examples: "roofing", "HVAC", "janitorial", "paving", "software". Leave empty for everything.

## `adTypes` (type: `array`):

Which kinds of postings to include. By default only actual solicitations (ITB, ITN, RFP, RFI, RFSOQ). Add Agency Decision, Single Source etc. if you track awards/intent notices.

## `postedSince` (type: `string`):

Only bids published on or after this date. Absolute (2026-10-01) or relative (7 days, 2 weeks).

## `statuses` (type: `array`):

OPEN = currently accepting responses. CLOSED and WITHDRAWN are historical and require "Posted since" so the scan stays bounded.

## `onlyNewSinceLastRun` (type: `boolean`):

Recommended for scheduled runs. Remembers bids already delivered and returns only new ones, plus bids the agency changed (new version/addendum, new due date or status; change_type = "updated"). A run with nothing new costs only the start fee.

## `stateStoreName` (type: `string`):

Name of the key-value store used to remember delivered bids. Use different names for different saved searches so they don't share memory.

## `includeDescription` (type: `boolean`):

Include the plain-text advertisement description (truncated to 4,000 characters).

## `sources` (type: `array`):

Procurement portals to pull from. Currently Florida's statewide MyFloridaMarketPlace Vendor Information Portal (state agencies plus many universities, colleges, water management districts, counties and cities). Leave as is.

## `states` (type: `array`):

Two-letter state codes. Currently only FL has a supported source. Leave as is.

## `requestDelaySecs` (type: `number`):

Politeness delay between requests to the source. Minimum 0.5.

## Actor input object example

```json
{
  "maxResults": 20,
  "agencies": [],
  "keywords": [],
  "adTypes": [
    "Invitation to Bid",
    "Invitation to Negotiate",
    "Request for Proposals",
    "Request for Information",
    "Request for Statement of Qualifications"
  ],
  "statuses": [
    "OPEN"
  ],
  "onlyNewSinceLastRun": false,
  "stateStoreName": "gov-bids-southeast-state",
  "includeDescription": true,
  "sources": [
    "florida_vip"
  ],
  "states": [
    "FL"
  ],
  "requestDelaySecs": 1
}
```

# Actor output Schema

## `results` (type: `string`):

All bids saved by this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxResults": 20,
    "sources": [
        "florida_vip"
    ],
    "states": [
        "FL"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jedkirby/gov-bids-southeast").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "maxResults": 20,
    "sources": ["florida_vip"],
    "states": ["FL"],
}

# Run the Actor and wait for it to finish
run = client.actor("jedkirby/gov-bids-southeast").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxResults": 20,
  "sources": [
    "florida_vip"
  ],
  "states": [
    "FL"
  ]
}' |
apify call jedkirby/gov-bids-southeast --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jedkirby/gov-bids-southeast"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/YhYPXBtmGQ4uF7VWm/builds/jGgTargoW3KDsIIMK/openapi.json
