# Grants.gov Scraper - Federal Grants (`datalayer/grants-gov-funding`) Actor

Grants.gov search returns a title, an agency and a date. Award size, whether you must match funds, and who may actually apply live on a second endpoint that nothing on the store joins up. This does, and its deadline radar correctly excludes forecasts, which have no closing date yet by design.

- **URL**: https://apify.com/datalayer/grants-gov-funding.md
- **Developed by:** [Datalayer](https://apify.com/datalayer) (community)
- **Categories:** Business, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Grants.gov Scraper — Federal Grant Opportunities

Scrape every **US federal grant opportunity** from Grants.gov, joined to the
detail endpoint the search results hide.

The search gives you a title, an agency and a closing date. Everything that
decides whether an application is worth two weeks of work — how large the award
is, whether you must put up matching funds, who is actually eligible — lives on
a **second endpoint**, one request per opportunity. Nothing on the store joins
the two.

### What you get that a search wrapper cannot give you

**The award range.** `awardCeiling` and `awardFloor`: the largest and smallest
single award the agency will make. This is the size signal — but **coverage
varies sharply by agency**, so read the honest numbers below before relying on
it.

**The cost-share flag.** `requiresCostSharing` — you must supply matching funds.
The most reliably published field on the detail endpoint, and for a small
nonprofit it single-handedly decides whether a programme is reachable. It is
not in the search results at all.

**Decoded eligibility.** The search filter takes numeric codes (`25`, `12`,
`20`). The output gives you plain English — "Private institutions of higher
education", "County governments" — plus the agency's own eligibility narrative,
which usually narrows things further than the codes suggest.

**A closing-soon radar that understands forecasts.** A *forecasted* opportunity
has an **empty** close date, because the deadline does not exist yet. Treating
that as a date puts every forecast at the top of a deadline list. Here they are
flagged `hasNoDeadlineYet` and kept off the radar — while still being returned,
because a forecast is early warning a competitor watching only posted
opportunities will miss.

**The programme contact.** Name and email of the person to ask before you write
anything.

### An honest note on award size

An earlier version of this actor led on *average award* — estimated funding
divided by expected number of awards. Then it got measured:

| Field | Spread across 39 agencies | Default run (NIH-heavy) |
|---|---|---|
| `costSharing` | **100%** | 92% |
| `awardCeiling` | 80% | **30%** |
| `awardFloor` | 76% | 13% |
| `estimatedFunding` | 38% | — |
| `expectedNumberOfAwards` | **0%** | **0%** |

*Both measured 2026-08-16: 66 opportunities sampled across 39 agencies, and 100
enriched on a default run.*

Two things follow, and neither is hidden here:

1. `expectedNumberOfAwards` is populated on **nothing**, so an average award is
   not computable. The field is still returned and will populate if agencies
   start filing it, but it is null today. **Use `awardCeiling` and `awardFloor`.**
2. **Ceiling coverage depends heavily on which agencies you pull.** A broad
   sweep across 39 agencies publishes ceilings 80% of the time; an NIH-dominated
   default run only 30%. NIH rarely publishes them. If award size matters to
   you, filter by agency and check `opportunitiesWithAwardRange` in the summary
   before drawing conclusions.

### Who uses this

- **Nonprofits and universities** — building a deadline pipeline instead of
  checking a website.
- **Small businesses chasing SBIR/STTR** — filtering to programmes they can
  actually win, at a size worth the effort.
- **Grant consultants** — watching named agencies for new programmes.
- **Anyone already using our USAspending actor** — this is money going *out*;
  that one is money already *spent*. `cfdaNumbers` joins them.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `keyword` | string | `""` | Free text across titles and descriptions |
| `statuses` | array | `["posted","forecasted"]` | Open now, plus announced-but-not-open |
| `closingWindowDays` | integer | `30` | What counts as closing soon |
| `closingSoonOnly` | boolean | `false` | Drop rows outside the window |
| `agencies` | array | `[]` | Agency codes, e.g. `HHS-NIH`, `USDA-NIFA` |
| `eligibilities` | array | `[]` | Applicant-type codes, e.g. `25`, `12` |
| `fundingCategories` | array | `[]` | e.g. `HL` health, `ED` education |
| `minAwardCeiling` | integer | `0` | Drops rows with no published ceiling |
| `excludeCostSharing` | boolean | `false` | Drop programmes needing matching funds |
| `enrich` | boolean | `true` | The second request. Off = titles only |
| `maxEnriched` | integer | `100` | Runs **deadline-first**, so a capped run enriches what matters |

Agency summaries are always built from everything collected, even with a filter
on — otherwise the funding totals would describe your filter rather than the
agency.

### Output

**`opportunity`** — `title`, `agency`, `status`, `closeDate`, `daysUntilClose`,
`isForecast`, `awardCeiling`, `awardFloor`, `estimatedTotalFunding`,
`requiresCostSharing`, `applicantTypes`, `eligibilitySummary`,
`agencyContactEmail`, `cfdaNumbers`, `opportunityUrl`.

**`closing_soon`** — the deadline-driven subset, soonest first.

**`agency_summary`** — `opportunities`, `forecasts`, `closingSoon`,
`soonestCloseDate`, `totalFundingAdvertised`, `medianAwardCeiling`,
`largestAwardCeiling`, `opportunitiesWithAwardRange`,
`opportunitiesRequiringCostShare`, `topApplicantTypes`.

### Reliability

- `awardCeiling` arrives as the literal string **`"none"`** when absent.
  `Number("none")` is `NaN` and `if (awardCeiling)` passes on it, so a naive
  parse silently emits NaN. Resolved to `null` here.
- Dates are `MM/DD/YYYY`, converted to ISO.
- `isEnriched` tells you whether the detail fields are absent because the cap
  was reached or because the agency did not publish them. Those are different.
- One opportunity failing to enrich never costs the run.

### Pricing

Pay per event. $0.002 per opportunity, $0.01 per closing-soon row, $0.05 per
agency summary.

# Actor input Schema

## `keyword` (type: `string`):

Free-text search across opportunity titles and descriptions, e.g. rural broadband, cancer research. Leave empty for everything.

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

Grants.gov agency codes, e.g. HHS-NIH, USDA-NIFA, NSF. Leave empty for all.

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

Posted means open now. Forecasted means announced but not yet open — the early warning, and it has no deadline yet by design.

## `closingSoonOnly` (type: `boolean`):

Drop opportunity rows outside the window. Agency summaries are still built from everything.

## `closingWindowDays` (type: `integer`):

An opportunity counts as closing soon if its deadline falls inside this many days.

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

Grants.gov applicant-type codes, e.g. 25 for nonprofits without 501(c)(3), 21 for individuals, 12 for small businesses.

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

e.g. HL for health, ED for education, AG for agriculture, ENV for environment.

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

G for grant, CA for cooperative agreement, PC for procurement contract, O for other.

## `minAwardCeiling` (type: `integer`):

Requires enrichment. Filters on the largest single award the agency will make. Measured 2026-08-16: a ceiling is published on about 80% of opportunities, and rows without one are dropped by this filter. 0 means no filter.

## `excludeCostSharing` (type: `boolean`):

Cost sharing means you must put up matching funds. For a small applicant that single flag decides whether a programme is reachable.

## `includeOpportunities` (type: `boolean`):

Return one row per opportunity.

## `includeClosingSoon` (type: `boolean`):

Return the deadline-driven subset again as its own row type, soonest first.

## `includeAgencySummary` (type: `boolean`):

Per-agency funding advertised, typical award size and how many programmes demand matching funds.

## `maxOpportunities` (type: `integer`):

Grants.gov serves up to 1000 per page.

## `enrich` (type: `boolean`):

One extra request per opportunity, and the only way to get award ceiling, expected number of awards and the computed average award. Turn off for a fast title-only list.

## `maxEnriched` (type: `integer`):

Enrichment runs deadline-first, so a capped run enriches the ones closing soonest.

## `proxyConfiguration` (type: `object`):

Optional. Grants.gov is a public API and does not require a proxy.

## Actor input object example

```json
{
  "keyword": "climate",
  "agencies": [],
  "statuses": [
    "posted",
    "forecasted"
  ],
  "closingSoonOnly": false,
  "closingWindowDays": 30,
  "eligibilities": [],
  "fundingCategories": [],
  "fundingInstruments": [],
  "minAwardCeiling": 0,
  "excludeCostSharing": false,
  "includeOpportunities": true,
  "includeClosingSoon": true,
  "includeAgencySummary": true,
  "maxOpportunities": 200,
  "enrich": true,
  "maxEnriched": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `closing` (type: `string`):

Opportunities with a deadline inside the window, soonest first.

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

Every matching opportunity with award economics and eligibility.

## `agencies` (type: `string`):

Per-agency funding advertised, typical award size and cost-share load.

## `csv` (type: `string`):

Everything as a CSV download.

## `runSummary` (type: `string`):

Counts, how many carried award economics, and anything that failed.

# 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 = {
    "keyword": "climate",
    "closingWindowDays": 30,
    "maxOpportunities": 200,
    "maxEnriched": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("datalayer/grants-gov-funding").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 = {
    "keyword": "climate",
    "closingWindowDays": 30,
    "maxOpportunities": 200,
    "maxEnriched": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("datalayer/grants-gov-funding").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 '{
  "keyword": "climate",
  "closingWindowDays": 30,
  "maxOpportunities": 200,
  "maxEnriched": 100
}' |
apify call datalayer/grants-gov-funding --silent --output-dataset

```

## MCP server setup

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

```

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/xd5U3sE6oNuGE92Iy/builds/nhWj4DtCesON2r8UJ/openapi.json
