# Grants.gov Funding Opportunity Search (`gubidonius/grants-gov`) Actor

Searches US federal funding opportunities on Grants.gov and returns the agency contact, the award amounts and the real closing date. Grants.gov keeps two records per opportunity and the older one often has the higher version, so every row says which one its deadline came from.

- **URL**: https://apify.com/gubidonius/grants-gov.md
- **Developed by:** [Gregory Bolshakov](https://apify.com/gubidonius) (community)
- **Categories:** Business, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

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 Funding Opportunity Search

Searches US federal funding opportunities on Grants.gov. You get the closing date, the award
amounts, the eligibility codes and the name, email and phone of the person at the agency who
runs the opportunity, as JSON, CSV or Excel.

No API key and no login. The data is public and this Actor reads it directly.

### What is different here

Grants.gov keeps two records for one opportunity. A forecast, which is a plan, and a
synopsis, which is the real posted opportunity. They carry separate version numbers, and the
forecast usually has the higher one even though the synopsis replaced it.

So if you take the newest version, you get the forecast. Forecasts often carry no closing
date at all, so you end up with an empty deadline for an opportunity that has a real one, and
nothing looks broken.

I checked this on live data. In 150 opportunities, 10 held both records and the forecast
outranked the synopsis on version in 5 of them. This Actor picks by which record is real, not
by which number is bigger, and every row carries `closeDateSource` so you can see which one
it used.

The contact details are the second thing. They exist only on the per opportunity endpoint,
not in search results, so a scraper that reads only the search misses them. All 150
opportunities had a contact email.

### Dates

Closing dates come back as `YYYY-MM-DD` with the timezone in its own column. Grants.gov
stamps them US Eastern and mixes EST and EDT inside one answer, so reading them as UTC moves
a deadline by four or five hours. On the last day that matters.

A forecasted opportunity with no date published gets `none-published` rather than a date
borrowed from somewhere else.

### Status matters more than you would think

`archived` is a much bigger bucket than the rest. A search for water returns about 500 posted
and forecasted opportunities and over 16,000 once you add archived. Pick the statuses you
actually want.

### Completeness

Grants.gov publishes an exact match count, so every row carries `searchMatched`,
`searchRowsReturned` and `searchComplete`. If you asked for fewer rows than exist,
`searchLimitedBy` says `maxResults` rather than pretending the answer is whole.

### Cost

Pay per event, priced on the Actor page. A search matching nothing is free, because nothing
is charged until rows are written to your dataset.

# Actor input Schema

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

Free text searched across opportunity titles and descriptions. Leave empty to return everything matching the other filters.

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

Which stages to include. Forecasted opportunities are plans and usually have no closing date yet. Archived is by far the largest bucket, tens of thousands against hundreds posted, so adding it changes the size of the answer completely.

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

Pipe separated Grants.gov agency codes, for example HHS-NIH11. Leave empty for all agencies.

## `eligibilities` (type: `string`):

Pipe separated Grants.gov eligibility codes, for example 25 for nonprofits with 501(c)(3) status.

## `fundingCategories` (type: `string`):

Pipe separated Grants.gov funding activity category codes, for example HL for health.

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

Stop after this many. Being stopped here is reported as maxResults, which is not the same as the search running out.

## `includeDescription` (type: `boolean`):

The full synopsis text. It is long, so turn it off if you only want the structured fields.

## `onlyNewSinceLastRun` (type: `boolean`):

Returns only opportunities not seen on the previous run of this same search. The first run records a baseline and returns everything with isNew empty, because nothing has been seen yet to compare against.

## Actor input object example

```json
{
  "keyword": "cancer research",
  "statuses": [
    "forecasted",
    "posted"
  ],
  "maxResults": 500,
  "includeDescription": true,
  "onlyNewSinceLastRun": false
}
```

# Actor output Schema

## `results` (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": "cancer research"
};

// Run the Actor and wait for it to finish
const run = await client.actor("gubidonius/grants-gov").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": "cancer research" }

# Run the Actor and wait for it to finish
run = client.actor("gubidonius/grants-gov").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": "cancer research"
}' |
apify call gubidonius/grants-gov --silent --output-dataset

```

## MCP server setup

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

```

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/eealOe0zg3ZrsPmLU/builds/g2UTBiCgUe4Klr3Gc/openapi.json
