# Grants.gov Scraper — Open Federal Funding Opportunities (`northbell/grants-gov-opportunities-scraper`) Actor

Open US federal funding opportunities from Grants.gov: agency, posted and closing dates, award ceiling and floor, eligible applicants, assistance listing, synopsis. Filter by keyword, agency, category, size; flag new since your last run. Official API, no login.

- **URL**: https://apify.com/northbell/grants-gov-opportunities-scraper.md
- **Developed by:** [Northbell](https://apify.com/northbell) (community)
- **Categories:** Business, Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 opportunities

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Grants.gov Scraper — Open Federal Funding Opportunities

Search **Grants.gov**, the US government's listing of federal funding opportunities, by keyword, agency, funding category, applicant type or award size and get one clean row per opportunity: **title, agency and department, posted and closing dates, award ceiling and floor, total funding, expected number of awards, eligible applicants, funding category and instrument, Assistance Listing numbers and a short synopsis**, with a link to the opportunity on Grants.gov. **$2.00 per 1,000 opportunities**, no login, no API key.

> This product uses the Grants.gov API but is not endorsed or certified by the U.S. Department of Health and Human Services.

Run it again, or put it on a daily schedule, and every row also tells you **whether the opportunity is new since the last run** (`isNew`). Set *What to return* to *Only new* and you pay only for the opportunities you have not seen before. Grants.gov lists 869 opportunities open for applications and 590 forecasts (16 Oct 2026), so the useful question is what appeared since yesterday; this keeps the list of what you have already seen.

### What you get

| Field | What it is |
|---|---|
| `opportunityId`, `opportunityNumber`, `url` | Grants.gov's internal ID, the number the agency gave the funding opportunity, and the link to its page on Grants.gov |
| `status`, `docType` | `posted` (open for applications), `forecasted` (announced in advance), `closed` or `archived`; `synopsis` (the opportunity itself) or `forecast` |
| `isNew`, `previousRunAt` | `true` / `false` whether you had not seen this opportunity in your previous run of the same search, and when that run was (`null` on the first run) |
| `title`, `description` | the title, and the synopsis cut at 500 characters (a trailing `…` marks a cut; empty without details) |
| `agencyCode`, `agency`, `topAgencyCode`, `topAgency` | the office that offers the funding (`National Institutes of Health`), its code (`HHS-NIH11`), and its department (`Department of Health and Human Services`) |
| `postedOn`, `closesOn` | the date it was posted and its application deadline (forecasts have none) |
| `awardCeiling`, `awardFloor`, `estimatedTotalFunding`, `expectedNumberOfAwards` | the largest and smallest single award, the total money available and how many awards are planned, as the agency states them |
| `costSharingRequired`, `category`, `fundingInstruments`, `fundingCategories` | whether the applicant must put in matching money, `Discretionary`, `Earmark`…, `Grant` / `Cooperative Agreement`…, and the subject area (`Health`, `Education`…) |
| `eligibleApplicants`, `eligibilityNote` | who may apply (`Small businesses`, `State governments`…) and the agency's note on eligibility, cut at 300 characters |
| `assistanceListings`, `assistanceProgramTitles` | the federal program numbers (for example `93.307`, the old CFDA numbers) and their titles |
| `archiveOn`, `lastUpdatedOn` | when the opportunity will be archived and when it was last changed |
| `forecastedSynopsisOn`, `forecastedAwardOn`, `fiscalYear` | on forecasts: the planned posting date, the planned award date and the fiscal year |
| `detailsFetched` | `true` when the full details were read (see *Input*); the fields that need them are `null` or empty otherwise |
| `observedAt` | when the row was collected |

### Run it again and again

- **On a schedule**: save your input as a task and add a **Schedule**: the same search every morning. Send each run to Google Sheets, Slack or email with an integration on the task.
- **Watch for changes**: Set **What to return** to *Only opportunities that are new since the last run*.
- **In bulk**: Combine **Keywords**, **Agencies**, **Who can apply** and **Funding categories** in one run.

### Use it for

- **Grant monitoring**: a daily schedule with your keywords and applicant type, *posted* and *Only new*, sent to Sheets, Slack or your CRM
- **Lead lists for grant writers and consultants**: which agencies fund your clients' fields, how much per award and when the deadline is
- **Early warning**: *forecasted* opportunities announce funding before it opens; the planned posting and award dates are in the row
- **Research**: closed opportunities by agency and category show what was funded in the past and at what size

### Input

```json
{
  "keywords": ["software", "cybersecurity"],
  "statuses": ["posted", "forecasted"],
  "postedWithinDays": 30,
  "eligibilities": ["23"],
  "minAward": 50000,
  "maxResults": 100,
  "output": "new"
}
```

- All filters are combined with AND; the entries inside one list are combined with OR. Words on a single keyword line must all appear. Each keyword line (and each Assistance Listing line) is a separate search on Grants.gov, and the results are merged without duplicates.
- **agencies**: the name or code as Grants.gov lists it (`Department of Energy`, `DOE`, `HHS-NIH11`). A top-level agency includes its sub-agencies. A name the Actor cannot find stops the run before anything is charged.
- **statuses**: `posted` (default), `forecasted`, `closed`, `archived`.
- **postedWithinDays**: only opportunities first posted in the last N days; empty means all, newest first. **closesWithinDays** — only those whose deadline falls in the next N days.
- **eligibilities**, **fundingCategories**, **fundingInstruments**, **assistanceListings** — Grants.gov's own codes; the input form lists the common ones.
- **minAward**, **maxAward** — the range of single award sizes you care about. An opportunity is kept when its range from award floor to award ceiling overlaps yours. Opportunities that state no ceiling (or 0) are left out when either is set, because their size is unknown.
- **includeDetails**: on by default. Grants.gov's search lists only the title, agency, dates and listing numbers, so the Actor reads each opportunity's page for the synopsis, award sizes, applicants and category: one extra request per opportunity. Switch it off for a fast list. A size filter reads the details whatever this says.
- Results are sorted newest first, and **maxResults** (default 100, up to 2,000) cuts the list from the old end. With *Only new* it is the number of new opportunities to return: the Actor reads down the list, past the opportunities you have already seen (up to 2,000 deep), until it has found that many. Opportunities below the cut-off are not marked as seen, so they come back as new in your next run.
- Grants.gov's search has no place or state filter, so this Actor has none either.

"Is it new" is remembered per search — the same keywords, agencies, statuses, applicant types, categories, listings and award sizes — in a named key-value store in your Apify account, so the second run of the same search already shows `isNew`. Changing *Posted within*, *Maximum opportunities* or the details switch keeps the same history. An opportunity that the agency changes later keeps its ID and is not shown as new again.

### Pricing

**$2.00 per 1,000 opportunities**, plus $0.01 per run. Error rows (a search Grants.gov rejects, Grants.gov not answering) are free. With *Only new*, opportunities you have already seen are skipped and not charged. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing.

### Notes

- Source: the public search API of Grants.gov (`search2` and `fetchOpportunity`), run by the US Department of Health and Human Services. Grants.gov's [API guide](https://grants.gov/api/api-guide) states that these two endpoints need no authentication, and nothing from behind a login is read. The [API terms and conditions](https://grants.gov/api/terms-conditions) allow using the API to search, display, analyze and retrieve grants data, and I found no clause on commercial use or on automated access in them; they ask services that use the API to show the notice at the top of this page and not to modify or misrepresent the content, which is why dates are only converted to ISO form and long text is only cut and marked with `…`. They also say access may be limited or blocked if limits are exceeded; no numeric limit is published, so the Actor identifies itself in its requests and waits 0.6 to 0.7 seconds between them.
- No contact persons, email addresses or phone numbers are returned: the Actor never reads the contact fields of an opportunity, and emails or international phone numbers that appear inside a synopsis are removed. Free text can still mention a person, so check synopses before you republish them.
- In a live read of the 100 newest open opportunities on 16 Oct 2026 (posted 25 Sep to 16 Oct), all 100 had a synopsis, an applicant list and Assistance Listing numbers, and 99 had a deadline. `awardCeiling` was stated on 74, left blank by the agency on 23 and 0 on 3; `awardFloor` was above 0 on 30 and 0 on 39, so a floor of 0 usually means none is stated. `estimatedTotalFunding` was above 0 on 64 and `expectedNumberOfAwards` was filled on 74. 93 of the synopses were longer than 500 characters and were cut.
- Reading those 100 opportunities with details took 87 seconds; the same 100 without details took 2.5 seconds, and 600 opportunities (three pages of results) took 3.8 seconds.
- Grants.gov counted 869 posted, 590 forecasted, 8,704 closed and 73,413 archived opportunities on 16 Oct 2026. Forecasts have no deadline and no archive date, and some posted opportunities have no archive date either.
- If Grants.gov is rate limiting or unavailable, the Actor waits and retries twice. If it still gets no answer it adds a free error row, and the run is marked failed when nothing at all could be read. If a single opportunity's details cannot be read, its row comes out with `detailsFetched` `false` (and is left out when you use a size filter).

For awards that have already been made — who won which federal contract or grant and for how much — see [USAspending Scraper](https://apify.com/northbell/usaspending-awards-scraper). For public tenders in the EU, see [EU Tenders Scraper (TED)](https://apify.com/northbell/eu-tenders-ted-search).

### For AI agents

`{"statuses": ["posted"], "postedWithinDays": 14, "maxResults": 5}` returns up to 5 rows, newest first, each with agency, deadline, award ceiling and eligible applicants. Rows have `type`: `opportunity` or `error`. Fields that do not apply to an opportunity are `null` (or an empty list), never missing. Schedule the same input daily with `"output": "new"` to get only what was posted since the previous run. This product uses the Grants.gov API but is not endorsed or certified by the U.S. Department of Health and Human Services.

# Actor input Schema

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

Words to find in the opportunity text. One per line; an opportunity that matches any line is returned. Words on one line must all appear. Keep them short, e.g. "cybersecurity" or "wildfire". Leave empty to skip.

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

Agencies that offer the funding, one per line: the name or code as Grants.gov lists it, e.g. "Department of Energy", "DOE", "National Science Foundation" or a sub-agency code such as "HHS-NIH11". A top-level agency includes all its sub-agencies. An unknown name stops the run before anything is charged. Leave empty for all agencies.

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

Which opportunities to include, one per line: "posted" (open for applications now), "forecasted" (announced in advance, not yet open), "closed" (deadline passed) and "archived" (older, kept for reference).

## `postedWithinDays` (type: `integer`):

Only opportunities first posted in the last N days. Leave empty for all of them, newest first. Run it daily with 3 or 7 and "Only new" below for a cheap feed of fresh opportunities.

## `closesWithinDays` (type: `integer`):

Only opportunities whose application deadline falls in the next N days. Opportunities with no stated deadline (all forecasts) are left out. Leave empty to skip.

## `eligibilities` (type: `array`):

Only opportunities open to these kinds of applicants, one two-digit code per line: 23 small businesses, 22 for-profit organizations other than small businesses, 12 nonprofits with 501(c)(3) status, 13 other nonprofits, 06 public universities, 20 private universities, 00 state governments, 01 county governments, 02 city governments, 07 federally recognized tribes, 21 individuals, 25 others, 99 unrestricted. Leave empty for all.

## `fundingCategories` (type: `array`):

Only opportunities in these categories, one code per line: HL health, ED education, ST science and technology, ENV environment, EN energy, AG agriculture, T transportation, AR arts, HU humanities, FN food and nutrition, ISS income security and social services, LJL law and justice, CD community development, DPR disaster relief, NR natural resources, O other. Leave empty for all.

## `fundingInstruments` (type: `array`):

Only these kinds of funding, one code per line: G grant, CA cooperative agreement, PC procurement contract, O other. Leave empty for all.

## `assistanceListings` (type: `array`):

Only opportunities under these federal programs, one per line, in the form 93.307 (the old CFDA numbers). Each line is a separate search and the results are merged. Leave empty for all.

## `minAward` (type: `number`):

Only opportunities whose largest award (the award ceiling) is at least this many US dollars. Opportunities that state no ceiling are left out when you set this or the maximum. Needs the details, which the Actor then reads whatever the setting below says.

## `maxAward` (type: `number`):

Only opportunities whose smallest award (the award floor, 0 if none is stated) is at most this many US dollars. Opportunities that state no ceiling are left out when you set this or the minimum.

## `includeDetails` (type: `boolean`):

On: one extra request per opportunity adds the synopsis, award ceiling and floor, total funding, number of awards, eligible applicants and funding category. Off: only title, agency, dates and listing numbers. Reading 100 opportunities took 87 seconds with details on and 2.5 seconds with them off.

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

How many opportunities to return, newest first. You pay per opportunity returned. With "Only new" the Actor reads past the opportunities you have already seen until it has found this many new ones. Narrow the search with the filters above rather than raising this.

## `output` (type: `string`):

With "Only new", opportunities you already got in an earlier run of the same search are skipped and not charged. The first run returns everything, because there is nothing to compare with yet.

## Actor input object example

```json
{
  "keywords": [
    "software"
  ],
  "statuses": [
    "posted"
  ],
  "postedWithinDays": 30,
  "includeDetails": true,
  "maxResults": 100,
  "output": "all"
}
```

# Actor output Schema

## `opportunities` (type: `string`):

Agency, dates, award size, applicants and listing numbers for each opportunity.

# 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 = {
    "keywords": [
        "software"
    ],
    "statuses": [
        "posted"
    ],
    "postedWithinDays": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/grants-gov-opportunities-scraper").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 = {
    "keywords": ["software"],
    "statuses": ["posted"],
    "postedWithinDays": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("northbell/grants-gov-opportunities-scraper").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 '{
  "keywords": [
    "software"
  ],
  "statuses": [
    "posted"
  ],
  "postedWithinDays": 30
}' |
apify call northbell/grants-gov-opportunities-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northbell/grants-gov-opportunities-scraper"
        }
    }
}
```

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/zCiugNbmzfk9spAcr/builds/XZkUHLnKFIFAHbqc7/openapi.json
