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

Scrape US federal grant opportunities from grants.gov. Filter by keyword, agency, and status. Remembers what it already returned, so scheduled runs deliver only new grants instead of the same list every time.

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

## Pricing

from $4.00 / 1,000 grants

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/platform/actors/running/actors-in-store#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 — US Federal Grant Opportunities

Scrape US federal grant opportunities from **grants.gov**, the official government grant
database. Filter by keyword, agency, and opportunity status. Export to JSON, CSV, or Excel.

Unlike other grants.gov scrapers, this one **remembers what it already returned**. Schedule
it daily and you receive only the grants posted since your last run — not the same list
every morning with the diffing left to you.

### What this Actor does

- **Scrape federal grant opportunities** from the official grants.gov search API
- **Get only new grants** — built-in deduplication across scheduled runs
- **Filter grants by keyword**, so you see only funding matching your work
- **Filter by agency** — EPA, DOI, HHS, and any other agency code
- **Include forecasted grants** that are announced but not yet accepting applications
- **Drop expired opportunities** automatically

### Who uses this

- **Nonprofits and grant writers** tracking new funding opportunities in their field
- **Researchers** monitoring agency funding calls
- **Small businesses** looking for federal assistance programmes
- **AI agents** that need federal grant data as a callable tool

### Example output

```json
{
  "uid": "9c4e1f70a2b83d55",
  "source": "grants.gov",
  "source_id": "363400",
  "title": "Water Quality Monitoring Grant",
  "buyer": "Environmental Protection Agency",
  "country": "US",
  "published": "2026-08-01",
  "deadline": "2026-10-15",
  "categories": ["66.419", "66.461", "EPA-R9-2026"],
  "url": "https://grants.gov/search-results-detail/363400"
}
```

### Input parameters

| Field | Meaning |
|---|---|
| `keywords` | Return grants matching any of these in the title or CFDA/opportunity numbers |
| `excludedKeywords` | Drop grants mentioning any of these |
| `statuses` | `posted`, `forecasted`, `closed`, `archived`. Default `posted` |
| `agencies` | Agency codes to restrict to, e.g. `EPA`, `DOI`, `HHS` |
| `onlyNew` | Return only grants not seen in previous runs. Default true |
| `includeExpired` | Keep grants whose close date has passed. Default false |
| `maxResults` | Cap on grants per run, and therefore on cost |

### How to monitor new grants daily

1. Set `keywords` to your field, for example `["water"]` or `["cybersecurity"]`
2. Leave `onlyNew` on
3. Schedule the Actor to run each morning
4. Connect the dataset to email, Slack, or a webhook

Each run delivers only opportunities posted since the last one.

### Behaviour worth knowing

**Award amounts and descriptions are always null.** grants.gov does not include them in
search results — they live on a separate detail endpoint that would require one extra
request per grant, multiplying both run time and cost. Follow the `url` for full details.

**Grants with no close date are kept.** Some opportunities publish none, and missing live
funding is worse than seeing one extra row.

**API errors are surfaced, not swallowed.** grants.gov answers with HTTP 200 even when it
rejects a request, so the Actor checks the error code in the body and logs the real reason
rather than reporting "no results".

**State commits only after delivery.** A run that fails before pushing results re-reports
them next time rather than losing them.

**Seen-state is forgotten after 180 days**, so stored state cannot grow without bound.

### Data source

[grants.gov search2 API](https://grants.gov/api/common/search2) — official, public, and
free. No key or authentication required, because its purpose is to expose publicly
available funding opportunities.

### Pricing

Pay per event: you are charged per grant delivered. A run that finds nothing new costs
nothing beyond platform compute. Cap your spend with `maxResults`.

### Development

```bash
python -m venv .venv
./.venv/bin/pip install pytest httpx
./.venv/bin/python -m pytest tests/ -q
```

Parsing, filtering, and deduplication are pure functions with no network access. Only
`src/main.py` touches the network.

# Actor input Schema

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

Return grants mentioning any of these terms in the title or CFDA/opportunity numbers. Leave empty to return everything matching the other filters.

## `excludedKeywords` (type: `array`):

Drop grants mentioning any of these terms.

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

Which opportunity states to include. Posted means open for application; forecasted means announced but not yet accepting.

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

Restrict to specific agency codes, e.g. EPA, DOI, HHS. Leave empty for all agencies.

## `onlyNew` (type: `boolean`):

Remember what previous runs returned and report only what is new. Leave on for scheduled monitoring; turn off to re-export everything matching your filters.

## `includeExpired` (type: `boolean`):

Keep grants you can no longer apply for. Off by default. Grants that publish no close date are always kept.

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

Caps how many grants one run returns, and therefore what it costs.

## Actor input object example

```json
{
  "keywords": [
    "water",
    "environment"
  ],
  "statuses": [
    "posted"
  ],
  "onlyNew": true,
  "includeExpired": false,
  "maxResults": 200
}
```

# Actor output Schema

## `grants` (type: `string`):

Every grant delivered by this run, as JSON. One record per opportunity, with agency, open and close dates, CFDA numbers, and a link to the full listing.

## `grantsCsv` (type: `string`):

The same grants as a CSV file, for opening in Excel or Google Sheets.

## `datasetView` (type: `string`):

Table view of the grants returned 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 = {
    "keywords": [
        "water",
        "environment"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fuyuki0/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 = { "keywords": [
        "water",
        "environment",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fuyuki0/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 '{
  "keywords": [
    "water",
    "environment"
  ]
}' |
apify call fuyuki0/grants-gov-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fuyuki0/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/OkWlhXput5O95Zps9/builds/rUZapQheC2qf9FCUA/openapi.json
