# Grants.gov Scraper: Federal Grant Opportunities (`automation_craft/grants-gov-scraper`) Actor

Scrape Grants.gov federal grant opportunities with award amounts, deadlines, eligibility, ALN and attachments; look up by number or monitor new grants. This product uses the Grants.gov API but is not endorsed or certified by the U.S. Department of Health and Human Services.

- **URL**: https://apify.com/automation_craft/grants-gov-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 5 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 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: Federal Grant Opportunities

**Grants.gov Scraper** turns the US federal government's list of grant funding opportunities into clean rows: every
forecasted, posted, closed and archived opportunity, with award amounts, dates, eligibility, description, contacts,
attachments and the agency's own amendment history. It reads the official Grants.gov API, needs no login and no API key,
and can watch a search for you: run it on a schedule with a monitor name and each run delivers only what is new or
amended since the last one.

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

#### What it does

- **Search** like Grants.gov does: keywords (OR, AND, "exact phrases", -exclusions, wild\*cards), status, agency or whole
  department, funding category, funding instrument, eligible applicant type and Assistance Listing (CFDA) number, plus
  what Grants.gov cannot filter: a posted date window from any date to any date (Grants.gov offers only "posted in the
  last N days"), a closing date window and a minimum award ceiling.
- **Look up** exact opportunities by number (PAR-25-274), Grants.gov id (357305) or Grants.gov link. A number shared by
  several opportunities returns each of them.
- **Full records** by default: award ceiling and floor, estimated total funding, expected awards, cost sharing, eligible
  applicants (names and codes), eligibility text, description as plain text, agency contact, every attachment with its
  download link, application packages, related opportunities, revision number and days until the close date.
- **Revision rows**: one free row per amendment Grants.gov keeps in the record (which fields changed, before and after,
  with the agency's comment).
- **Monitor**: a scheduled run with the same monitor name delivers and charges only opportunities that are new to it or
  that Grants.gov amended to a higher revision. A run that finds nothing new delivers a free status row.
- **Honest misses**: an id or number Grants.gov does not have, a code that does not exist and an empty search each get
  a free status row that says so, and every run ends with a summary row with its counters.
- **List mode**: switch full records off for the short list row at a lower price (a run delivers up to 100,000 rows;
  the largest list run tested on the platform delivered 600 rows in 2 seconds).

#### Quick start

1. Press Start with the example input (the 10 newest posted opportunities about health), or clear every field to get
   the 100 newest open opportunities (forecasted and posted) as full records.
2. Or type a keyword ("rural broadband"), pick statuses, agencies or categories, and set Maximum opportunities.
3. To read exact opportunities, paste opportunity numbers, ids or Grants.gov links into the Lookup section.
4. To get only new and amended opportunities every day, give the search a Monitor name and schedule the task.
5. Export the dataset as JSON, CSV or Excel, or read it through the Apify API.

### What you get

One row per opportunity (`type: "opportunity"`). The fill rates below were measured on 150 live records on 2026-10-10
(50 posted, 40 forecasted, 30 closed, 30 archived, from 134 agencies in 23 departments and from several years), by
running the Actor's own row builder over
them (`research/fill/fill-rates.json`); amounts count when above zero. Forecasts have no close date yet: they carry the
estimated post, close and award dates and the fiscal year instead.
The sample spreads over agencies and years; the 300 newest open opportunities of one real run (7kMwWCHPRCZCLpiyg,
2026-10-10: 193 posted, 107 forecasted) differ: posted close date 99%, award ceiling 76%, attachments 65%, application
packages 90%, contact e-mail 98%; forecasted estimated close date 91%, estimated award date 97%, award ceiling 43%,
attachments 1%.

| Field | What it is | Filled (posted / forecasted / closed / archived) |
|---|---|---|
| `opportunityId`, `opportunityNumber`, `title`, `url` | identity and the public Grants.gov page | 100% |
| `status`, `documentType`, `fundingType` | forecasted, posted, closed or archived; synopsis or forecast; discretionary, mandatory and so on | 100% |
| `agencyCode`, `agencyName`, `topAgencyCode`, `topAgencyName` | the posting agency and its department | 100% |
| `postedDate`, `closeDate`, `daysUntilClose`, `archiveDate`, `originalCloseDate` | dates as YYYY-MM-DD (US Eastern) | close date 86% / 0% / 100% / 97% |
| `estimatedPostDate`, `estimatedCloseDate`, `estimatedAwardDate`, `estimatedProjectStartDate`, `fiscalYear` | forecast dates | forecasts: close 88%, award 55% |
| `awardCeiling`, `awardFloor` | the largest and smallest single award, in US dollars (numbers) | ceiling 74% / 65% / 90% / 87%, floor 50% / 48% / 73% / 63% |
| `estimatedTotalFunding`, `expectedNumberOfAwards` | program size | funding 44% / 68% / 53% / 53%, awards 68% / 75% / 70% / 77% |
| `costSharing` | whether cost sharing or matching is required | 100% |
| `fundingInstruments`, `fundingCategories`, `eligibleApplicants` (with `...Codes`) | Grants.gov's own names and codes | 100% |
| `eligibilityText` | the agency's additional eligibility text | 68% / 83% / 57% / 70% |
| `assistanceListings`, `assistanceListingNumbers` | Assistance Listing (CFDA) numbers and program titles | 98% / 100% / 100% / 97% |
| `description` | the synopsis or forecast text, as plain text | 100% |
| `contactName`, `contactDetails`, `contactEmail`, `contactPhone` | the agency contact | e-mail 94% / 100% / 80% / 97% |
| `attachments`, `attachmentCount` | every file with folder, name, type, size and download link | 82% / 33% / 70% / 83% |
| `applicationPackages` | package and competition ids, opening and closing dates | 64% / 0% / 3% / 0% |
| `relatedOpportunities` | linked opportunities | 4% / 5% / 10% / 0% |
| `revision`, `versionsInHistory`, `lastUpdatedAt`, `lastChangeComment` | the amendment count and the last change | revision 100%, last update 100% / 100% / 100% / 80%, comment 52% / 23% / 67% / 30%, history 54% / 20% / 57% / 30% |
| `monitorChange` | with a monitor: new or revised | monitor runs |

A shortened real row (posted 2026-10-09):

```json
{
  "type": "opportunity",
  "opportunityId": "360905",
  "opportunityNumber": "RFA-CA-28-013",
  "title": "Carcinogen Hazard Assessment Monographs Program (CHAMP) (R01 Clinical Trial Not Allowed)",
  "url": "https://www.grants.gov/search-results-detail/360905",
  "status": "posted",
  "agencyName": "National Institutes of Health",
  "topAgencyName": "Department of Health and Human Services",
  "postedDate": "2026-10-09",
  "closeDate": "2027-02-09",
  "awardCeiling": 700000,
  "awardFloor": 700000,
  "estimatedTotalFunding": 800000,
  "expectedNumberOfAwards": 1,
  "costSharing": false,
  "fundingInstruments": ["Grant"],
  "fundingCategories": ["Health"],
  "assistanceListingNumbers": ["93.393", "93.396", "93.399"],
  "contactEmail": "ncidccpsegrpnofos@mail.nih.gov",
  "attachmentCount": 1,
  "revision": 3,
  "lastUpdatedAt": "2026-10-09T08:47:44-04:00"
}
```

Other rows in the same dataset: `revision` (one amendment, free, only when Revision rows is on), `searchResult` (the
short list row, when Full records is off), `status` (a miss, an empty search or a stop, free) and one `summary` at the end
(counters, coverage, billing and the Grants.gov notice). The dataset has three views: Opportunities, Revisions and Status
rows.

### How much does it cost to scrape Grants.gov?

You pay per opportunity delivered, plus a small fee per run. Misses, empty searches, records that fail your filters,
revision rows and status rows are free; a run that delivers nothing costs only its start fee (charged once more if you
resurrect the run).

| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| Opportunity (a full record) | $0.69 / 1,000 | $0.69 / 1,000 | $0.59 / 1,000 | $0.49 / 1,000 |
| Search result (a list row, full records off) | $0.20 / 1,000 | $0.20 / 1,000 | $0.18 / 1,000 | $0.16 / 1,000 |
| Actor start (once per run, and once more if you resurrect it) | $0.0025 | $0.0025 | $0.0025 | $0.0025 |

Platinum and Diamond plans pay the Gold price. The Actor start fee has no plan discount. The Store pricing card shows
these same prices per 1,000 events: "$0.69 / 1,000" on the Opportunity row means one opportunity costs 0.069 cents.

Examples at the Bronze price: the 100 newest open opportunities cost $0.0715; all open opportunities as full records
(about 1,500) about $1.04; a daily monitor that finds 10 new opportunities $0.0094 a day; 10,000 list rows $2.0025.

### Input

| Field | What it does |
|---|---|
| `keyword` | Grants.gov keyword search: words joined with OR, `AND`, "exact phrase", `-word`, `wild*` |
| `statuses` | forecasted, posted, closed, archived (empty: forecasted and posted) |
| `agencies` | agency codes: a department (HHS) includes its sub agencies, a sub agency (HHS-NIH11) is that one; checked against Grants.gov's list |
| `fundingCategories`, `fundingInstruments`, `eligibleApplicants` | Grants.gov's codes, matched when the opportunity carries any of them |
| `assistanceListings` | Assistance Listing (CFDA) numbers such as 93.866 |
| `postedWithinDays` or `postedFrom` / `postedTo` | posted date window (US Eastern dates) |
| `closingWithinDays` or `closingFrom` / `closingTo` | close date window; forecasts have no close date and are left out |
| `minAwardCeiling` | minimum award ceiling in US dollars, checked on the full record |
| `sortBy` | newest (default), oldest, closingSoonest, closingLatest, agency, title, number |
| `opportunities` | lookup: opportunity numbers, ids or Grants.gov links (search fields are left aside) |
| `includeDetails` | full records (default) or the short list row |
| `includeRevisionHistory` | adds the free revision rows |
| `maxItems` | the most paid rows one run delivers (default 100) |
| `monitorName` | remembers what this search delivered; later runs deliver only new and amended opportunities |

Every value is checked before any opportunity is read: an unknown field, a date that does not exist, a code Grants.gov
does not use (agency codes are checked against Grants.gov's own list) or a number in the wrong form stops the run with a
free status row that names the problem.

#### How the monitor works

Give a search a monitor name and schedule it. The first run delivers what the search finds. Every later run walks the
whole search again (the open opportunities are two list calls) and delivers, and charges for, only the opportunities that
are new to the monitor, or whose list row changed (status, close date, number, title or posted date) and whose record
Grants.gov amended to a higher revision. A forecast that becomes posted, an extended deadline and a renumbered
opportunity are delivered with `monitorChange: "revised"`; a deadline that passes (posted to closed) is not an amendment
and is not delivered. A monitor name belongs to one search: the same name with other settings gets a free status row.
The monitor watches at most 20,000 opportunities (the open ones are about 1,500) and never forgets an opportunity it
delivered, so it never bills the same version twice; its memory holds up to 60,000 opportunities.

### What this Actor does NOT do

- It does not see amendments that change only the text or the amounts of an opportunity in a monitor run: those show up
  in the record's revision history the next time it is delivered, or in a run without a monitor.
- It does not download attachment files: each attachment carries its direct download link and the folder's zip link.
- It does not score how well an opportunity fits you, and it calls no AI model: it delivers the record as Grants.gov
  publishes it.
- It does not cover private foundations, state grant portals or SAM.gov contract opportunities: only Grants.gov.
- It does not use the Simpler.Grants.gov API, which needs a personal API key.
- It does not order results by award ceiling, award floor or relevance: it offers the sort keys of the Grants.gov API
  (posted date, close date, agency, title, number), and every row carries the amounts to sort on.
- It has no webhook input: Apify's own run webhooks and integrations send the results wherever you want.
- It has no cost sharing filter and no maximum award filter: Grants.gov cannot filter on either, and every row carries
  `costSharing`, `awardCeiling` and `awardFloor` to filter on.
- It does not hide the agency contact: `contactName`, `contactDetails`, `contactEmail` and `contactPhone` are the public
  points of contact the agency publishes with each opportunity, and some name a person.

### API examples

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~grants-gov-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keyword": "rural broadband", "statuses": ["posted"], "maxItems": 20}'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('automation_craft/grants-gov-scraper').call({ agencies: ['HHS-NIH11'], closingWithinDays: 30 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation_craft/grants-gov-scraper").call(run_input={"opportunities": ["PAR-25-274", "357305"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

### FAQ

#### Do I need a Grants.gov API key or account?

No. The Actor reads the official Grants.gov API endpoints that need no key and no login. You only need an Apify account.

#### How do I get alerts for new federal grants?

Save your search as a task with a monitor name and schedule it (daily, for example). Each run delivers only the
opportunities that are new or amended since the last run, so an Apify integration (Slack, e-mail, Google Sheets, a
webhook) receives just those.

#### Can I search by CFDA or Assistance Listing number?

Yes. Put the numbers (for example 93.866) in Assistance Listing numbers. Grants.gov's documented `aln` parameter is
ignored by its own API; this Actor sends the parameter that works and checks every row against your numbers.

#### Is there a limit on how many opportunities I can export?

Grants.gov sets no limit: its search returns every match. Set Maximum opportunities to what you need (up to 100,000 per
run); list rows are the fastest way to export many opportunities, and a large export can be split by status or posted
date. The largest runs tested on the platform delivered 600 list rows in 2 seconds and 300 full records in 64 seconds.

#### Which grants close soon?

Set Closing within the next N days (30, for example) and the order Closing soonest first. Every row also carries
`daysUntilClose`.

#### Why does this Actor run with limited permissions?

It needs nothing beyond its own storage: it reads the public Grants.gov API, writes to its own dataset and, when you give
a monitor name, keeps that monitor's memory in a named key-value store it creates itself. Limited permissions are the
least privilege that does that.

### Changelog

- 0.1 (2026-10-11): the Opportunity price is 0.69 / 0.69 / 0.59 / 0.49 per 1,000 (Free / Bronze / Silver / Gold).
- 0.1 (2026-10-10): first release.

### More data tools by Automation Craft

- [SEC Form D Scraper: Offerings & Funding Leads](https://apify.com/automation_craft/sec-form-d-scraper)
- [UK Find a Tender Scraper: Tenders, Awards, Buyers](https://apify.com/automation_craft/uk-find-a-tender-scraper)
- [UK Contracts Finder Scraper: Tenders & Awards](https://apify.com/automation_craft/uk-contracts-finder-scraper)
- [US New Business Registrations Scraper - LLC Leads](https://apify.com/automation_craft/us-new-business-registrations-scraper)
- [US Building Permits Scraper - 38 City Sources](https://apify.com/automation_craft/us-building-permits-scraper)
- [UK Food Hygiene Ratings Scraper - FSA Register](https://apify.com/automation_craft/uk-food-hygiene-ratings-scraper)
- [Yahoo Finance Scraper: Quotes, History, Financials](https://apify.com/automation_craft/yahoo-finance-scraper)
- [Google News Scraper: Search, Topics, Decoded URLs](https://apify.com/automation_craft/google-news-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation_craft/grants-gov-scraper/changelog.md

# Actor input Schema

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

Words to search for, as on Grants.gov: words separated by spaces match ANY of them, AND between words matches all, a phrase in double quotes matches exactly, a minus excludes a word (water -quality), a star matches a word start (wat\*). Grants.gov searches the title, the description, the eligibility text and the Assistance Listing titles. Example: "rural broadband". Left empty: no keyword.

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

Which opportunities to include. Left empty: forecasted and posted (the open ones, about 1,500). Closed and archived reach back to 2004 (about 82,000).

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

Agency codes as Grants.gov lists them. A department code (HHS, DOE, NSF) includes all its sub agencies; a sub agency code (HHS-NIH11, DOE-ID) means that one only. Codes are checked against Grants.gov's own agency list; an unknown code stops the run with a free row that says so. Example: HHS-NIH11.

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

Categories of funding activity. An opportunity matches when it carries ANY of the chosen categories.

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

Grant, cooperative agreement, procurement contract or other. An opportunity matches when it carries ANY of the chosen instruments.

## `eligibleApplicants` (type: `array`):

Who may apply. An opportunity matches when it names ANY of the chosen applicant types. Unrestricted opportunities carry their own type (Unrestricted).

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

Assistance Listing numbers, formerly CFDA numbers, written NN.NNN (a few carry letters, such as 93.T21). Example: 93.866. An opportunity matches when it lists ANY of them.

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

Only opportunities posted on or after the date N days before the run's date (US Eastern; a forecast counts from the day it was announced). Use this or the two posted dates below, not both.

## `postedFrom` (type: `string`):

Earliest posted date, YYYY-MM-DD.

## `postedTo` (type: `string`):

Latest posted date, YYYY-MM-DD.

## `closingWithinDays` (type: `integer`):

Only opportunities whose application due date is between today and today plus N days (0 means closing today). Forecasts carry no close date, so this leaves them out. Use this or the two closing dates below, not both.

## `closingFrom` (type: `string`):

Earliest application due date, YYYY-MM-DD.

## `closingTo` (type: `string`):

Latest application due date, YYYY-MM-DD.

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

Only opportunities whose largest single award (award ceiling) is at least this many US dollars. Checked on the full record: opportunities without a stated ceiling are left out, and records that do not pass are not charged.

## `sortBy` (type: `string`):

The order in which opportunities are read and delivered. Left empty: newest posted first.

## `opportunities` (type: `array`):

Opportunity numbers (PAR-25-274, HHS-2026-ACF-OCS-EE-0001), Grants.gov ids (357305) or Grants.gov links. Numbers are matched exactly and are case sensitive; a number shared by several opportunities returns each of them. An id or number Grants.gov does not have gets a free status row.

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

On: every opportunity is delivered as its full record (amounts, eligibility, description, contacts, attachments, packages, version count), one Opportunity event each. Off: the short list row only (id, number, title, agency, status, dates, Assistance Listings), one cheaper Search result event each. Left empty: on.

## `includeRevisionHistory` (type: `boolean`):

Adds one free row per amendment Grants.gov keeps in the record's history: which fields changed between two revisions, before and after, with the agency's comment. Needs full records.

## `maxItems` (type: `integer`):

The most paid rows (opportunities or search results) one run delivers. Left empty: 100. All open opportunities are about 1,500; the whole archive about 83,500.

## `monitorName` (type: `string`):

Give a name to remember what this search delivered. Each later run with the same name delivers, and charges for, only opportunities that are new to it, or that Grants.gov amended to a higher revision with a change in the status, close date, number, title or posted date. A deadline that passes is not an amendment, and an opportunity it delivered is never forgotten. One name belongs to one search (the same settings); a monitor works with full records.

## Actor input object example

```json
{
  "keyword": "health",
  "statuses": [
    "posted"
  ],
  "includeDetails": true,
  "maxItems": 10
}
```

# Actor output Schema

## `items` (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 = {
    "keyword": "health",
    "statuses": [
        "posted"
    ],
    "includeDetails": true,
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/grants-gov-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 = {
    "keyword": "health",
    "statuses": ["posted"],
    "includeDetails": True,
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/grants-gov-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 '{
  "keyword": "health",
  "statuses": [
    "posted"
  ],
  "includeDetails": true,
  "maxItems": 10
}' |
apify call automation_craft/grants-gov-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/grants-gov-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/aeSgvbsDF47gUBsPf/builds/3SvM49elCejUaSOAK/openapi.json
