# NIH RePORTER Funded Projects Scraper (`knotty_mistveil/nih-reporter-projects`) Actor

NIH-funded research projects from the official NIH RePORTER Project API v2: award amount, dates, PIs, program officer, institution and NIH institute.

- **URL**: https://apify.com/knotty\_mistveil/nih-reporter-projects.md
- **Developed by:** [Jason](https://apify.com/knotty_mistveil) (community)
- **Categories:** Business, Lead generation, Education
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 project returneds

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?

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

## NIH RePORTER Funded Projects Scraper

Pulls US National Institutes of Health research awards from **NIH RePORTER**, the official public
record of NIH- and HHS-funded projects, through its documented **Project API v2**. No API key, no
account, no browser automation. You get one flat JSON record per project with the project and core
project numbers, the funding institute or center, the activity code and award type, the award amount
and fiscal year, the award-notice, start and end dates, the recipient organisation with its city,
state and country, the contact principal investigator and every listed PI, the NIH program officer,
the assigned index terms and the project abstract - filtered by fiscal year, award-notice-date
window, activity code, NIH institute, organisation name or state, principal-investigator name,
keyword and minimum award. On 10 September 2026 the API held **61,703 FY2026 projects** and
**76,326 FY2025 projects**, with **11,583** award notices in the last 30 days.

### What you get

Every record contains:

| Field | Description |
| --- | --- |
| `id` | NIH application id, e.g. `11443962` - the number that keys the public project page |
| `source` | `nih-reporter`, constant |
| `url` | `https://reporter.nih.gov/project-details/{id}` - the public project page |
| `projectNumber` | Full NIH project (application) number, e.g. `1R01MD021856-01` |
| `coreProjectNumber` | Core project number shared across a grant's years, e.g. `R01MD021856` |
| `title` | Project title |
| `fiscalYear` | NIH fiscal year of the award, e.g. `2026` |
| `awardAmount` | Total funding awarded for the fiscal year, in USD, or `null` when NIH published none |
| `awardNoticeDate` | Date the Notice of Award was issued, `YYYY-MM-DD` |
| `projectStartDate` / `projectEndDate` | Project budget-period start and end, `YYYY-MM-DD` |
| `activityCode` | NIH activity code, e.g. `R01`, `R21`, `U01`, `K99` |
| `awardType` | NIH application type code: `1` new, `2` competing renewal, `3` supplement, `4` extension, `5` non-competing continuation, `7` change of institution, `9` transfer |
| `agency` | Administering NIH institute or center abbreviation, e.g. `NCI`, `NIMHD`, `NHLBI` |
| `contactPiName` | The contact principal investigator's full name |
| `allPiNames` | Every listed principal investigator's full name (array) |
| `programOfficerName` | The NIH program officer named on the award, or `null` |
| `organizationName` | Recipient organisation name, e.g. `UNIVERSITY OF HAWAII AT MANOA` |
| `orgCity` / `orgState` / `orgCountry` | Organisation location (state is a US state or foreign province code) |
| `departmentType` | The organisation's department type, e.g. `ANATOMY/CELL BIOLOGY` |
| `terms` | NIH-assigned index terms, first 50, as an array |
| `abstract` | The project abstract, whitespace-normalised and trimmed to 2,000 characters |
| `fetchedAt` | ISO timestamp of the run that produced the record |

The dataset has three views: **Overview** (dates, project number, institute, award, organisation,
contact PI), **Investigators and institutions** (all PIs, program officer, full organisation and
department) and **Funding and terms** (activity code, award type, amount, fiscal year, dates, terms).

### Input

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `fiscalYears` | string\[] | current FY | NIH fiscal years to include (FY starts 1 October, so FY2026 = 1 Oct 2025 - 30 Sep 2026). Empty = all years. |
| `daysBack` | integer | `30` | Look-back window in days on the award-notice date, ending today. Ignored when `dateFrom`/`dateTo` are set. |
| `dateFrom` | string | - | Start of the award-notice-date window, `YYYY-MM-DD`, inclusive. Overrides `daysBack`. |
| `dateTo` | string | today | End of the award-notice-date window, `YYYY-MM-DD`, inclusive. |
| `activityCodes` | string\[] | all | NIH activity codes such as `R01`, `R21`, `U01`, `K99`. A project is kept when its code matches any. |
| `agencies` | string\[] | all | Administering institute/center abbreviations, e.g. `NCI`, `NIAID`, `NHLBI`, `NIMHD`, `NIGMS`. |
| `orgStates` | string\[] | all | Two-letter organisation state or province codes, e.g. `CA`, `NY`, `MA`. |
| `orgNames` | string\[] | all | Organisation name fragments, matched as a case-insensitive substring, e.g. `stanford`, `johns hopkins`. |
| `piNames` | string\[] | all | Principal-investigator name fragments, matched by NIH's own any-name search, e.g. `smith`. |
| `keywords` | string\[] | none | Words searched across title, index terms and abstract. See `keywordsOperator`. |
| `keywordsOperator` | string | `and` | `and` = every keyword word must appear; `or` = any word matches. |
| `minAward` | integer | - | Keep only projects whose award is at least this many USD. Projects with no published amount are excluded when set. |
| `maxItems` | integer | `500` | Stop after this many projects. You are charged per project, so this is also the cost cap. Newest award-notice date first, so a value below the window's volume drops the **oldest** projects in the window. |

Example - the last 90 days of NCI cancer R01 awards to California institutions:

```json
{
  "fiscalYears": ["2026"],
  "daysBack": 90,
  "activityCodes": ["R01"],
  "agencies": ["NCI"],
  "orgStates": ["CA"],
  "keywords": ["cancer"],
  "maxItems": 500
}
```

Example - every award a named investigator or institution received this fiscal year:

```json
{ "fiscalYears": ["2026"], "daysBack": 366, "orgNames": ["stanford"], "piNames": ["smith"], "maxItems": 500 }
```

Bad input fails fast: an invalid fiscal year, activity code, institute abbreviation, state code or
malformed date stops the run with the validation message as its status, before any request is made.

### Output example

A real record from a live run on 10 September 2026 (`{"activityCodes": ["R01"], "daysBack": 14, "maxItems": 5}`),
with `terms` and `abstract` shortened here for length (the record ships all 50 terms and the full
2,000-character abstract):

```json
{
  "id": "11443962",
  "source": "nih-reporter",
  "url": "https://reporter.nih.gov/project-details/11443962",
  "projectNumber": "1R01MD021856-01",
  "coreProjectNumber": "R01MD021856",
  "title": "Aina-Based Engagement and Social Epigenomic Pathways to Metabolic Health in Native Hawaiian Youth",
  "fiscalYear": 2026,
  "awardAmount": 712197,
  "awardNoticeDate": "2026-09-05",
  "projectStartDate": "2026-09-05",
  "projectEndDate": "2031-05-31",
  "activityCode": "R01",
  "awardType": "1",
  "agency": "NIMHD",
  "contactPiName": "Alika Keolaokalani Maunakea",
  "allPiNames": ["Ruben Juarez", "Alika Keolaokalani Maunakea"],
  "programOfficerName": "NATHANIEL STINSON",
  "organizationName": "UNIVERSITY OF HAWAII AT MANOA",
  "orgCity": "HONOLULU",
  "orgState": "HI",
  "orgCountry": "UNITED STATES",
  "departmentType": "ANATOMY/CELL BIOLOGY",
  "terms": ["(TNF)-α", "12-20 years old", "16S RNA sequencing", "type 2 diabetes", "Native Hawaiian", "..."],
  "abstract": "PROJECT SUMMARY/ABSTRACT Native Hawaiians and other Pacific Islanders (NHPIs) experience among the highest rates of type 2 diabetes mellitus (DM) in the United States, with onset nearly a decade earlier than other groups. …",
  "fetchedAt": "2026-09-10T14:07:37.221Z"
}
```

Every run also writes a `SUMMARY` record to the key-value store with the resolved award-notice-date
window, the filters used, how many pages were read, the reported total, and the two completeness
flags `limitReached` and `windowExhausted` (see *Limits and freshness*).

### Pricing

Pay per result: **US$0.003 per project delivered** (US$3 per 1,000 projects). You are charged only
for records pushed to the dataset; a run that returns nothing costs nothing. Runs on the Apify free
plan are limited by the platform's free-tier usage allowance.

### Data source and licence

- Endpoint: `POST https://api.reporter.nih.gov/v2/projects/search`. It is public and needs no
  authentication or account. Documentation: <https://api.reporter.nih.gov/> and the Data Elements
  guide at <https://api.reporter.nih.gov/documents/Data%20Elements%20for%20RePORTER%20Project%20API_V2.pdf>
  (both read 10 September 2026).
- **Licence.** NIH RePORTER is produced by the National Institutes of Health, a US federal agency, as
  part of its official duties. Its content is a US Government work, not subject to domestic copyright
  under 17 U.S.C. § 105, and free to reuse - including commercially. NIH's RePORTER FAQ states the
  records are in the public domain. Attribute as "Source: NIH RePORTER" and link to the project page;
  do not imply NIH endorsement, and do not use NIH names or logos to suggest one. Read 10 September 2026.
- **Rate limits and courtesy.** The API guide asks users to "post no more than one URL request per
  second" and to run large jobs off-peak (weekends, or weekday nights 21:00-05:00 US Eastern), and
  warns that abusive rates may lead to an IP block. This Actor paces its paging to roughly one request
  a second and retries `429`/`5xx` responses with exponential back-off. Read 10 September 2026.
- **Personal data.** `contactPiName`, `allPiNames` and `programOfficerName` are the names of the
  researchers and NIH staff associated with each award. They are public research records that NIH
  publishes so the funded work is transparent and accountable; the API returns no email addresses or
  phone numbers. Use them for legitimate research and business development (competitive intelligence,
  collaboration mapping, market sizing) - not for spam. Downstream contact, marketing in particular,
  is the buyer's responsibility under the applicable regime (CAN-SPAM in the US, GDPR/PECR if you are
  contacting from or into the EU/UK). Investigators' names also appear in `abstract`.

### Limits and freshness

- **Volumes, measured 10 September 2026** by querying the API: FY2026 held **61,703** projects and
  FY2025 held **76,326**. Award notices issued in the last **30 days** numbered **11,583** (all
  activity codes), the last **7 days** **1,154**, and the last 30 days of **R01** awards **3,373**.
  FY2026 NCI held **8,387** projects. So the default run (current fiscal year, all activity codes,
  30-day award-notice window) returns about 11,600 projects - well above the default `maxItems` of
  500, which keeps the newest 500. Raise `maxItems` and narrow the window to pull a full window.
- **Size `maxItems` to the window, and check `windowExhausted`.** The stream is newest-first on the
  award-notice date, so a `maxItems` below the window's volume drops the **oldest** projects in it -
  but never silently. The run stops the moment the cap is filled, warns `maxItems (N) reached before
  every matching project was returned`, and the `SUMMARY` record carries `limitReached: true` with
  `windowExhausted: false`. `windowExhausted: true` is the guarantee that you hold the complete set:
  it is set only when the API ran out of matching results with every kept record delivered.
- **The API pages only to its first 15,000 matches.** An `offset` above 14,999 is refused with HTTP
  400 ("System doesn't support offset value greater than 14,999", verified 10 September 2026). This
  Actor never asks for a deeper page: when a filter matches more than 15,000 projects it stops at the
  ceiling, warns `NIH RePORTER stops paging at offset 14999`, and reports `windowExhausted: false`.
  A whole fiscal year (60,000-76,000 projects) is therefore not reachable in one run - split it by
  award-notice-date window (each 30-day window is ~12,000, comfortably under the ceiling) or by
  institute or activity code.
- **Speed, measured 10 September 2026** on this machine: 500 projects in **7.5 s** (one page), 1,500
  projects in **13.7 s** (three pages, including the ~1.1 s pause between pages). Most of a small run
  is SDK start-up and writing one dataset file per record.
- **Paging.** Results come 500 rows per request (the API's maximum), sorted by award-notice date
  descending; paging stops as soon as the API runs out of results, `maxItems` is filled, or the
  offset ceiling is reached - so a capped run never fetches a page it cannot deliver.
- **Filtering is server-side.** Fiscal year, award-notice window, activity code, institute,
  organisation name and state, PI name, keyword and minimum award are all applied by the API, so a
  filtered run reads only matching rows. The minimum-award filter uses the API's amount range with
  `has_value: true` (the API ignores a lone minimum), so it also drops projects that publish no
  award amount. Keywords are combined with AND by default (every word must appear across the title,
  index terms and abstract); set `keywordsOperator` to `or` to match any word.
- **Freshness.** Awards are issued on business days. Measured 10 September 2026, the newest
  award-notice date in the API was **2026-09-05**. RePORTER is updated as awards are processed and a
  project's record is revised in place across its budget years, so run an overlapping window
  (`daysBack: 3` daily) rather than one that exactly abuts the previous run. Dates are calendar dates
  as NIH publishes them, with no time component.

### Use cases

- **Research-funding intelligence and market sizing:** track new awards by institute, activity code,
  organisation or state - with the award amount, fiscal year and project dates already on the record -
  to size a therapeutic area, watch a competitor's grant pipeline, or map who funds what.
- **Business development for CROs, vendors and core facilities:** find newly funded labs by activity
  code and institution the week the award notice posts, with the contact PI and their department, to
  reach principal investigators with fresh budgets.
- **Collaboration and expertise mapping:** pull every award to a named investigator or institution,
  or every project matching a set of scientific keywords, to build co-investigator networks, find
  reviewers, or assemble a landscape review from the abstracts and index terms.

### Support

Open an issue on the Actor's Issues tab on Apify Store. Replies within 14 days. Bug reports that name
the run id and the input used are fixed fastest.

# Actor input Schema

## `fiscalYears` (type: `array`):

NIH fiscal years to include (a fiscal year starts on 1 October, so FY2026 runs 1 Oct 2025 - 30 Sep 2026). Leave empty to search every year. Default: the current fiscal year.

## `daysBack` (type: `integer`):

Look-back window in days on the award notice date, ending today. Ignored when Date from / Date to are set.

## `dateFrom` (type: `string`):

Start of the award-notice-date window, YYYY-MM-DD (inclusive). Overrides Days back.

## `dateTo` (type: `string`):

End of the award-notice-date window, YYYY-MM-DD (inclusive). Defaults to today.

## `activityCodes` (type: `array`):

NIH activity codes, e.g. R01, R21, U01, K99, F31, T32, P30. Empty = all. A project is kept when its activity code matches any of these.

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

Administering institute or center abbreviations, e.g. NCI, NIAID, NHLBI, NIMHD, NIGMS, NIA, NIMH, NINDS, NIDDK. Empty = all of NIH and the other agencies RePORTER indexes.

## `orgStates` (type: `array`):

Two-letter state or province codes of the recipient organisation, e.g. CA, NY, MA, TX. Empty = all locations.

## `orgNames` (type: `array`):

Recipient organisation name fragments, matched as a case-insensitive substring, e.g. stanford, harvard, "johns hopkins". Empty = all organisations.

## `piNames` (type: `array`):

Principal investigator name fragments (first, last or full name), matched by NIH's own any-name search, e.g. smith, "jane doe". Empty = all investigators.

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

Words searched across the project title, NIH index terms and abstract. By default every word must appear somewhere in those fields (see Keyword match). A phrase in one entry is searched as its separate words. Empty = no keyword filter.

## `keywordsOperator` (type: `string`):

How multiple keyword words combine. AND keeps a project only when every word appears; OR keeps it when any word appears.

## `minAward` (type: `integer`):

Keep only projects whose award amount is at least this many US dollars. Projects with no published award amount are excluded when this is set. Empty = no minimum.

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

Stop after this many projects. You are charged per project delivered, so this is also the cost cap. Newest award-notice date first, so a value below the window's volume drops the OLDEST projects in the window. The API can be paged only to its first 15,000 matches; narrow the window or fiscal years to reach more.

## Actor input object example

```json
{
  "fiscalYears": [
    "2026"
  ],
  "daysBack": 30,
  "activityCodes": [],
  "agencies": [],
  "orgStates": [],
  "orgNames": [],
  "piNames": [],
  "keywords": [],
  "keywordsOperator": "and",
  "maxItems": 500
}
```

# Actor output Schema

## `results` (type: `string`):

All projects returned by the run, one JSON object each. Append ?format=csv or ?format=xlsx to download a spreadsheet.

## `summary` (type: `string`):

Counts, the award-notice-date window used, the filters applied, the number of pages read and the completeness flags, written at the end of the 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 = {
    "fiscalYears": [
        "2026"
    ],
    "daysBack": 30,
    "activityCodes": [],
    "agencies": [],
    "orgStates": [],
    "orgNames": [],
    "piNames": [],
    "keywords": [],
    "keywordsOperator": "and",
    "maxItems": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("knotty_mistveil/nih-reporter-projects").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 = {
    "fiscalYears": ["2026"],
    "daysBack": 30,
    "activityCodes": [],
    "agencies": [],
    "orgStates": [],
    "orgNames": [],
    "piNames": [],
    "keywords": [],
    "keywordsOperator": "and",
    "maxItems": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("knotty_mistveil/nih-reporter-projects").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 '{
  "fiscalYears": [
    "2026"
  ],
  "daysBack": 30,
  "activityCodes": [],
  "agencies": [],
  "orgStates": [],
  "orgNames": [],
  "piNames": [],
  "keywords": [],
  "keywordsOperator": "and",
  "maxItems": 500
}' |
apify call knotty_mistveil/nih-reporter-projects --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,knotty_mistveil/nih-reporter-projects"
        }
    }
}
```

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/KmRujA0FRoRnwTYMg/builds/MsSYgaypeKcySNZIg/openapi.json
