# State & Local Government RFP / Bid Monitor (five jurisdictions) (`sovereign_workspace/state-local-rfp-monitor`) Actor

One event per open state or local government solicitation (bids, RFPs, RFQs) from official open-data feeds: New York City, Los Angeles, Montgomery County MD, Delaware and Baton Rouge. Filter by keyword, category, UNSPSC and days to close.

- **URL**: https://apify.com/sovereign\_workspace/state-local-rfp-monitor.md
- **Developed by:** [Chase Mariano](https://apify.com/sovereign_workspace) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 rfp matcheds

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

## State & Local Government RFP / Bid Monitor

One **event per open solicitation** (bid, RFP, RFQ, IFB) from state and
local governments that publish their procurement notices through an
**official open-data feed**: New York City, Los Angeles, Montgomery
County (MD), the State of Delaware, and Baton Rouge (LA). Filter by
keyword, category, UNSPSC code, state and days left before the close
date. Built for small government contractors and bid consultants who
need "new roofing and HVAC bids closing in at least 10 days" on a
daily schedule, not five portals checked by hand.

**Pricing: pay per event.** `rfp-matched` — $0.03 per open solicitation
returned. With **Only new solicitations** on (the default), a daily
schedule charges each solicitation once while it stays open. A run with
no matches costs you nothing.

**Only official machine feeds, never scraped portals.** Each source is
the jurisdiction's own Socrata open-data API. If one source is down or
changes shape, that source is skipped and named in the run status and
the others still deliver. A run fails only if every selected source
fails, and then nothing is charged.

### Coverage

| Source id | Feed | State | Official dataset |
|---|---|---|---|
| `nyc_city_record` | New York City: City Record Online (DCAS) | NY | [data.cityofnewyork.us/d/dg92-zbpx](https://data.cityofnewyork.us/d/dg92-zbpx) |
| `la_ramp` | City of Los Angeles: RAMP Open Bid Opportunities | CA | [data.lacity.org/d/hf3r-utnq](https://data.lacity.org/d/hf3r-utnq) |
| `montgomery_county_md` | Montgomery County, MD: Solicitations | MD | [data.montgomerycountymd.gov/d/eeq6-nnwe](https://data.montgomerycountymd.gov/d/eeq6-nnwe) |
| `delaware_state` | State of Delaware: Open Bids (OMB / GSS) | DE | [data.delaware.gov/d/2hnj-zwix](https://data.delaware.gov/d/2hnj-zwix) |
| `baton_rouge` | City of Baton Rouge / East Baton Rouge Parish: Bid Openings | LA | [data.brla.gov/d/u9zk-8nix](https://data.brla.gov/d/u9zk-8nix) |

Five jurisdictions, one of them a state. This is not a national bid
aggregator: most state e-procurement portals don't publish an open data
feed, and this Actor doesn't scrape them. Federal opportunities are
covered by the SAM.gov Opportunity Monitor.

### Input

```json
{"states": ["NY", "MD"], "keywords": ["roofing", "hvac"], "min_days_to_close": 10}
```

- **Filters combine with AND; entries within one filter combine with OR.**
- **Keywords** match the title, description, category and agency, ignoring case.
- **Category contains** matches the source's category text. Montgomery and Delaware publish no category text, so they drop out when this is set.
- **UNSPSC code prefixes** apply to Delaware, the only source that publishes codes. Other sources drop out when this is set.
- **Standing lists:** by default, notices whose close date is more than a year away are left out. These are standing prequalification lists and continuous solicitations (NYC marks them 2999-12-31). Set **Include standing / open-ended lists** to get them, flagged `open_ended`.
- **Order:** results come soonest close first.

### Example output (one dataset item per solicitation)

```json
{
 "source": "delaware_state",
 "jurisdiction": "State of Delaware",
 "state": "DE",
 "level": "state",
 "record_id": "BSD270001-CHILLERDRD",
 "reference_number": "BSD270001-CHILLERDRD",
 "title": "Darley Rd EEC Boiler and Chiller Replacement",
 "agency": "BSD",
 "notice_type": null,
 "category": null,
 "category_codes": [
  "7215",
  "9512"
 ],
 "posted_date": "2026-08-12",
 "due_date": "2026-09-24",
 "due_time": null,
 "status": null,
 "description": null,
 "contact_name": null,
 "contact_email": null,
 "contact_phone": null,
 "url": "https://mmp.delaware.gov/Bids/Details/9277",
 "days_to_close": 1,
 "open_ended": false,
 "source_dataset_url": "https://data.delaware.gov/d/2hnj-zwix"
}
```

### Output fields

One dataset item per result; every field is always present
(empty or null when the source has no value). Defined in
`.actor/dataset_schema.json`.

| Field | Type | Description |
|---|---|---|
| `source` | string | Source id: nyc\_city\_record, la\_ramp, montgomery\_county\_md, delaware\_state or baton\_rouge |
| `jurisdiction` | string | Publishing jurisdiction (e.g. New York City, NY) |
| `state` | string | Two-letter state of the jurisdiction |
| `level` | string | city, county or state |
| `record_id` | string | The source's own id for this notice |
| `reference_number` | string or null | Solicitation / PIN / contract number where the source gives one |
| `title` | string or null | Solicitation title (max 300 chars) |
| `agency` | string or null | Issuing agency or department |
| `notice_type` | string or null | RFP, IFB, RFQ, selection method, etc., as the source words it |
| `category` | string or null | Category text where the source gives one |
| `category_codes` | array | UNSPSC codes where the source publishes them (Delaware); otherwise empty |
| `posted_date` | string or null | Date posted or issued, YYYY-MM-DD (null where the source has none) |
| `due_date` | string or null | Close / bid-opening date, YYYY-MM-DD |
| `due_time` | string or null | Close time HH:MM, local to the jurisdiction, where given |
| `status` | string or null | Source status (e.g. Open, Amended, Active) where given |
| `description` | string or null | Plain-text description or note (max 1000 chars) where given |
| `contact_name` | string or null | Contact or buyer name where given |
| `contact_email` | string or null | Contact email where given |
| `contact_phone` | string or null | Contact phone where given |
| `url` | string or null | Link to the notice, as given by the source (null if it gives none) |
| `days_to_close` | integer or null | Days from the run date to the close date |
| `open_ended` | boolean | True for a standing list whose close date is more than 365 days away |
| `source_dataset_url` | string | The official open-data dataset this record came from |

Runs stop cleanly at your max-charge limit: nothing is pushed past
what you agreed to pay for. Anything a limit or budget cut leaves
undelivered is returned on the next run of the same watch.

### Freshness and quirks

- **Refresh cadence** is set by each publisher: LA hourly, NYC, Montgomery and Baton Rouge daily, Delaware weekly. The Actor reads the live feed every run.
- **Dates are local** to the jurisdiction, exactly as published. `days_to_close` counts from the run date. Always confirm the deadline on the linked notice before bidding.
- **Links:**
  - Montgomery County's feed has no per-notice link, so `url` is null and `source_dataset_url` points to the official dataset.
  - Baton Rouge's link is the bid-information link the city gives in the notice.
- **Only new solicitations** remembers what a watch has already returned in a key-value store in your account (`state-local-rfp-monitor-state`). A different set of sources or filters is a different watch.

### Sources, attribution and disclaimers

- **New York City:** City Record Online, NYC Department of Citywide Administrative Services, via NYC Open Data (public domain).
- **Los Angeles:** City of Los Angeles, RAMP, via data.lacity.org (CC0 1.0).
- **State of Delaware:** Office of Management and Budget, Government Support Services, via data.delaware.gov (public data, "as is").
- **Baton Rouge:** City of Baton Rouge / Parish of East Baton Rouge Purchasing, via Open Data BR (public domain).
- **Montgomery County, Maryland,** via data.montgomerycountymd.gov. The county's terms require this notice: "The data made available here has been modified for use from its original source, which is Montgomery County, Maryland ("the County"). THE COUNTY MAKES NO REPRESENTATIONS OR WARRANTIES AS TO THE COMPLETENESS, ACCURACY, OR TIMELINESS OF ANY DATA. THE COUNTY EXPRESSLY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. THE COUNTY MAKES NO REPRESENTATION OR WARRANTY AS TO THE WEBISTE OR APPLICATION USING DATA DRAWN FROM DATA.MONTGOMERYCOUNTYMD.GOV OR FOR THE USEFULNESS OR INTEGRITY OF THE WEB SITE OR APPLICATION. The data is subject to change and possible deletion, temporarily or permanently. It is understood that the information contained in the web feed is being used at one's own risk."
- **Not affiliated with or endorsed by** any of these governments. Each source's data is provided "as is". What this Actor changes: HTML is converted to plain text, dates are normalized to YYYY-MM-DD, and fields are renamed to one common schema.

# Actor input Schema

## `profile` (type: `string`):

Named config preset applied at start. Any field you set explicitly below overrides the preset.

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

Which official feeds to read. Leave empty for all five.

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

Two-letter states to keep (NY, CA, MD, DE, LA). Leave empty for all.

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

Keep solicitations whose title, description, category or agency contains at least one of these words (e.g. roofing, janitorial, software). Leave empty for all.

## `categories` (type: `array`):

Keep solicitations whose category text contains one of these (e.g. construction, personal services). Sources without categories are dropped when this is set.

## `category_codes` (type: `array`):

UNSPSC code prefixes, 2-8 digits (e.g. 72 for building and construction services). Only Delaware publishes codes, so other sources are dropped when this is set.

## `min_days_to_close` (type: `integer`):

Skip solicitations closing sooner than this many days from the run date (0 keeps those closing today).

## `posted_within_days` (type: `integer`):

Keep only solicitations posted in the last N days (0 = any). Baton Rouge publishes no posted date, so it's dropped when this is set.

## `include_open_ended` (type: `boolean`):

Include standing prequalification lists and continuous solicitations whose close date is more than a year away (NYC uses 2999-12-31 for these).

## `only_new` (type: `boolean`):

Remember what this watch (same sources and filters) has already returned, in a key-value store in your account, so a daily schedule charges each solicitation once.

## `limit` (type: `integer`):

Maximum number of solicitations to return per run.

## Actor input object example

```json
{
  "min_days_to_close": 0,
  "posted_within_days": 0,
  "include_open_ended": false,
  "only_new": true,
  "limit": 100
}
```

# Actor output Schema

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

No description

## `errorCounters` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("sovereign_workspace/state-local-rfp-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("sovereign_workspace/state-local-rfp-monitor").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 '{}' |
apify call sovereign_workspace/state-local-rfp-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sovereign_workspace/state-local-rfp-monitor"
        }
    }
}
```

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/QqaO3VCOVbrIPE5mE/builds/4Jh4hADol7RDRfAZM/openapi.json
