Grants
Overview
NIH, NSF and CORDIS awards: who was funded for what, with abstracts and amounts.
- status
- live
- document id
grant_ide.g.nih:R25HG007515- citation
[NIH R25HG007515]- updated
- 2026-10
Common calls
Find awards
POST /v1/grants/search {"query": "单细胞转录组", "filters": {"agency": "nih", "fy": {"gte": 2020}}}Read one award
GET /v1/grants/read/nih:R25HG007515Counts per institute
GET /v1/grants/facets?field=ic_or_directorateThe fine print
- One NIH document = all yearly awards under a core project number (amount_total is the sum, funding_by_year the breakdown); one NSF document = one award; one CORDIS document = one project (grant_id = cordis:<project id>), org_* is the coordinator and amount_total the EU contribution in EUR (currency=EUR at level=head; NIH / NSF have no currency field and are in USD).
- org_country casing is inconsistent in the source (both UNITED STATES and United States, 1.088M awards) — pass both spellings.
- `topics` are open labels with tens of thousands of values: good to read, poor to filter on — use research_domain.
- Where no abstract exists the summary comes from the title alone (_enrich.basis=title_only).
- The index holds no full text: level=full is not available yet (abstracts are already in level=detail; progress reports and publications are not in this corpus).
Search
POST
/v1/grants/searchHybrid retrieval, one card per hit. 2 credits. Free sample:
single cell transcriptomics.Filter fields
| field | type · ops | meaning |
|---|---|---|
| agency | keyword · eq anynih · nsf · cordis | Funding agency |
| research_domain | keyword · eq anybiomedical · life_sciences · clinical · public_health · engineering · physical_sciences … 13 values, /facets lists them all | Research domain (model-assigned, closed set of 13) |
| ic_or_directorate | keyword · eq any | NIH institute, NSF directorate or CORDIS framework programme (FP7 / H2020 / HORIZON …, see facets) |
| activity_code | keyword · eq any | Funding mechanism: NIH activity code (R01 / R21 / F32 …), NSF award type or CORDIS funding scheme |
| fy | integer · eq range | Fiscal year, range |
| start_year | integer · eq range | Project start year, range |
| end_year | integer · eq range | Project end year, range |
| amount_total | number · eq range | Total amount, range (USD for NIH / NSF; EU contribution in EUR for CORDIS — pair with agency when filtering across agencies) |
| org_country | keyword · eq any | Organisation country (source casing is inconsistent — see notes) |
7 more, all usable
| field | type · ops | meaning |
|---|---|---|
| org_state | keyword · eq any | US state |
| org_name | keyword · eq any | Organisation name (exact) |
| pi_names | keyword · eq any | PI name as written in the source (NIH uses LAST, FIRST) |
| topics | keyword · eq any | Research topics (open model-generated labels, very high cardinality) |
| programs | keyword · eq any | Programme names |
| core_project_num | keyword · eq any | NIH core project number |
| is_renewal | bool · eq | Renewal |
Parameters
| Parameter | Type | Description |
|---|---|---|
| query REQUIRED | string | 1–1000 characters. Or an array of up to 5 (batch; hits become results[]). |
| top_k | integer= 10 | 1–100. |
| fields | brief · head= brief | head costs one more credit and returns the head view per hit. |
| filters | json | Filter DSL object (see Getting started); declared fields are listed above. |
| mode | hybrid · dense · bm25= hybrid | Retrieval mode. Leave it out to use the first. |
| offset | integer= 0 | Pagination. |
Example
{ "domain": "grants", "query": "…", "hits": [ { "id": "nih:R25HG007515", "score": 0.83, "brief": { … } } ], "total": null, "coverage": …, "warnings": [],
"meta": { "request_id": "req_…", "credits": { "charged": 2, "balance": 1998, "pool": "allowance" }, "latency_ms": 41, "cached": false } } Two layers. 1,328,138 documents carry vectors; the store behind them holds 1,313,241. Hits carry
layer: index | pg — pg means the match was by words, not meaning — and coverage says which layer answered (answered_by) and why a fallback did not happen (no_fallback_because). Filters that only one layer has cannot be mixed; the 400 names which belongs where.Undeclared filter fields return 400 rather than being ignored silently. Filters combine with AND;
_or / _not are available.Read
GET
/v1/grants/read/{grant_id}Three depths.
detail is the default. Free sample: nih:R25HG007515.Levels
| level | credits | returns |
|---|---|---|
| brief | 1 | Card: the fields needed to triage, same as in search hits |
| detail (default) | 2 | Every structured field (rule-derived plus model-generated; model fields are listed in _enrich.fields) |
| full | 5 | Full text (not available yet: abstracts are already in level=detail; progress reports and publications are not in this corpus) |
Parameters
| Parameter | Type | Description |
|---|---|---|
| grant_id (path) REQUIRED | string | Document id (grant_id). |
| level | brief · detail · full= detail | How deep to read. |
| format | json · md · html= json | Response shape. |
Example
{ "domain": "grants", "id": "nih:R25HG007515", "level": "detail", "view": "head", "data": { … } | "text": "…", "token_count": 1834, "meta": { … } } The older
GET /v1/grants/doc/{id}?view=… still works.Read many
POST
/v1/grants/readUp to 50 ids, one level. Missing ids come back with
error: "not_found" and are not charged.Parameters
| Parameter | Type | Description |
|---|---|---|
| ids REQUIRED | string[] | Document ids. |
| level | brief · detail · full= detail | Level for every id. |
Example
{ "domain": "grants", "level": "detail", "docs": [ { "id": "…", "data": { … } }, { "id": "…", "error": "not_found" } ], "meta": { … } } Facets
GET
/v1/grants/facets?field={field}Legal values for a filter field, so an agent never guesses; precomputed fields carry counts, declared enums come without. Free, no key.
Parameters
| Parameter | Type | Description |
|---|---|---|
| field REQUIRED | agency · research_domain · ic_or_directorate · activity_code · org_country · org_state | Filter field with facets. |
| limit | integer= 50 | Max values. |
Example
{ "domain": "grants", "field": "…", "values": [ { "value": "…", "count": 3120 } ], "meta": { … } } Askregistered key+ /stream
POST
/v1/grants/askAgentic Q&A over this domain: the model turns the question into filters plus keywords from the domain's own self-description, reads the hits and answers with [grants: ] citations; /stream is NDJSON with real token deltas.
effort low / medium / high = 50 / 100 / 200 credits. Append /stream for NDJSON; the first event is always billing. A failure before the first answer_delta is refunded.Parameters
| Parameter | Type | Description |
|---|---|---|
| query REQUIRED | string | 1–2000 characters. Be specific; ask for numbers if you want numbers. |
| effort | low · medium · high= low | Reading rounds, and the price: 50 / 100 / 200 credits. Your plan caps it. |
| verbose | bool= false | Include the tool-call trace (tool_call / tool_result / thinking events when streaming). |
| top_k | integer= 10 | Speculative prefetch size. |
| stream_answer | bool= true | Streaming only: false emits one answer event instead of deltas. |
| max_rounds | integer | 0–8, overrides the effort preset. |
| force_answer_after | number | Seconds; hard cutover into the answer phase. |
| max_answer_tokens | integer= 4096 | Hitting it sets answer_truncated. |
| language | string | Answer language; defaults to the query’s. |
Example
{ "answer": "… [NIH R25HG007515] …", "sources": [ … ], "stats": { "rounds": 1, "elapsed_s": 6.2, "answer_truncated": false }, "coverage"?: { … }, "meta": { "credits": { "charged": 50, … } } } Citations are real — every id in
answer exists in this domain (format [NIH R25HG007515]). sources is the retrieval set, not the citation list. answer_truncated means incomplete.