# NIH Grant Publication Linkage & Output Report (`taroyamada/nih-grant-publication-output-report`) Actor

Connect official NIH RePORTER grants to linked PubMed citations. Monitor new grant-publication links and generate source-linked research output portfolio reports and exports. Baseline and unchanged checks are free.

- **URL**: https://apify.com/taroyamada/nih-grant-publication-output-report.md
- **Developed by:** [naoki anzai](https://apify.com/taroyamada) (community)
- **Categories:** Business, Education
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 nih grant-publication link rows

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

## NIH Grant Publication Linkage & Output Report

Research offices, funders, and R\&D portfolio teams enter NIH core project numbers or bounded project searches.
The Actor connects official NIH RePORTER project records to the Publication API and optional PubMed citation metadata.
It returns source-linked linkage alerts, portfolio output reports, and exports; baseline and unchanged checks produce zero rows and zero charges.

### Store Quickstart

Start with a bounded value report. This example uses a public project identifier from NIH's API documentation and returns source-linked publication alerts, a portfolio report, and a reusable export. For a recurring schedule, switch the same watch to `baseline_only` after the first report.

```json
{
  "watches": [
    {
      "id": "nih-linked-publications",
      "coreProjectNumbers": ["UG1HD078437"]
    }
  ],
  "monitorKey": "nih-linked-publications",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": true,
  "emitUnchanged": false,
  "includePubMedMetadata": true,
  "maxProjectsPerWatch": 5,
  "maxPublicationsPerProject": 25,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

The report and export are the primary buyer deliverables; alerts explain the individual changed links. Repeat the same watch on a weekly schedule with `initialRunMode: "baseline_only"` for a free baseline, then receive only new or changed public links. If nothing changes, the run emits zero rows and zero charges.

### Run the next report

Use a new `monitorKey` and `emit_backfill` when an explicit current portfolio report is needed:

```json
{
  "watches": [
    {
      "id": "nih-linked-publications",
      "coreProjectNumbers": ["UG1HD078437"]
    }
  ],
  "monitorKey": "nih-linked-publications-current",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": true,
  "includePubMedMetadata": true,
  "maxProjectsPerWatch": 5,
  "maxPublicationsPerProject": 25,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

Use the `publication.pmid` values from this report as the next literature input. Run [PubMed Literature Watch & Research Report](https://apify.com/taroyamada/pubmed-research-intelligence) with those PMIDs or a related query: set `generateReport: true` for a current literature update, and also set `generateExport: true` with `emitRawRows: false` when you need a systematic-review screening/reference export. This keeps the grant-output and literature-review steps in one source-linked workflow.

### Input examples

#### Topic and fiscal-year portfolio

```json
{
  "watches": [
    {
      "id": "immunotherapy-r01",
      "terms": ["immunotherapy"],
      "fiscalYears": [2025, 2026],
      "activityCodes": ["R01"]
    }
  ],
  "monitorKey": "immunotherapy-r01-output",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "maxProjectsPerWatch": 10,
  "maxPublicationsPerProject": 100,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

#### Institution portfolio

```json
{
  "watches": [
    {
      "id": "institution-u01",
      "institutions": ["Example University"],
      "activityCodes": ["U01"],
      "fiscalYears": [2024, 2025, 2026]
    }
  ],
  "monitorKey": "institution-u01-output",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "includePubMedMetadata": true,
  "maxProjectsPerWatch": 10,
  "maxPublicationsPerProject": 100,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

#### Explicit export without PubMed enrichment

```json
{
  "watches": [
    {
      "id": "project-export",
      "coreProjectNumbers": ["UG1HD078437"]
    }
  ],
  "monitorKey": "project-export-2026",
  "initialRunMode": "emit_backfill",
  "generateReport": false,
  "emitRawRows": true,
  "emitExport": true,
  "includePubMedMetadata": false,
  "maxProjectsPerWatch": 5,
  "maxPublicationsPerProject": 50,
  "maxChargeUsd": 25,
  "dryRun": false
}
```

### Sample output

The report is the primary output:

```json
{
  "rowType": "nih_grant_publication_output_report",
  "billingEventName": "nih-grant-publication-output-report",
  "report": {
    "reportType": "grant_publication_output_change_report",
    "selectedProjectCount": 2,
    "selectedPublicationLinkCount": 7,
    "newLinkCount": 7,
    "metadataChangeCount": 0,
    "byPublicationYear": [
      {"key": "2026", "count": 4},
      {"key": "2025", "count": 3}
    ],
    "interpretation": "Descriptive public link and citation metadata only."
  },
  "sourceUrl": "https://api.reporter.nih.gov/?urls.primaryName=V2.0"
}
```

See [`docs/sample-output.json`](docs/sample-output.json) for representative alert, report, and export rows.

### Buyer workflow

1. Link a bounded grant portfolio to new public citations with this Actor's alert/report/export path.
2. Compare the associated award portfolio in [NIH RePORTER Funding Landscape Report](https://apify.com/taroyamada/nih-research-funding-landscape-report).
3. Continue to [PubMed Literature Watch & Research Report](https://apify.com/taroyamada/pubmed-research-intelligence) for the literature update and systematic-review export step, then widen discovery with [OpenAlex Research Intelligence](https://apify.com/taroyamada/openalex-research-intelligence) when needed.

### See also

- [NIH RePORTER Funding Landscape Report](https://apify.com/taroyamada/nih-research-funding-landscape-report) for the preceding award-landscape report.
- [PubMed Literature Watch & Research Report](https://apify.com/taroyamada/pubmed-research-intelligence) for the next literature update or systematic-review export.

### Output fields

- `project`: public NIH project number, title, organization, fiscal year, award amount, dates, and official source URL.
- `publication`: PMID, linked core project number, optional title, journal, publication date/type, DOI, and official URLs.
- `changeType`: `new_publication_link` or `publication_metadata_changed`.
- `report`: project/link totals and descriptive grouping by project, publication year, and journal.
- `limitations` and `prohibitedInterpretations`: safeguards that travel with each row.

The Actor intentionally omits investigator and program-officer identity, direct communication fields, article abstracts, and full text.

### Pricing

| Event | Price | Delivered when |
|---|---:|---|
| `nih-grant-publication-link-row` | $0.008 | Optional normalized public grant-publication link |
| `nih-publication-output-change-alert` | $0.25 | A new linkage or citation-metadata change is observed |
| `nih-grant-publication-output-report` | $15.00 | Selected changes are grouped into a portfolio report |
| `nih-grant-publication-export` | $10.00 | Selected records are packaged as a source-linked export |

There is no start charge. The Actor estimates the complete configured event charge before its first dataset push and fails closed if the estimate exceeds `maxChargeUsd`.

### Baseline and no-change billing

- `baseline_only` stores the first observed links and emits zero rows and zero charges.
- A later unchanged run emits zero rows and zero charges.
- `emitUnchanged` cannot override this billing safeguard.
- State is committed only after all billable rows receive a positive Apify PPE receipt.

### Compliance and interpretation

- Sources: official NIH RePORTER Project and Publication APIs plus optional NCBI ESummary citation metadata.
- Requests use no login, browser session, shared credential, or required API key.
- NIH requests are sequential and no faster than one request per second.
- NCBI keyless requests remain below the documented three-request-per-second limit.
- A linkage is a public association, not proof that a grant caused a publication.
- The report is not a quality, productivity, investigator, institution, clinical, or return-on-investment score.
- It is not medical, investment, financial, grant-writing, legal, procurement, or hiring advice.
- No NIH, HHS, NCBI, NLM, or funding-agency endorsement is implied.

### Development

```text
npm test
npm start
```

# Actor input Schema

## `watches` (type: `array`):

Use project numbers directly or a bounded NIH project search.

## `monitorKey` (type: `string`):

Stable isolated state namespace for this recurring portfolio.

## `initialRunMode` (type: `string`):

baseline\_only stores the first observation with zero rows. emit\_backfill delivers the current linked publications.

## `generateReport` (type: `boolean`):

Generate one descriptive publication-output report when new or changed links are delivered.

## `emitRawRows` (type: `boolean`):

Add one low-priced normalized row for each selected grant-publication link.

## `emitExport` (type: `boolean`):

Generate a compact JSON-ready export when selected links are delivered.

## `emitUnchanged` (type: `boolean`):

Accepted for compatibility. Unchanged monitoring runs always remain zero rows and zero charge.

## `includePubMedMetadata` (type: `boolean`):

Use official NCBI ESummary to add title, journal, publication date, and publication types for linked PMIDs.

## `ncbiEmail` (type: `string`):

Optional valid email sent to NCBI with the tool parameter. No NCBI API key is required at this Actor's conservative request rate.

## `maxProjectsPerWatch` (type: `integer`):

Bounded project portfolio size. Keep this small for fast scheduled checks.

## `maxPublicationsPerProject` (type: `integer`):

Maximum linked publication records retained for each core project.

## `maxChargeUsd` (type: `number`):

Fail closed before pushing any row when the planned PPE charge exceeds this cap.

## `dryRun` (type: `boolean`):

Return representative rows without calling NIH or NCBI, saving state, or charging events.

## Actor input object example

```json
{
  "watches": [
    {
      "id": "nih-linked-publications",
      "coreProjectNumbers": [
        "UG1HD078437"
      ]
    }
  ],
  "monitorKey": "nih-publication-output-watch",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "includePubMedMetadata": true,
  "ncbiEmail": "",
  "maxProjectsPerWatch": 10,
  "maxPublicationsPerProject": 100,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

# 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 = {
    "watches": [
        {
            "id": "nih-linked-publications",
            "coreProjectNumbers": [
                "UG1HD078437"
            ]
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/nih-grant-publication-output-report").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 = { "watches": [{
            "id": "nih-linked-publications",
            "coreProjectNumbers": ["UG1HD078437"],
        }] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/nih-grant-publication-output-report").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "watches": [
    {
      "id": "nih-linked-publications",
      "coreProjectNumbers": [
        "UG1HD078437"
      ]
    }
  ]
}' |
apify call taroyamada/nih-grant-publication-output-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=taroyamada/nih-grant-publication-output-report",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/lYZuyNAqECG0SrFgB/builds/JBV18fG1zt1ZULrZy/openapi.json
