Research Organization Registry API in C#

by Cyrus Gomes

ROR API Documentation: https://ror.readme.io/docs/rest-api

ROR API License: https://ror.readme.io/docs/ror-basics#what-is-ror

The ROR API is licensed under the Creative Commons’ CC0 license, designating its data as part of the public domain.

The Research Organization Registry (ROR) API provides persistent identifiers for research organizations.

These recipe examples were tested on August 21, 2024.

NOTE: The ROR API limits requests to a maximum of 2000 requests in a 5-minute period.

Setup#

ROR Data Dump#

When working with larger datasets, consider using the ROR data dump: https://ror.readme.io/docs/data-dump

Install Packages#

Install the CURL and jq packages by typing the following command in the terminal:

!sudo apt install curl jq

Create Directory#

Use the following command to create the ROR directory for our projects:

!mkdir ROR

Change to the newly created directory with the following command:

%cd ROR

Now, we utilize the %%file following command to create the following makefile, which will compile our program and create an executable.

%%file makefile

# Set the variable CC to gcc, which is used to build the program
CC=gcc

# Enable debugging information and enable all compiler warnings
CFLAGS=-g -Wall

# Set the BIN variable as the name of the binary file we are creating
BIN=ror

# Create the binary file
all: $(BIN)

# Map any file ending in .c to a binary executable. 
# "$<" represents the .c file and "$@" represents the target binary executable
%: %.c

	# Compile the .c file using the gcc compiler with the CFLAGS and links 
	# Resulting binary with the CURL library
	$(CC) $(CFLAGS) $< -o $@ -lcurl

# Clean target which removes specific files
clean:

	# Remove the binary file and an ".dSYM" (debug symbols for debugging) directories
	# The RM command uses -r to remove directories and -f to force delete
	$(RM) -rf $(BIN) *.dSYM
Writing makefile

The %%file command is used again to create our .c file, which contains the code for the program:

%%file ./ror.c

#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* CURL program that retrieves Research Organization Registry data from
   https://api.ror.org/ */

int main(int argc, char *argv[]) {

    // If arguments are invalid just return
    if (argc != 3 || strcmp(argv[1], "-url") != 0) {
        fprintf(stderr, "Error. Please provide the URL correctly. (./ror -url [url])\n");
        return EXIT_FAILURE;
    }

    // Initialize CURL HTTP connection
    CURL *curl = curl_easy_init();
    if (!curl) {
        fprintf(stderr, "CURL initialization failed\n");
        return EXIT_FAILURE;
    }

    // Set the URL to which the HTTP request will be sent
    curl_easy_setopt(curl, CURLOPT_URL, argv[2]);

    // Set option to follow redirections
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

    // Perform the HTTP request
    CURLcode result = curl_easy_perform(curl);

    // Check if the request was successful
    if (result != CURLE_OK) {
        fprintf(stderr, "Download problem: %s\n", curl_easy_strerror(result));
    }

    // Clean up and deallocate resources
    curl_easy_cleanup(curl);

    return EXIT_SUCCESS;
}
Writing ./ror.c
!make
# Compile the .c file using the gcc compiler with the CFLAGS and links 
# Resulting binary with the CURL library
gcc -g -Wall ror.c -o ror -lcurl

1. Searching with queries#

This first example uses the query parameter of the ROR API to search for an institution by name. In this example, we’ll search for The University of Alabama:

%%bash

# The search query is the institution name
institution="University of Alabama"

# Use the quotes function to URL encode our search term
url="https://api.ror.org/organizations?query=$(printf "%s" "$institution" | jq -s -R -r @uri)"

# Retrieve data from the API and store it in a JSON file
./ror -url "$url" | jq '.' > response.json

# Fetch data from the JSON file and process it with jq
cat response.json | jq -r ' "Total number of results: \(.number_of_results)\nPage length: \(.items | length)"'
Total number of results: 26471
Page length: 20

The results indicate that the query produced thousands of results, but only the data for 20 institutions were returned in this query. However, the top result was exactly what we were looking for:

# Display data of the top search result
!cat response.json | jq -r '.["items"][0]'
{
  "id": "https://ror.org/03xrrjk67",
  "name": "University of Alabama",
  "email_address": null,
  "ip_addresses": [],
  "established": 1831,
  "types": [
    "Education"
  ],
  "relationships": [
    {
      "label": "Mississippi Alabama Sea Grant Consortium",
      "type": "Related",
      "id": "https://ror.org/04vzsq290"
    },
    {
      "label": "University of Alabama System",
      "type": "Parent",
      "id": "https://ror.org/051fvmk98"
    }
  ],
  "addresses": [
    {
      "lat": 33.20984,
      "lng": -87.56917,
      "state": null,
      "state_code": null,
      "city": "Tuscaloosa",
      "geonames_city": {
        "id": 4094455,
        "city": "Tuscaloosa",
        "geonames_admin1": {
          "name": "Alabama",
          "id": 4829764,
          "ascii_name": "Alabama",
          "code": "US.AL"
        },
        "geonames_admin2": {
          "name": "Tuscaloosa",
          "id": 4094463,
          "ascii_name": "Tuscaloosa",
          "code": "US.AL.125"
        },
        "license": {
          "attribution": "Data from geonames.org under a CC-BY 3.0 license",
          "license": "http://creativecommons.org/licenses/by/3.0/"
        },
        "nuts_level1": {
          "name": null,
          "code": null
        },
        "nuts_level2": {
          "name": null,
          "code": null
        },
        "nuts_level3": {
          "name": null,
          "code": null
        }
      },
      "postcode": null,
      "primary": false,
      "line": null,
      "country_geonames_id": 6252001
    }
  ],
  "links": [
    "https://www.ua.edu/"
  ],
  "aliases": [],
  "acronyms": [],
  "status": "active",
  "wikipedia_url": "http://en.wikipedia.org/wiki/University_of_Alabama",
  "labels": [
    {
      "label": "Universidad de Alabama",
      "iso639": "es"
    },
    {
      "label": "Université de l'Alabama",
      "iso639": "fr"
    }
  ],
  "country": {
    "country_name": "United States",
    "country_code": "US"
  },
  "external_ids": {
    "ISNI": {
      "preferred": null,
      "all": [
        "0000 0001 0727 7545"
      ]
    },
    "FundRef": {
      "preferred": "100011531",
      "all": [
        "100011531"
      ]
    },
    "OrgRef": {
      "preferred": null,
      "all": [
        "327950"
      ]
    },
    "Wikidata": {
      "preferred": null,
      "all": [
        "Q492318"
      ]
    },
    "GRID": {
      "preferred": "grid.411015.0",
      "all": "grid.411015.0"
    }
  }
}

The following code produces the name, ROR ID, city, and wikipedia URL of the top result of the query:

!cat response.json | jq -r '.["items"][0]["name"]'
University of Alabama
!cat response.json | jq -r '.["items"][0]["id"]'
https://ror.org/03xrrjk67
!cat response.json | jq -r '.["items"][0]["addresses"][0]["city"]'
Tuscaloosa
!cat response.json | jq -r '.["items"][0]["wikipedia_url"]'
http://en.wikipedia.org/wiki/University_of_Alabama

Searching by alternate names#

The example below uses abbreviated forms of the full names of universities when searching:

%%bash

# List of institutions to be searched
institutions=(
    'University of Alabama Tuscaloosa'
    'Missouri'
    'Dartmouth'
    'Oxford'
    'UCLA'
)

# Send an HTTP request for each institution
for institution in "${institutions[@]}"; do

    # Set the URL for each institution
    url="https://api.ror.org/organizations?query=$(printf "%s" "$institution" | jq -s -R -r @uri)"

    # Retrieve data from the API and print the name
    # Print the search term and the name of its top result
    top_result=$(./ror -url "$url" | jq -r '.["items"][0]["name"]')
    echo "$institution: $top_result"

    # Stagger requests to be nicer on the ROR servers
    sleep 1

done
University of Alabama Tuscaloosa: University of Alabama
Missouri: Missouri College
Dartmouth: Dartmouth Hospital
Oxford: Stockholm Environment Institute
UCLA: Universidad Centroccidental Lisandro Alvarado

The top results of the queries above are probably not what you would have expected. The example below remedies these issues by having more clearly defined search strings:

%%bash

# List of institutions to be searched
institutions=(
    'University of Alabama Tuscaloosa'
    'University of Missouri'
    'Dartmouth College'
    'University of Oxford'
    'University of California Los Angeles'
)

# Send an HTTP request for each institution
for institution in "${institutions[@]}"; do

    # Set the URL for each institution
    url="https://api.ror.org/organizations?query=$(printf "%s" "$institution" | jq -s -R -r @uri)"

    # Retrieve data from the API and print the name
    # Print the search term and the name of its top result
    top_result=$(./ror -url "$url" | jq -r '.["items"][0]["name"]')
    echo "$institution: $top_result"

    # Stagger requests to be nicer on the ROR servers
    sleep 1

done
University of Alabama Tuscaloosa: University of Alabama
University of Missouri: University of Missouri
Dartmouth College: Dartmouth College
University of Oxford: University of Oxford
University of California Los Angeles: University of California, Los Angeles

2. Searching with filters#

The ROR API also allows searches to be performed with the filter parameter, which can take 3 arguments: status, types, and country. For more information on what values these arguments can take, read the ROR documentation here: https://ror.org/tutorials/intro-ror-api/#filtering-results

%%bash

# List of institutions to be searched
filters=(
    "country.country_name:$(printf 'United States' | jq -s -R -r @uri)"
    'types:Education'
    'status:Active'
)

# Join array elements using ',' as separator
filters_string=$(IFS=','; echo "${filters[*]}")

# Set the URL for each institution
url="https://api.ror.org/organizations?filter=$filters_string"

# Print the number of results
./ror -url "$url" | jq -r '.["number_of_results"]'
4307

Paging through a result#

The example below pages through the results to find the names and ROR IDs of the first 100 institutions returned using the filter:

%%bash

# List of institutions to be searched
filters=(
    "country.country_name:$(printf 'United States' | jq -s -R -r @uri)"
    'types:Education'
    'status:Active'
)

# Join array elements using ',' as separator
filters_string=$(IFS=','; echo "${filters[*]}")

# URL constructed with the filters
url="https://api.ror.org/organizations?filter=$filters_string"

# Retrieve data from the api and print the name
response=$(./ror -url "$url" | jq -r '.')

# Number of results and length of items
num_results=$(echo "$response" | jq '.["number_of_results"]')
length_items=$(echo "$response" | jq '.["items"] | length')

# Create an array to store the institution names and ids
declare -A institution_name_ids

# Calculate number of pages in result
total_pages=$(((num_results) / length_items + 1))

# Remove the "&& page_number < 5" to iterate over all the pages
# Limited to first 5 pages for this tutorial
for ((page_number = 0; page_number < total_pages && page_number < 5; page_number++)); do

    # Complete the URL with filters and page number
    url="https://api.ror.org/organizations?filter=$filters_string&page=$((page_number + 1))"

    # Retrieve the data from the API
    response=$(./ror -url "$url" | jq -r '.["items"]')

    # Retrieve the name and id and store in the associative array
    while IFS=: read -r name id; do
        institution_name_ids["$name"]="$id"
    done < <(jq -r '.[] | "\(.name):\(.id)"' <<< "$response")

    # Stagger requests to be nicer on the ROR servers
    sleep 1

done

# Print each name and id
# Store it in a file called institution_name_ids.txt
for key in "${!institution_name_ids[@]}"; do
    echo "$key: ${institution_name_ids[$key]}" 
done | sort -k1 | tee institution_name_ids.txt
Alaska Marine Safety Education Association: https://ror.org/01gr48a54
Anchorage School District: https://ror.org/02yvffa38
Antioch College: https://ror.org/00bmb8a49
Archmere Academy: https://ror.org/04k7qsz50
ASA College: https://ror.org/039h3aa75
Athens Technical College: https://ror.org/000ge9g13
Atlantic Union College: https://ror.org/03aat3341
Austin Independent School District: https://ror.org/01g9rp025
Averett University: https://ror.org/00vm5ky05
Barber–Scotia College: https://ror.org/05rmcwb88
Barre Town Middle and Elementary School: https://ror.org/008jf2g02
Baton Rouge Community College: https://ror.org/057r54s29
Baylor School: https://ror.org/01qd58v91
Bay Path University: https://ror.org/05xca6483
Bergen Community College: https://ror.org/02hwvpm08
Biloxi Public Schools: https://ror.org/01j6w4907
Bonanza High School: https://ror.org/021mk5n73
Boston Architectural College: https://ror.org/00q4tes89
Brookdale Community College: https://ror.org/05mrhv083
Cape Cod Community College: https://ror.org/02w1skc55
Cape Fear Community College: https://ror.org/05mc3r439
Capital Community College: https://ror.org/014a8dd26
Centralia College: https://ror.org/026sdzz57
Central Virginia Community College: https://ror.org/00ehy3369
Cincinnati Christian University: https://ror.org/00342ps77
Cincinnati State Technical and Community College: https://ror.org/01g5qva43
Claremont Colleges: https://ror.org/03xaz7s88
Clark State Community College: https://ror.org/02k16sh85
CollegeAmerica: https://ror.org/050p5ky47
College of Lake County: https://ror.org/03v8atx30
College of Westchester: https://ror.org/00ck0vh11
College of Western Idaho: https://ror.org/05sfzsk90
Columbus College of Art and Design: https://ror.org/03n6gc586
Columbus State Community College: https://ror.org/02s8rep32
Committee on Institutional Cooperation: https://ror.org/02ntfsb56
Compton Community College District: https://ror.org/013f0nb72
Concordia Seminary: https://ror.org/05tq5tc82
Concordia University Chicago: https://ror.org/02jvqj155
Concordia University Wisconsin: https://ror.org/04k83g518
Cornerstone University: https://ror.org/01nfeyj87
Cottey College: https://ror.org/05w3cd862
Culver Stockton College: https://ror.org/00n855a93
Divine Word College: https://ror.org/0448r9386
Eagle Gate College: https://ror.org/04hs3y322
East Arkansas Community College: https://ror.org/0583vk835
East Central Community College: https://ror.org/03qa0dm98
Eastern Arizona College: https://ror.org/03fcyyh75
Eastern West Virginia Community and Technical College: https://ror.org/034fab991
Eastern Wyoming College: https://ror.org/03ye76s02
Eastwick College and the HoHoKus Schools: https://ror.org/02fa80e12
Edison Community College: https://ror.org/0182rkr07
Faulkner University: https://ror.org/048kc5t54
Feather River College: https://ror.org/03wzvrw53
Fisher College: https://ror.org/02a3j1p21
Harrington College of Design: https://ror.org/02v431325
Heartland Community College: https://ror.org/004xm6e62
Hebrew Theological College: https://ror.org/01g2p0822
Henderson Community College: https://ror.org/00vzha967
Hennepin Technical College: https://ror.org/00m41wh60
Hibbing Community College: https://ror.org/037saaz25
Hillsdale College: https://ror.org/05vs4fq96
Hocking College: https://ror.org/01tpw6659
Holy Cross College: https://ror.org/0574bwf68
Illinois Mathematics and Science Academy: https://ror.org/024xf4148
Illinois Valley Community College: https://ror.org/04v1k1t27
Indianapolis Public Schools: https://ror.org/04ttjs010
Indiana University East: https://ror.org/046z54t28
Indiana University Kokomo: https://ror.org/04161kh40
International Business College - Fort Wayne: https://ror.org/00qbqm161
Missouri Baptist University: https://ror.org/05wfyqn93
Missouri Southern State University: https://ror.org/01zqbp192
Missouri Valley College: https://ror.org/02msncq66
Moody Bible Institute: https://ror.org/05wffnp93
Moraine Park Technical College: https://ror.org/03afd3b65
Morton College: https://ror.org/03wn0d080
Mount Mary University: https://ror.org/02qr05d85
Mount Vernon Nazarene University: https://ror.org/01jtsd542
Paterson Public Schools: https://ror.org/00e3ms285
Prince George's County Public Schools: https://ror.org/047137m93
Southeastern Illinois College: https://ror.org/017f49052
Southern State Community College: https://ror.org/02xaxz408
South Suburban College: https://ror.org/01c6kab21
Southwestern Illinois College: https://ror.org/04y17xm23
Southwestern Michigan College: https://ror.org/01g1dn598
Spertus Institute for Jewish Learning and Leadership: https://ror.org/01hxtdq06
Spoon River College: https://ror.org/025vzq165
Spring Arbor University: https://ror.org/02j8e5x02
State Fair Community College: https://ror.org/00v02jt04
Vincennes University: https://ror.org/03gbwkj22
Walsh College: https://ror.org/05s4pg032
Washington State Community College: https://ror.org/03mbgzm57
Washtenaw Community College: https://ror.org/03k77wm53
Waubonsee Community College: https://ror.org/03dfsfy59
Waukesha County Technical College: https://ror.org/01hqrfw90
Wells College: https://ror.org/006pvfx30
Wesley Theological Seminary: https://ror.org/04ky2re88
Westwood College: https://ror.org/05kjfpp30
Wilmington College: https://ror.org/01k08ez36
Wisconsin Indianhead Technical College: https://ror.org/01r678s56
Wisconsin Lutheran College: https://ror.org/00nve0j20

The resulting dictionary can be used to find the ROR of an institution based on its name:

!grep "Eastern Arizona College" institution_name_ids.txt
Eastern Arizona College: https://ror.org/03fcyyh75

3. Searching with queries and filters#

The filter and query parameters can both be used in a single request. In this example, we filter the results of the query “Birmingham” to only include institutions from the United States:

%%bash

# Filter results to the United States
filters=(
    "country.country_name:$(printf 'United States' | jq -s -R -r @uri)"
)

# Search term
query="Birmingham"

# Join array elements using ',' as separator
filters_string=$(IFS=','; echo "${filters[*]}")

# Set the URL for each institution
url="https://api.ror.org/organizations?query=$query&filter=$filters_string"

# Print the number of results
./ror -url "$url" | jq -r '.["number_of_results"]'
12
%%bash

# Filter results to the United States
filters=(
    "country.country_name:$(printf 'United States' | jq -s -R -r @uri)"
)

# Search term
query="Birmingham"

# Join array elements using ',' as separator
filters_string=$(IFS=','; echo "${filters[*]}")

# URL constructed with the filters
url="https://api.ror.org/organizations?query=$query&filter=$filters_string"

# retrieve data from the api and print the name
response=$(./ror -url "$url" | jq -r '.')

# Find number of results and length of items
num_results=$(echo "$response" | jq '.["number_of_results"]')
length_items=$(echo "$response" | jq '.["items"] | length')

# Create an array to store the institution names and ids
declare -A institution_name_ids

# Calculate number of pages in result
total_pages=$(((num_results) / length_items + 1))

# Remove the "&& page_number < 5" to iterate over all the pages
# Limited to first 5 pages for this tutorial
for ((page_number = 0; page_number < total_pages && page_number < 5; page_number++)); do

    # Complete the url with filters, query, and page number
    url="https://api.ror.org/organizations?query=$query&filter=$filters_string&page=$((page_number + 1))"

    # Retrieve the data from the API
    response=$(./ror -url "$url" | jq -r '.["items"]')

    # Retrieve the name and id and store in the associative array
    while IFS=: read -r name id; do
        institution_name_ids["$name"]="$id"
    done < <(jq -r '.[] | "\(.name):\(.id)"' <<< "$response")

    # Stagger requests to be nicer on the ROR servers
    sleep 1

done

# Print each name and id
# Store it in a file called institution_name_ids_2.txt
for key in "${!institution_name_ids[@]}"; do
    echo "$key: ${institution_name_ids[$key]}" 
done | sort -k1 | tee institution_name_ids_2.txt
Alabama Audubon: https://ror.org/02qbyex13
Birmingham Bloomfield Community Coalition: https://ror.org/004mx7t23
Birmingham Civil Rights Institute: https://ror.org/00fqce595
Birmingham Museum of Art: https://ror.org/030y6zg68
Birmingham Public Library: https://ror.org/05czff141
Birmingham–Southern College: https://ror.org/006g42111
Birmingham VA Medical Center: https://ror.org/0242qs713
St. Vincent's Birmingham: https://ror.org/000crk757
UAB Medicine: https://ror.org/036554539
University of Alabama at Birmingham Hospital: https://ror.org/01rm42p40
University of Alabama at Birmingham: https://ror.org/008s83205
Vision Specialists of Michigan: https://ror.org/02awhp844