Skill Tracer
Skills › Scientific Agent Skills › paper-lookup › ror.md

ror.md

127 lines · skills/paper-lookup/references/ror.md at 5f2bc03

Open on GitHub
1# ROR (Research Organization Registry)
2
3Open registry of research organizations. Use it to turn an affiliation string
4into a ROR ID (`https://ror.org/05a0ya142`) or to look up one org. It is not
5a paper database. OpenAlex and Crossref already *carry* ROR IDs on works;
6this API is how you resolve or check an existing ID.
7
8All figures below verified 2026-09-10. Use the **v2** routes.
9

ROR (Research Organization Registry)

Open registry of research organizations. Use it to turn an affiliation string into a ROR ID (https://ror.org/05a0ya142) or to look up one org. It is not a paper database. OpenAlex and Crossref already carry ROR IDs on works; this API is how you resolve or check an existing ID.

All figures below verified 2026-09-10. Use the v2 routes.

Raw lines 1 to 9
10## Base URL
12```
13https://api.ror.org/v2
14```
16Docs: https://ror.readme.io/docs/rest-api

Base URL

https://api.ror.org/v2

Docs: https://ror.readme.io/docs/rest-api

Raw lines 10 to 17
18## Authentication
20None. Heartbeat: `GET https://api.ror.org/heartbeat` → `OK`.

Authentication

None. Heartbeat: GET https://api.ror.org/heartbeat → OK.

Raw lines 18 to 21
22## Rate Limits
242000 requests / 5 minutes / IP. Traffic spikes around midnight UTC. For bulk
25matching, run the API locally (Docker) rather than hammering the public host.

Rate Limits

2000 requests / 5 minutes / IP. Traffic spikes around midnight UTC. For bulk matching, run the API locally (Docker) rather than hammering the public host.

Raw lines 22 to 26
27## Identifier
29A ROR ID is `https://ror.org/` plus nine characters (`0` + 6 alphanumeric +
302 check-ish chars), e.g. `https://ror.org/05a0ya142`. The path
31`/v2/organizations/05a0ya142` accepts the suffix alone.

Identifier

A ROR ID is https://ror.org/ plus nine characters (0 + 6 alphanumeric + 2 check-ish chars), e.g. https://ror.org/05a0ya142. The path /v2/organizations/05a0ya142 accepts the suffix alone.

Raw lines 27 to 32
33## Key Endpoints

Key Endpoints

Raw lines 33 to 34
35### 1. Keyword / identifier search
37```
38GET /v2/organizations?query={text}
39```
41Searches **only** `names` and `external_ids` (GRID, ISNI, Wikidata, Crossref
42Funder ID). It does not search addresses, websites, or relationships.
44Unquoted common words explode. Verified:
46| `query` | `number_of_results` | First hit |
47|---|---|---|
48| `Broad Institute` | 13016 | Broad Institute (lucky, not guaranteed) |
49| `"Broad Institute"` | 3 | Broad Institute |
51Never take `items[0]` as the match without reading `names` and `status`.
52Quote the string (`%22…%22`) when the user gave a proper name.
54Pages contain at most 20 active records. `page` is 1-based and capped at 500 (10,000 results); exceeding it can return HTTP 200 with `errors`. Use the ROR dump for the whole registry. Filter and page per
55https://ror.readme.io/docs/api-filtering and
56https://ror.readme.io/docs/api-paging. Pass `all_status=true` if you need
57inactive / withdrawn orgs in a list.

1. Keyword / identifier search

GET /v2/organizations?query={text}

Searches only names and external_ids (GRID, ISNI, Wikidata, Crossref Funder ID). It does not search addresses, websites, or relationships.

Unquoted common words explode. Verified:

querynumber_of_resultsFirst hit
Broad Institute13016Broad Institute (lucky, not guaranteed)
"Broad Institute"3Broad Institute

Never take items[0] as the match without reading names and status. Quote the string (%22…%22) when the user gave a proper name.

Pages contain at most 20 active records. page is 1-based and capped at 500 (10,000 results); exceeding it can return HTTP 200 with errors. Use the ROR dump for the whole registry. Filter and page per https://ror.readme.io/docs/api-filtering and https://ror.readme.io/docs/api-paging. Pass all_status=true if you need inactive / withdrawn orgs in a list.

Raw lines 35 to 58
59### 2. Affiliation matcher (unstructured strings)
61```
62GET /v2/organizations?affiliation={raw affiliation}
63```
65Best for "Broad Institute of MIT and Harvard, Cambridge, MA" dumped from a
66PDF. As of 2026-05-26 this parameter defaults to the **single search**
67strategy.
69The JSON is **not** the same as `?query=`. Each item is a match wrapper:
71```json
73 "substring": "Broad Institute of MIT and Harvard, Cambridge, MA",
74 "score": 1.0,
75 "matching_type": "SINGLE SEARCH",
76 "chosen": true,
77 "organization": { "id": "https://ror.org/05a0ya142", "names": […], "status": "active" }
79```
81Read `items[].organization` and `chosen`. `items[0].id` is absent — that is
82how a naive parse reports "no ROR ID" after a successful match.
84Verified: 10 items, first `chosen` true, organization is Broad Institute.

2. Affiliation matcher (unstructured strings)

GET /v2/organizations?affiliation={raw affiliation}

Best for "Broad Institute of MIT and Harvard, Cambridge, MA" dumped from a PDF. As of 2026-05-26 this parameter defaults to the single search strategy.

The JSON is not the same as ?query=. Each item is a match wrapper:

{
  "substring": "Broad Institute of MIT and Harvard, Cambridge, MA",
  "score": 1.0,
  "matching_type": "SINGLE SEARCH",
  "chosen": true,
  "organization": { "id": "https://ror.org/05a0ya142", "names": […], "status": "active" }
}

Read items[].organization and chosen. items[0].id is absent — that is how a naive parse reports "no ROR ID" after a successful match.

Verified: 10 items, first chosen true, organization is Broad Institute.

Raw lines 59 to 85
86### 3. One organization
88```
89GET /v2/organizations/{ror_id_or_suffix}
90```
92```
93GET /v2/organizations/05a0ya142
94```
96Always returns the record, including `inactive` / `withdrawn`. Lists hide
97those statuses by default; a single-id GET does not. Check `status` before
98writing the ID into metadata.
100v2 records have `names[]` (with types: ror_display, alias, acronym, label),
101not a top-level `name`. `/organizations/{id}` without `/v2` currently still
102returns the v2 shape; call `/v2/` so a future default change does not flip
103the schema under you.

3. One organization

GET /v2/organizations/{ror_id_or_suffix}
GET /v2/organizations/05a0ya142

Always returns the record, including inactive / withdrawn. Lists hide those statuses by default; a single-id GET does not. Check status before writing the ID into metadata.

v2 records have names[] (with types: ror_display, alias, acronym, label), not a top-level name. /organizations/{id} without /v2 currently still returns the v2 shape; call /v2/ so a future default change does not flip the schema under you.

Raw lines 86 to 104
105## Typical Workflow
1071. Proper name or GRID/ISNI → `?query="…"` and inspect the shortlist.
1082. Messy affiliation line → `?affiliation=` and keep rows with
109 `chosen: true`. If none is chosen, report the candidates for review; neither a high score nor the first position establishes a match.
1103. Known ROR ID → GET the record and confirm `status: active`.
1114. Then, if the user wanted papers from that org, search OpenAlex /
112 Crossref with the ROR ID. Do not search ROR for papers.

Typical Workflow

  1. Proper name or GRID/ISNI → ?query="…" and inspect the shortlist.
  2. Messy affiliation line → ?affiliation= and keep rows with chosen: true. If none is chosen, report the candidates for review; neither a high score nor the first position establishes a match.
  3. Known ROR ID → GET the record and confirm status: active.
  4. Then, if the user wanted papers from that org, search OpenAlex / Crossref with the ROR ID. Do not search ROR for papers.
Raw lines 105 to 113
114## Failure Modes
116| What you did | What happens | What to do |
117|---|---|---|
118| Unquoted `University` / `Institute` query | Thousands of hits | Quote the name; do not auto-pick |
119| Read `items[0].id` on an affiliation response | `null` | Use `items[0].organization.id` |
120| Wrote an inactive ROR from a single-id GET | Record exists, `status` is not `active` | Read `status` |
121| Used v1 field `name` | Missing | Use `names[].value` |

Failure Modes

What you didWhat happensWhat to do
Unquoted University / Institute queryThousands of hitsQuote the name; do not auto-pick
Read items[0].id on an affiliation responsenullUse items[0].organization.id
Wrote an inactive ROR from a single-id GETRecord exists, status is not activeRead status
Used v1 field nameMissingUse names[].value
Raw lines 114 to 122
123## Official sources reviewed 2026-09-30
125- https://ror.readme.io/docs/rest-api
126- https://ror.readme.io/docs/api-paging
127- https://ror.readme.io/docs/api-affiliation

Official sources reviewed 2026-09-30

  • https://ror.readme.io/docs/rest-api
  • https://ror.readme.io/docs/api-paging
  • https://ror.readme.io/docs/api-affiliation
Raw lines 123 to 127