# OpenAlex

> Search the open catalogue of the world's research: hundreds of millions of papers, preprints, books and datasets, the researchers who wrote them, the journals that published them, and the institutions, funders and grants behind them. Follow citations both ways, read abstracts, download full text, and turn any query into counts by year, country or journal.

App · Research & Academia · 41 actions. Web page: https://docs.lodol.com/docs/integrations/openalex

## Actions

### Add entities to a collection

Add entities to a saved collection in one call - the step that turns a search into a saved list. Ids already in the collection are counted rather than duplicated, and an id of the wrong kind is refused outright naming the offender. A collection holds at most 1,000 entities. Needs an API key.

**Inputs**

- Collection ID (`collection_id`, text, required): The collection to add to.
- Entity IDs (`entity_ids`, list, required): The entities to add. Every id has to match the kind the collection holds.

**Outputs**

- `added` (number)
- `already_present` (number)
- `collection_id` (text)
- `rejected_wrong_type` (number)
- `requested_count` (number)

**Example output**

```json
{
  "added": 2,
  "already_present": 0,
  "collection_id": "col_beNWUTw6qY",
  "rejected_wrong_type": 0,
  "requested_count": 2
}
```

### Autocomplete

Turn a half-typed name into an OpenAlex id, fast. This is the documented way to resolve a name before filtering by it - OpenAlex matches ids, never names, so 'works by MIT' means looking MIT up first. Each suggestion carries a hint that tells similar names apart: an author's institution, a work's authors, an institution's city. Leave the type empty to search everything at once, and paste an id, DOI or ORCID as the query to match it directly.

**Inputs**

- What the user typed (`query`, text, required): The partial name to complete. An OpenAlex id, DOI or ORCID pasted here is matched exactly.
- Kind of thing (`entity_type`, text): Which kind of entity to suggest. Leave empty to search every kind at once. One of: `works`, `authors`, `sources`, `institutions`, `topics`, `keywords`, `concepts`, `publishers`, `funders`.
- Also matching (`search`, text): An extra full-text search the suggestions must also match, for narrowing a picker to one corner of the catalogue.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.

**Outputs**

- `entity_type` (text)
- `query` (text)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "entity_type": "institutions",
  "query": "flori",
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 31192599,
      "display_name": "University of Florida",
      "entity_type": "institution",
      "external_id": "https://ror.org/02y3ad647",
      "hint": "Gainesville, USA",
      "id": "https://openalex.org/I33213144",
      "works_count": 367380
    }
  ],
  "total_count": 212
}
```

### Check API usage

Check how much of today's OpenAlex budget is left: the daily credit limit, what has been spent, what remains, when it resets, and what each kind of call costs. Worth reading at the top of a scheduled workflow that is about to make thousands of calls. Needs an API key on this connection - the figures are about the key.

**Inputs**: None.

**Outputs**

- `credit_costs` (object)
- `credits_limit` (number)
- `credits_remaining` (number)
- `credits_used` (number)
- `resets_at` (text)
- `resets_in_seconds` (number)

**Example output**

```json
{
  "credit_costs": {
    "content": 100,
    "list": 1,
    "search": 10,
    "singleton": 0
  },
  "credits_limit": 100000,
  "credits_remaining": 98766,
  "credits_used": 1234,
  "resets_at": "2026-08-27T00:00:00.000Z",
  "resets_in_seconds": 43200
}
```

### Create a saved collection

Create a private, named list of OpenAlex entities of one type, holding up to 1,000 of them. Once it exists, its id goes in the 'Saved collection' field of any search on that type, or into an id filter on a related type - a collection of journals filters works by where they were published. A collection holds one type only, so tracking works and their authors means two collections. Needs an API key.

**Inputs**

- Name (`display_name`, text, required): What to call it, up to 30 characters. Must be unique among your collections.
- Kind of entity (`entity_type`, text, required): What the collection holds. It can only be changed later while the collection is still empty. One of: `works`, `authors`, `sources`, `institutions`, `topics`, `sdgs`, `funders`, `publishers`, `keywords`, `concepts`.
- Description (`description`, text): Optional notes, up to 500 characters.
- Entity IDs (`entity_ids`, list): The entities to start it with, up to 1,000. Every id has to match the kind chosen above. Can be left empty and filled in later.

**Outputs**

- `collection` (object)

**Example output**

```json
{
  "collection": {
    "created_at": "2026-05-26T14:00:00",
    "description": "Papers I'm tracking for the altmetrics review",
    "display_name": "My altmetrics papers",
    "entity_count": 2,
    "entity_type": "works",
    "id": "col_beNWUTw6qY",
    "updated_at": "2026-05-26T14:00:00",
    "user_id": "user-TSamuHxDbnhn"
  }
}
```

### Delete a saved collection

Delete a saved collection and its membership list. The entities in it are untouched - only the list goes, and it cannot be undone. Needs an API key, and the collection has to belong to this connection's account.

**Inputs**

- Collection ID (`collection_id`, text, required): The collection to delete.

**Outputs**

- `collection_id` (text)
- `deleted` (true/false)

**Example output**

```json
{
  "collection_id": "col_beNWUTw6qY",
  "deleted": true
}
```

### Download a work's full text

Download the cached full text of a work as a file, either the original PDF or machine-readable TEI XML. OpenAlex holds full text for more than 50 million works; check the work's has_content field, or filter on has_content.pdf, before asking. The file lands in document storage, so a later step can attach it to an email, put it in a folder or read it. Needs an API key, and each download costs a cent of your OpenAlex budget.

**Inputs**

- Work ID (`work_id`, text, required): The OpenAlex id of the work. The full-text archive is addressed by OpenAlex id only, so look the work up first if all you have is a DOI.
- Format (`content_format`, text): Which copy to download. PDF is the original file; TEI XML is the same paper parsed into structured sections, which is easier for a later step to read. One of: `pdf` (PDF (the original file)), `grobid_xml` (TEI XML (machine-readable, parsed by Grobid)).

**Outputs**

- `byte_size` (number)
- `content_format` (text)
- `content_type` (text)
- `document_ref` (text)
- `documents` (list)
- `filename` (text)
- `url` (text)
- `work_id` (text)

**Example output**

```json
{
  "byte_size": 1048576,
  "content_format": "pdf",
  "content_type": "application/pdf",
  "document_ref": "doc_01J8Z5Q2N4V7K",
  "documents": [
    {
      "content_type": "application/pdf",
      "document_ref": "doc_01J8Z5Q2N4V7K",
      "filename": "W3038568908.pdf",
      "size_bytes": 1048576,
      "url": "/actions/core/serve-document/doc_01J8Z5Q2N4V7K"
    }
  ],
  "filename": "W3038568908.pdf",
  "url": "/actions/core/serve-document/doc_01J8Z5Q2N4V7K",
  "work_id": "W3038568908"
}
```

### Get a concept (legacy)

Get one concept by OpenAlex id or Wikidata id: its description, its level, the concepts above and beside it, and its works and citation counts. Deprecated in favour of topics, and kept for continuity with older analyses. Free.

**Inputs**

- Concept ID (`concept_id`, text, required): The concept to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `wikidata`, `display_name`, `level`, `description`, `image_url`, `image_thumbnail_url`, `international` (Name in other languages), `ancestors`, and 8 more.

**Outputs**

- `concept` (object)

**Example output**

```json
{
  "concept": {
    "cited_by_count": 933341750,
    "display_name": "Medicine",
    "id": "https://openalex.org/C71924100",
    "level": 0,
    "works_count": 86486082
  }
}
```

### Get a domain, field or subfield

Get one level of the subject hierarchy by its number - domain 3, field 17, subfield 1702. Returns its description, the levels above and below it, its siblings, and how many works and citations sit under it. Free.

**Inputs**

- Level (`level`, text, required): Which level the id belongs to. One of: `domains` (Domains (4: the top level)), `fields` (Fields (26)), `subfields` (Subfields (252)).
- ID (`subject_id`, text, required): The number identifying it. Domains are 1 to 4, fields are two digits, subfields are four.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `display_name_alternatives`, `description`, `fields`, `siblings`, `works_count`, `cited_by_count`, `works_api_url`, and 6 more.

**Outputs**

- `level` (text)
- `subject` (object)

**Example output**

```json
{
  "level": "fields",
  "subject": {
    "cited_by_count": 160069587,
    "description": "study of computation",
    "display_name": "Computer Science",
    "id": "https://openalex.org/fields/17",
    "works_count": 23408426
  }
}
```

### Get a funder

Get one funder by OpenAlex id or ROR: its names, country, homepage and logo, how many grants it has made, and the works and citations that acknowledge it, year by year. Free.

**Inputs**

- Funder ID or ROR (`funder_id`, text, required): The funder to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `alternate_titles`, `description`, `country_code`, `is_global_south`, `awards_count`, `homepage_url`, `image_url`, and 8 more.

**Outputs**

- `funder` (object)

**Example output**

```json
{
  "funder": {
    "awards_count": 2175047,
    "cited_by_count": 111490034,
    "country_code": "US",
    "display_name": "National Institutes of Health",
    "id": "https://openalex.org/F4320332161",
    "works_count": 1839960
  }
}
```

### Get a grant

Get one research grant by its OpenAlex id: its title and abstract, the funder and the funder's own grant number, the amount and currency, start and end dates, the principal investigator and co-investigators, the institutions that received it, and the works it paid for. Free.

**Inputs**

- Grant ID (`award_id`, text, required): The grant to fetch, by OpenAlex id.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `display_name`, `description`, `funder`, `funder_award_id`, `funder_scheme`, `funding_type`, `amount`, `currency`, `start_date`, and 17 more.

**Outputs**

- `award` (object)

**Example output**

```json
{
  "award": {
    "amount": 338786.0,
    "currency": "USD",
    "display_name": "Genetic analysis of dopaminergic neuron specification in C.elegans",
    "end_year": 2014,
    "funded_outputs_count": 0,
    "funder": {
      "display_name": "National Institutes of Health",
      "id": "https://openalex.org/F4320332161"
    },
    "funder_award_id": "2r01ns050266-06",
    "funder_scheme": "R01",
    "funding_type": "research",
    "id": "https://openalex.org/G5066037109",
    "start_date": "2004-09-15",
    "start_year": 2004
  }
}
```

### Get a journal or repository

Get one source by OpenAlex id or ISSN: its titles and ISSNs, who publishes it, whether it is open access and whether DOAJ lists it, what it charges to publish, the topics it covers, and its works, citations and h-index over time. Free.

**Inputs**

- Source ID or ISSN (`source_id`, text, required): The journal or repository to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `issn_l`, `issn`, `host_organization`, `host_organization_name`, `host_organization_lineage`, `type`, `is_oa`, and 26 more.

**Outputs**

- `source` (object)

**Example output**

```json
{
  "source": {
    "cited_by_count": 448736,
    "display_name": "PeerJ",
    "id": "https://openalex.org/S1983995261",
    "is_in_doaj": true,
    "is_oa": true,
    "issn_l": "2167-8359",
    "type": "journal",
    "works_count": 21590
  }
}
```

### Get a keyword

Get one keyword by its slug - keywords are named 'machine-learning' rather than by a letter-and-number id. Returns its label, how many works carry it, how often those works are cited, and a ready-made link to them. Free.

**Inputs**

- Keyword (`keyword_id`, text, required): The keyword's slug, or the full OpenAlex URL for it.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. One or more of: `id`, `display_name`, `works_count`, `cited_by_count`, `works_api_url`, `created_date`, `updated_date`.

**Outputs**

- `keyword` (object)

**Example output**

```json
{
  "keyword": {
    "cited_by_count": 47593799,
    "display_name": "Machine learning",
    "id": "https://openalex.org/keywords/machine-learning",
    "works_api_url": "https://api.openalex.org/works?filter=keywords.id:keywords/machine-learning",
    "works_count": 2030113
  }
}
```

### Get a publisher

Get one publisher by OpenAlex id or ROR: its names, where it sits in the publishing hierarchy, the countries it operates in, its logo, and its works and citation counts over time. Free.

**Inputs**

- Publisher ID or ROR (`publisher_id`, text, required): The publisher to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `alternate_titles`, `hierarchy_level`, `parent_publisher`, `lineage` (Ids of this and its parent organizations), `country_codes`, `homepage_url`, `image_url`, and 9 more.

**Outputs**

- `publisher` (object)

**Example output**

```json
{
  "publisher": {
    "cited_by_count": 649222945,
    "country_codes": [
      "NL"
    ],
    "display_name": "Elsevier BV",
    "hierarchy_level": 0,
    "id": "https://openalex.org/P4310320990",
    "works_count": 24213449
  }
}
```

### Get a saved collection

Get one saved collection: its name, description, what kind of entity it holds and how many. The entities themselves are paged separately - use List a collection's entities for those. Needs an API key, and the collection has to belong to this connection's account.

**Inputs**

- Collection ID (`collection_id`, text, required): The collection to fetch.

**Outputs**

- `collection` (object)

**Example output**

```json
{
  "collection": {
    "created_at": "2026-05-26T14:00:00",
    "description": "Papers I'm tracking for the altmetrics review",
    "display_name": "My altmetrics papers",
    "entity_count": 2,
    "entity_type": "works",
    "id": "col_beNWUTw6qY",
    "updated_at": "2026-05-26T14:00:00",
    "user_id": "user-TSamuHxDbnhn"
  }
}
```

### Get a Sustainable Development Goal

Get one UN goal by its number, 1 to 17: its name, the one-sentence statement of it, its official icon, and how many works and citations it accounts for. Free.

**Inputs**

- Goal number (`sdg_id`, text, required): The goal to fetch, 1 to 17. One of: `1` (1. No poverty), `2` (2. Zero hunger), `3` (3. Good health and well-being), `4` (4. Quality education), `5` (5. Gender equality), `6` (6. Clean water and sanitation), `7` (7. Affordable and clean energy), `8` (8. Decent work and economic growth), `9` (9. Industry, innovation and infrastructure), `10` (10. Reduced inequalities), and 7 more.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `description`, `image_url`, `image_thumbnail_url`, `works_count`, `cited_by_count`, `works_api_url`, `created_date`, `updated_date`.

**Outputs**

- `sdg` (object)

**Example output**

```json
{
  "sdg": {
    "cited_by_count": 508105277,
    "description": "Ensure healthy lives and promote well-being for all at all ages.",
    "display_name": "Good health and well-being",
    "id": "https://openalex.org/sdgs/3",
    "ids": {
      "openalex": "https://openalex.org/sdgs/3",
      "un": "https://metadata.un.org/sdg/3"
    },
    "works_count": 26198823
  }
}
```

### Get a topic

Get one topic by its OpenAlex id: what it covers, the keywords associated with it, its subfield, field and domain, its sibling topics, and how many works and citations it accounts for. Free.

**Inputs**

- Topic ID (`topic_id`, text, required): The topic to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `description`, `keywords`, `subfield`, `field`, `domain`, `siblings`, `works_count`, and 4 more.

**Outputs**

- `topic` (object)

**Example output**

```json
{
  "topic": {
    "cited_by_count": 904306,
    "display_name": "scientometrics and bibliometrics research",
    "domain": {
      "display_name": "Social Sciences",
      "id": "https://openalex.org/domains/2"
    },
    "field": {
      "display_name": "Decision Sciences",
      "id": "https://openalex.org/fields/18"
    },
    "id": "https://openalex.org/T10102",
    "subfield": {
      "display_name": "Statistics, Probability and Uncertainty",
      "id": "https://openalex.org/subfields/1804"
    },
    "works_count": 101356
  }
}
```

### Get a vocabulary entry

Get one entry from a controlled vocabulary by its code: the country US, the language fr, the licence cc-by, the work type preprint. Returns what the value means and how many works it covers, plus a ready-made link to them. Free.

**Inputs**

- Vocabulary (`vocabulary`, text, required): Which value set the code belongs to. One of: `work-types` (Work types (article, dataset, preprint...)), `source-types` (Source types (journal, repository...)), `institution-types` (Institution types (education, company...)), `countries`, `continents`, `languages`, `licenses` (Licences), `indexes` (Indexes (Crossref, PubMed, DOAJ, arXiv...)).
- Code (`entry_id`, text, required): The entry's code, as it appears in a filter: US, fr, cc-by, preprint, Q46.

**Outputs**

- `entry` (object)
- `vocabulary` (text)

**Example output**

```json
{
  "entry": {
    "cited_by_count": 1056294537,
    "display_name": "United States",
    "id": "https://openalex.org/countries/US",
    "works_count": 37907393
  },
  "vocabulary": "countries"
}
```

### Get a work

Get one work in full by its identifier: an OpenAlex id, a DOI, a PubMed id, a PMC id or a Microsoft Academic id. Returns everything OpenAlex holds about it, including the abstract rebuilt into readable text, every author with their affiliations, where free copies live, its topics, the works it cites and its citation counts. Single lookups are free, however many a workflow makes.

**Inputs**

- Work ID or DOI (`work_id`, text, required): The work to fetch. An OpenAlex id, a DOI, pmid:29456894 or pmcid:PMC5815332.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record, which for a heavily cited work can be hundreds of kilobytes. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `doi`, `title`, `display_name`, `type`, `language`, `publication_date`, `publication_year`, `biblio` (Volume, issue and page numbers), and 39 more.

**Outputs**

- `work` (object)

**Example output**

```json
{
  "work": {
    "abstract": "Despite growing interest in Open Access (OA) to scholarly literature, there is an unmet need for large-scale, up-to-date, and reproducible studies assessing the prevalence and characteristics of OA.",
    "cited_by_count": 1245,
    "display_name": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
    "doi": "https://doi.org/10.7717/peerj.4375",
    "id": "https://openalex.org/W2741809807",
    "language": "en",
    "open_access": {
      "any_repository_has_fulltext": true,
      "is_oa": true,
      "oa_status": "gold",
      "oa_url": "https://doi.org/10.7717/peerj.4375"
    },
    "primary_topic": {
      "display_name": "scientometrics and bibliometrics research",
      "id": "https://openalex.org/T10102"
    },
    "publication_date": "2018-02-13",
    "publication_year": 2018,
    "title": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
    "type": "article"
  }
}
```

### Get an author

Get one researcher's profile by OpenAlex id or ORCID: their name and its variants, every affiliation with the years, their topics, how many works they have, how often they are cited, their h-index and i10-index, and citations per year for the last decade. Free.

**Inputs**

- Author ID or ORCID (`author_id`, text, required): The author to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole profile. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `display_name_alternatives`, `orcid`, `full_name`, `raw_author_names`, `affiliations`, `last_known_institutions` (Current affiliations), `topics` (Topics (up to three, ranked)), and 8 more.

**Outputs**

- `author` (object)

**Example output**

```json
{
  "author": {
    "cited_by_count": 4476,
    "display_name": "Jason R Priem",
    "id": "https://openalex.org/A5023888391",
    "orcid": "https://orcid.org/0000-0001-6187-6610",
    "summary_stats": {
      "2yr_mean_citedness": 1.0,
      "h_index": 18,
      "i10_index": 21
    },
    "works_count": 65
  }
}
```

### Get an institution

Get one organization by OpenAlex id or ROR: its names and acronyms, where it is, what kind of organization it is, the organizations above and below it, its repositories, the topics it publishes on, and its output and citation counts year by year. Free.

**Inputs**

- Institution ID or ROR (`institution_id`, text, required): The organization to fetch.
- Details to return (`select_fields`, list): Which fields to return. Leave empty for the whole record. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `display_name_acronyms`, `display_name_alternatives`, `ror`, `country_code`, `type`, `type_id`, `lineage` (Ids of this and its parent organizations), and 19 more.

**Outputs**

- `institution` (object)

**Example output**

```json
{
  "institution": {
    "cited_by_count": 67679300,
    "country_code": "US",
    "display_name": "University of Michigan",
    "id": "https://openalex.org/I27837315",
    "ror": "https://ror.org/00jmfr291",
    "type": "education",
    "works_count": 992025
  }
}
```

### List a collection's entities

List the ids inside a saved collection, up to 200 at a time. Paged separately from the collection itself so a 1,000-entity list does not arrive attached to every read of its name. Needs an API key.

**Inputs**

- Collection ID (`collection_id`, text, required): The collection whose contents to list.
- Results per page (`per_page`, number): How many ids to return, up to 200. Defaults to 200. From 1 to 200.

**Outputs**

- `collection_id` (text)
- `entity_count` (number)
- `entity_ids` (list)
- `entity_type` (text)
- `total_entity_count` (number)

**Example output**

```json
{
  "collection_id": "col_beNWUTw6qY",
  "entity_count": 2,
  "entity_ids": [
    "https://openalex.org/W2755968057",
    "https://openalex.org/W2741809807"
  ],
  "entity_type": "works",
  "total_entity_count": 2
}
```

### List a vocabulary

List one of OpenAlex's eight fixed value sets: work types, source types, institution types, countries, continents, languages, licences or indexes. These are the exact values filters are written against, each with how many works it covers - what a workflow reads to build a picker, or to check a code before filtering on it.

**Inputs**

- Vocabulary (`vocabulary`, text, required): Which value set to list. One of: `work-types` (Work types (article, dataset, preprint...)), `source-types` (Source types (journal, repository...)), `institution-types` (Institution types (education, company...)), `countries`, `continents`, `languages`, `licenses` (Licences), `indexes` (Indexes (Crossref, PubMed, DOAJ, arXiv...)).
- Search term (`search`, text): Words to look for in an entry's name.
- Sort by (`sort_by`, text): Which field to order by - works_count, cited_by_count or display_name.
- Sort direction (`sort_direction`, text): Which way round to sort. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many entries to return, 1 to 100. Defaults to 25; most of these vocabularies fit in one page of 100. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. Only countries and languages run past one page. At least 1.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)
- `vocabulary` (text)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "countries",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 1056294537,
      "display_name": "United States",
      "id": "https://openalex.org/countries/US",
      "works_count": 37907393
    }
  ],
  "total_count": 240,
  "vocabulary": "countries"
}
```

### List saved collections

List the saved collections on this connection's OpenAlex account. A collection is a private, named list of entities of one type - the papers you are tracking for a grant, the journals in your library's subscription - and its id drops straight into a filter, so you name a thousand journals once instead of in every request. Needs an API key.

**Inputs**

- Containing this entity (`contains_entity_id`, text): Only the collections that already hold this entity - the check before adding it again.
- Results per page (`per_page`, number): How many collections to return, 1 to 100. Defaults to 25. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. At least 1.

**Outputs**

- `collection_count` (number)
- `collections` (list)
- `page` (number)
- `per_page` (number)
- `total_count` (number)
- `total_pages` (number)

**Example output**

```json
{
  "collection_count": 1,
  "collections": [
    {
      "created_at": "2026-05-26T14:00:00",
      "description": "Papers I'm tracking for the altmetrics review",
      "display_name": "My altmetrics papers",
      "entity_count": 2,
      "entity_type": "works",
      "id": "col_beNWUTw6qY",
      "updated_at": "2026-05-26T14:00:00",
      "user_id": "user-TSamuHxDbnhn"
    }
  ],
  "page": 1,
  "per_page": 25,
  "total_count": 3,
  "total_pages": 1
}
```

### List subject levels

List the levels of OpenAlex's subject hierarchy above a topic: 4 domains, 26 fields or 252 subfields, whichever you pick. Small enough to browse in one call, and the right handles for grouping a large result set - works per field, authors per domain. Each entry carries its parents, its children and its share of the literature.

**Inputs**

- Level (`level`, text, required): Which level of the hierarchy to list. One of: `domains` (Domains (4: the top level)), `fields` (Fields (26)), `subfields` (Subfields (252)).
- Search term (`search`, text): Words to look for in the name and description.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- Parent IDs (`parent_ids`, list): Only entries under these parents: domain ids when listing fields, field ids when listing subfields. Domains are the top level and have no parent.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `display_name_alternatives`, `description`, `fields`, `siblings`, `works_count`, `cited_by_count`, `works_api_url`, and 6 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `domain.id`, `field.id`, `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `level` (text)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "fields",
  "group_count": 0,
  "groups": [],
  "level": "fields",
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 160069587,
      "description": "study of computation",
      "display_name": "Computer Science",
      "id": "https://openalex.org/fields/17",
      "works_count": 23408426
    }
  ],
  "total_count": 26
}
```

### List Sustainable Development Goals

List the United Nations' 17 Sustainable Development Goals as OpenAlex holds them, each with how many works a classifier has tagged to it and how often those works are cited. There are exactly 17, so one call returns them all. This is the vocabulary behind questions like 'how much of our research is about clean water'.

**Inputs**

- Search term (`search`, text): Words to look for in a goal's name or description.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `description`, `image_url`, `image_thumbnail_url`, `works_count`, `cited_by_count`, `works_api_url`, `created_date`, `updated_date`.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "sdgs",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 508105277,
      "description": "Ensure healthy lives and promote well-being for all at all ages.",
      "display_name": "Good health and well-being",
      "id": "https://openalex.org/sdgs/3",
      "ids": {
        "openalex": "https://openalex.org/sdgs/3",
        "un": "https://metadata.un.org/sdg/3"
      },
      "works_count": 26198823
    }
  ],
  "total_count": 17
}
```

### List works a work cites

List the works a given work cites - its bibliography, backwards in time. The mirror of List works citing a work, and the way to pull a paper's reference list as full records rather than bare ids.

**Inputs**

- Work ID or DOI (`work_id`, text, required): The work whose reference list to fetch.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `relevance_score` (Search relevance), `cited_by_count` (Citation count), `publication_date` (Publication date), `publication_year` (Publication year), `display_name` (Name (A-Z)), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `doi`, `title`, `display_name`, `type`, `language`, `publication_date`, `publication_year`, `biblio` (Volume, issue and page numbers), and 39 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `publication_year`, `type`, `open_access.is_oa`, `open_access.oa_status`, `language`, `is_retracted`, `has_fulltext`, `indexed_in`, `authorships.author.id`, `authorships.institutions.id`, and 20 more.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)
- `work_id` (text)

**Example output**

```json
{
  "applied_filter": "cited_by:W2741809807",
  "cost_usd": 0.0001,
  "entity": "works",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "abstract": "Despite growing interest in Open Access (OA) to scholarly literature, there is an unmet need for large-scale, up-to-date, and reproducible studies assessing the prevalence and characteristics of OA.",
      "cited_by_count": 1245,
      "display_name": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "doi": "https://doi.org/10.7717/peerj.4375",
      "id": "https://openalex.org/W2741809807",
      "language": "en",
      "open_access": {
        "any_repository_has_fulltext": true,
        "is_oa": true,
        "oa_status": "gold",
        "oa_url": "https://doi.org/10.7717/peerj.4375"
      },
      "primary_topic": {
        "display_name": "scientometrics and bibliometrics research",
        "id": "https://openalex.org/T10102"
      },
      "publication_date": "2018-02-13",
      "publication_year": 2018,
      "title": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "type": "article"
    }
  ],
  "total_count": 43,
  "work_id": "W2741809807"
}
```

### List works citing a work

List the works that cite a given work - its citations, forwards in time. Use it to see who picked a paper up, to watch for new citations on a schedule, or to build a citation network one hop at a time. Sorts, filters and pages like any other work search.

**Inputs**

- Work ID or DOI (`work_id`, text, required): The work whose citations to list.
- Cited on or after (`from_publication_date`, date): Only citing works published on or after this date - the filter for 'what cited this since last month'.
- Cited on or before (`to_publication_date`, date): Only citing works published on or before this date.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `relevance_score` (Search relevance), `cited_by_count` (Citation count), `publication_date` (Publication date), `publication_year` (Publication year), `display_name` (Name (A-Z)), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `doi`, `title`, `display_name`, `type`, `language`, `publication_date`, `publication_year`, `biblio` (Volume, issue and page numbers), and 39 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `publication_year`, `type`, `open_access.is_oa`, `open_access.oa_status`, `language`, `is_retracted`, `has_fulltext`, `indexed_in`, `authorships.author.id`, `authorships.institutions.id`, and 20 more.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)
- `work_id` (text)

**Example output**

```json
{
  "applied_filter": "cites:W2741809807",
  "cost_usd": 0.0001,
  "entity": "works",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "abstract": "Despite growing interest in Open Access (OA) to scholarly literature, there is an unmet need for large-scale, up-to-date, and reproducible studies assessing the prevalence and characteristics of OA.",
      "cited_by_count": 1245,
      "display_name": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "doi": "https://doi.org/10.7717/peerj.4375",
      "id": "https://openalex.org/W2741809807",
      "language": "en",
      "open_access": {
        "any_repository_has_fulltext": true,
        "is_oa": true,
        "oa_status": "gold",
        "oa_url": "https://doi.org/10.7717/peerj.4375"
      },
      "primary_topic": {
        "display_name": "scientometrics and bibliometrics research",
        "id": "https://openalex.org/T10102"
      },
      "publication_date": "2018-02-13",
      "publication_year": 2018,
      "title": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "type": "article"
    }
  ],
  "total_count": 1230,
  "work_id": "W2741809807"
}
```

### Remove entities from a collection

Remove entities from a saved collection in one call. The entities themselves are untouched; only their membership goes. Needs an API key.

**Inputs**

- Collection ID (`collection_id`, text, required): The collection to remove from.
- Entity IDs (`entity_ids`, list, required): The entities to remove.

**Outputs**

- `collection_id` (text)
- `entity_ids` (list)
- `removed_count` (number)

**Example output**

```json
{
  "collection_id": "col_beNWUTw6qY",
  "entity_ids": [
    "W2755968057"
  ],
  "removed_count": 1
}
```

### Run a query (OQL)

Run a query written in OpenAlex Query Language, which reads like a sentence: 'works where year is (2020) and cited_by_count > (100) group by type'. OQL reaches questions the filter fields cannot express - nested boolean logic, proximity search, grouping written into the query itself - and the query names its own entity, so one action covers every kind. The query object form takes the same query as JSON, which is easier to build from a program. Sent as a POST, so a systematic-review query too long for a URL still works. Every result echoes your query back in all three spellings.

**Inputs**

- Query (`query`, text, required): The query to run. OQL text, or a JSON query object if you pick that format.
- Query format (`query_format`, text): How the query above is written. Defaults to OQL. One of: `oql` (OQL: works where year is (2020)), `oqo` (Query object (JSON): {"get_rows": "works", ...}).
- Sort by (`sort_by`, text): Which field to order results by. Sorting rides alongside the query rather than inside it.
- Sort direction (`sort_direction`, text): Which way round to sort. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. Reaches the first 10,000 records; past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in.
- Details to return (`select_fields`, list): Which fields to return for each record, by name. Leave empty for the whole record.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `query` (text)
- `query_format` (text)
- `query_forms` (object)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "query",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "query": "works where year is (2020)",
  "query_format": "oql",
  "query_forms": {
    "oql": "works where year is (2020)",
    "oxurl": "/works?filter=publication_year:2020"
  },
  "result_count": 1,
  "results": [
    {
      "abstract": "Despite growing interest in Open Access (OA) to scholarly literature, there is an unmet need for large-scale, up-to-date, and reproducible studies assessing the prevalence and characteristics of OA.",
      "cited_by_count": 1245,
      "display_name": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "doi": "https://doi.org/10.7717/peerj.4375",
      "id": "https://openalex.org/W2741809807",
      "language": "en",
      "open_access": {
        "any_repository_has_fulltext": true,
        "is_oa": true,
        "oa_status": "gold",
        "oa_url": "https://doi.org/10.7717/peerj.4375"
      },
      "primary_topic": {
        "display_name": "scientometrics and bibliometrics research",
        "id": "https://openalex.org/T10102"
      },
      "publication_date": "2018-02-13",
      "publication_year": 2018,
      "title": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "type": "article"
    }
  ],
  "total_count": 11437942
}
```

### Search authors

Find researchers by name, ORCID, institution, subject or impact. Returns each profile with its ORCID, current affiliations, topics, works and citation counts and h-index. This is how you turn a person's name into the author id that Search works filters on. Profiles are assembled by matching the names printed on papers, so a common name can produce several candidates - match on ORCID whenever you have one.

**Inputs**

- Name (`search`, text): A researcher's name, or part of one. Matched against the display name and the other spellings OpenAlex has seen for them.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- ORCID iDs (`orcids`, list): Only these authors, named by ORCID - the exact way to name a researcher.
- Has an ORCID (`has_orcid`, true/false): Only authors with an ORCID on their profile. Fewer than you would expect: an ORCID only reaches OpenAlex attached to a paper's metadata.
- Institution IDs (`institution_ids`, list): Only authors whose last known affiliation is one of these institutions. OpenAlex ids or ROR ids.
- Institution types (`institution_types`, list): Only authors whose last known affiliation is this kind of organization. One or more of: `education`, `healthcare`, `company`, `archive`, `nonprofit`, `government`, `facility`, `other`.
- Countries (`country_codes`, list): Only authors whose last known institution is in these countries.
- Continents (`continents`, list): Only entities on these continents. Choosing none means anywhere. One or more of: `africa`, `antarctica`, `asia`, `europe`, `north_america` (North America), `oceania`, `south_america` (South America).
- Topic IDs (`topic_ids`, list): Only records on these topics. Topic ids look like T10017 - find them with Search topics or Autocomplete. Filtering by a subject's name never works; OpenAlex matches ids.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Minimum citations (`min_cited_by_count`, number): Only records cited at least this many times. At least 0.
- Minimum h-index (`min_h_index`, number): Only authors with at least this h-index. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed), `summary_stats.h_index` (h-index), `summary_stats.i10_index` (i10-index).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `display_name_alternatives`, `orcid`, `full_name`, `raw_author_names`, `affiliations`, `last_known_institutions` (Current affiliations), `topics` (Topics (up to three, ranked)), and 8 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `has_orcid`, `last_known_institutions.id`, `last_known_institutions.country_code`, `last_known_institutions.continent`, `last_known_institutions.type`, `topics.id`, `topics.subfield.id`, `topics.field.id`, `topics.domain.id`, `works_count`, `cited_by_count`, `summary_stats.h_index`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "authors",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 4476,
      "display_name": "Jason R Priem",
      "id": "https://openalex.org/A5023888391",
      "orcid": "https://orcid.org/0000-0001-6187-6610",
      "summary_stats": {
        "2yr_mean_citedness": 1.0,
        "h_index": 18,
        "i10_index": 21
      },
      "works_count": 65
    }
  ],
  "total_count": 3
}
```

### Search concepts (legacy)

Search concepts, the six-level subject classification OpenAlex used before topics. OpenAlex has deprecated them in favour of topics and no longer maintains them, but they are still attached to every work, so this is the way to reproduce or continue an analysis built on them. For anything new, use Search topics.

**Inputs**

- Search term (`search`, text): Words to look for in the concept's name and description.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- Levels (`levels`, list): Only concepts at these levels of the old hierarchy. 0 is broadest (Medicine, Physics); 5 is narrowest.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `wikidata`, `display_name`, `level`, `description`, `image_url`, `image_thumbnail_url`, `international` (Name in other languages), `ancestors`, and 8 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `level`, `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "concepts",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 933341750,
      "display_name": "Medicine",
      "id": "https://openalex.org/C71924100",
      "level": 0,
      "works_count": 86486082
    }
  ],
  "total_count": 19
}
```

### Search funders

Find the organizations that pay for research: national agencies, charities, foundations and corporate funders. Search by name or filter by country. Each result carries its ROR id, how many grants it has made and how many works acknowledge it - the id you then use to filter works or grants by who paid for them.

**Inputs**

- Name (`search`, text): A funder's name, or part of one.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- ROR IDs (`rors`, list): Only these organizations, named by their ROR id - the global registry OpenAlex grounds organizations in. The exact way to name one.
- Countries (`country_codes`, list): Only funders based in these countries.
- Continents (`continents`, list): Only entities on these continents. Choosing none means anywhere. One or more of: `africa`, `antarctica`, `asia`, `europe`, `north_america` (North America), `oceania`, `south_america` (South America).
- Global South only (`is_global_south`, true/false): Only funders based in the Global South.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Minimum citations (`min_cited_by_count`, number): Only records cited at least this many times. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed), `summary_stats.h_index` (h-index).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `alternate_titles`, `description`, `country_code`, `is_global_south`, `awards_count`, `homepage_url`, `image_url`, and 8 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `country_code`, `continent`, `is_global_south`, `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "funders",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "awards_count": 2175047,
      "cited_by_count": 111490034,
      "country_code": "US",
      "display_name": "National Institutes of Health",
      "id": "https://openalex.org/F4320332161",
      "works_count": 1839960
    }
  ],
  "total_count": 2
}
```

### Search grants

Search more than 17 million research grants: what was funded, by whom, for how much and over what period. Filter by funder, grant number, funding type, recipient institution, country, start year or amount. Where a funder answers who paid, a grant answers which award - so this is the action behind 'what has this agency funded in our field since 2020'. Detail varies by source: a national grant database gives amounts, dates and a principal investigator, while a grant number lifted from a paper's funding note may give little more.

**Inputs**

- Search term (`search`, text): Words to look for in the grant's title and project description.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- Funder IDs (`funder_ids`, list): Only grants from these funders. OpenAlex ids or ROR ids - find them with Search funders.
- Grant numbers (`funder_award_ids`, list): Only these grants, named by the funder's own grant number - the string that appears in a paper's funding note.
- Funding types (`funding_types`, list): Only grants of these kinds, as the funder describes them - research, fellowship, and so on.
- Recipient institution IDs (`institution_ids`, list): Only grants awarded to these institutions.
- Recipient countries (`country_codes`, list): Only grants whose recipient institution is in these countries.
- Started in or after (`min_start_year`, number): Only grants that started in this year or later. From 1900 to 2100.
- Started in or before (`max_start_year`, number): Only grants that started in this year or earlier. From 1900 to 2100.
- Minimum amount (`min_amount`, number): Only grants worth at least this much, in the funder's own currency. Amounts are not converted between currencies, so pair this with a currency. At least 0.
- Currencies (`currencies`, list): Only grants denominated in these currencies, as three-letter ISO codes.
- Minimum funded works (`min_funded_outputs`, number): Only grants linked to at least this many works. Set it to 1 to skip the grants OpenAlex has not managed to match to any paper. At least 0.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `amount` (Award amount), `start_year` (Award start year), `end_year` (Award end year), `funded_outputs_count` (Number of funded works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `display_name`, `description`, `funder`, `funder_award_id`, `funder_scheme`, `funding_type`, `amount`, `currency`, `start_date`, and 17 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `funder.id`, `funding_type`, `provenance`, `currency`, `start_year`, `end_year`, `institution_awarded.id`, `institution_awarded.country_code`, `institution_awarded.type`, `primary_topic.field.id`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "awards",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "amount": 338786.0,
      "currency": "USD",
      "display_name": "Genetic analysis of dopaminergic neuron specification in C.elegans",
      "end_year": 2014,
      "funded_outputs_count": 0,
      "funder": {
        "display_name": "National Institutes of Health",
        "id": "https://openalex.org/F4320332161"
      },
      "funder_award_id": "2r01ns050266-06",
      "funder_scheme": "R01",
      "funding_type": "research",
      "id": "https://openalex.org/G5066037109",
      "start_date": "2004-09-15",
      "start_year": 2004
    }
  ],
  "total_count": 91
}
```

### Search institutions

Find universities, hospitals, companies, government agencies and other research organizations. Search by name or acronym, or filter by country, continent, kind of organization or size. Each result carries its ROR id, location with coordinates, parent and child organizations, the topics it publishes on, and its works and citation counts - which is what you need to turn 'MIT' into the institution id that Search works filters on.

**Inputs**

- Name (`search`, text): An organization's name, part of one, or an acronym. Also matches alternative names.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- ROR IDs (`rors`, list): Only these organizations, named by their ROR id - the global registry OpenAlex grounds organizations in. The exact way to name one.
- Has a ROR id (`has_ror`, true/false): Only organizations registered in ROR, the global registry of research organizations.
- Institution types (`institution_types`, list): Only organizations of these kinds. One or more of: `education`, `healthcare`, `company`, `archive`, `nonprofit`, `government`, `facility`, `other`.
- Countries (`country_codes`, list): Only organizations in these countries.
- Continents (`continents`, list): Only entities on these continents. Choosing none means anywhere. One or more of: `africa`, `antarctica`, `asia`, `europe`, `north_america` (North America), `oceania`, `south_america` (South America).
- Global South only (`is_global_south`, true/false): Only organizations in the Global South, as OpenAlex classifies countries.
- Topic IDs (`topic_ids`, list): Only records on these topics. Topic ids look like T10017 - find them with Search topics or Autocomplete. Filtering by a subject's name never works; OpenAlex matches ids.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Minimum citations (`min_cited_by_count`, number): Only records cited at least this many times. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed), `summary_stats.h_index` (h-index).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `display_name_acronyms`, `display_name_alternatives`, `ror`, `country_code`, `type`, `type_id`, `lineage` (Ids of this and its parent organizations), and 19 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `type`, `country_code`, `continent`, `is_global_south`, `has_ror`, `topics.id`, `topics.field.id`, `works_count`, `cited_by_count`, `summary_stats.h_index`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "institutions",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 67679300,
      "country_code": "US",
      "display_name": "University of Michigan",
      "id": "https://openalex.org/I27837315",
      "ror": "https://ror.org/00jmfr291",
      "type": "education",
      "works_count": 992025
    }
  ],
  "total_count": 8
}
```

### Search journals and repositories

Find the places works are published: journals, preprint servers, institutional repositories, conference proceedings and book series. Search by title or ISSN, or filter to build a list - every fully open-access journal listed in DOAJ, every repository in a country, the journals a publisher owns. Each result carries its ISSN, publisher, open-access status, article processing charge and impact statistics.

**Inputs**

- Title (`search`, text): A journal or repository name, or part of one. Also matches alternate titles and abbreviations.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- ISSNs (`issns`, list): Only these sources, named by ISSN - the exact way to name a journal.
- Source types (`source_types`, list): Only sources of these kinds. One or more of: `journal`, `repository`, `ebook platform`, `book series`, `conference`, `other`.
- Fully open access (`is_oa`, true/false): Only sources where every article is free to read.
- Listed in DOAJ (`is_in_doaj`, true/false): Only journals in the Directory of Open Access Journals, the curated index of peer-reviewed open journals.
- In the CWTS core collection (`is_core`, true/false): Only sources in the vetted core collection, which is the set to use for like-for-like bibliometrics.
- Countries (`country_codes`, list): Only sources based in these countries.
- Continents (`continents`, list): Only entities on these continents. Choosing none means anywhere. One or more of: `africa`, `antarctica`, `asia`, `europe`, `north_america` (North America), `oceania`, `south_america` (South America).
- Publisher or institution IDs (`host_organization_ids`, list): Only sources hosted by these organizations - a publisher id (P...) for a journal, an institution id (I...) for a repository.
- Topic IDs (`topic_ids`, list): Only records on these topics. Topic ids look like T10017 - find them with Search topics or Autocomplete. Filtering by a subject's name never works; OpenAlex matches ids.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Minimum citations (`min_cited_by_count`, number): Only records cited at least this many times. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed), `summary_stats.h_index` (h-index).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `issn_l`, `issn`, `host_organization`, `host_organization_name`, `host_organization_lineage`, `type`, `is_oa`, and 26 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `type`, `is_oa`, `is_in_doaj`, `is_core`, `country_code`, `continent`, `host_organization`, `topics.id`, `topics.field.id`, `works_count`, `cited_by_count`, `summary_stats.h_index`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "sources",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 448736,
      "display_name": "PeerJ",
      "id": "https://openalex.org/S1983995261",
      "is_in_doaj": true,
      "is_oa": true,
      "issn_l": "2167-8359",
      "type": "journal",
      "works_count": 21590
    }
  ],
  "total_count": 12
}
```

### Search keywords

Search the roughly 65,000 short phrases works are tagged with. Keywords are finer-grained than topics - 'type-1 diabetes' rather than 'Diabetes and Metabolic Disease' - so they are the better handle on a narrow slice of the literature. Each comes back with how many works carry it.

**Inputs**

- Search term (`search`, text): Words to look for in the keyword's name.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `display_name`, `works_count`, `cited_by_count`, `works_api_url`, `created_date`, `updated_date`.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "keywords",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 47593799,
      "display_name": "Machine learning",
      "id": "https://openalex.org/keywords/machine-learning",
      "works_api_url": "https://api.openalex.org/works?filter=keywords.id:keywords/machine-learning",
      "works_count": 2030113
    }
  ],
  "total_count": 31
}
```

### Search publishers

Find publishing companies and the imprints beneath them, from Elsevier and Springer Nature down to a single university press. Publishers nest: level 0 is a root company and each level below is a division or imprint, so filter by level to compare like with like. Each result carries its countries, its parent, and how many works and citations it accounts for.

**Inputs**

- Name (`search`, text): A publisher's name, or part of one.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- ROR IDs (`rors`, list): Only these organizations, named by their ROR id - the global registry OpenAlex grounds organizations in. The exact way to name one.
- Countries (`country_codes`, list): Only publishers operating in these countries.
- Hierarchy levels (`hierarchy_levels`, list): Only publishers at these levels. 0 is a root company; 1 and below are its divisions and imprints.
- Parent publisher IDs (`parent_publisher_ids`, list): Only publishers directly beneath these ones - the way to list a company's imprints.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Minimum citations (`min_cited_by_count`, number): Only records cited at least this many times. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `alternate_titles`, `hierarchy_level`, `parent_publisher`, `lineage` (Ids of this and its parent organizations), `country_codes`, `homepage_url`, `image_url`, and 9 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `country_codes`, `hierarchy_level`, `parent_publisher`, `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "publishers",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 649222945,
      "country_codes": [
        "NL"
      ],
      "display_name": "Elsevier BV",
      "hierarchy_level": 0,
      "id": "https://openalex.org/P4310320990",
      "works_count": 24213449
    }
  ],
  "total_count": 4
}
```

### Search topics

Search the roughly 4,500 subjects OpenAlex classifies every work into. Topics sit at the bottom of a four-level hierarchy - domain, then field, then subfield, then topic - and each one comes back with its keywords, its place in that hierarchy and how many works carry it. Use this to turn a subject you can describe into the topic id that Search works filters on; filtering by a subject's name never works.

**Inputs**

- Search term (`search`, text): Words to look for in the topic's name and description.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- Domain IDs (`domain_ids`, list): Only topics inside these domains, the four top-level branches. List them with List subject levels.
- Field IDs (`field_ids`, list): Only topics inside these fields, of which there are 26.
- Subfield IDs (`subfield_ids`, list): Only topics inside these subfields, of which there are 252.
- Minimum number of works (`min_works_count`, number): Only records with at least this many works to their name. At least 0.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `display_name` (Name (A-Z)), `cited_by_count` (Citation count), `works_count` (Number of works), `relevance_score` (Search relevance), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `display_name`, `description`, `keywords`, `subfield`, `field`, `domain`, `siblings`, `works_count`, and 4 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `domain.id`, `field.id`, `subfield.id`, `works_count`, `cited_by_count`.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": null,
  "cost_usd": 0.0001,
  "entity": "topics",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "cited_by_count": 904306,
      "display_name": "scientometrics and bibliometrics research",
      "domain": {
        "display_name": "Social Sciences",
        "id": "https://openalex.org/domains/2"
      },
      "field": {
        "display_name": "Decision Sciences",
        "id": "https://openalex.org/fields/18"
      },
      "id": "https://openalex.org/T10102",
      "subfield": {
        "display_name": "Statistics, Probability and Uncertainty",
        "id": "https://openalex.org/subfields/1804"
      },
      "works_count": 101356
    }
  ],
  "total_count": 6
}
```

### Search works

Search and filter OpenAlex's catalogue of scholarly works: journal articles, preprints, books, datasets, dissertations and more. Search the title, abstract and full text by keyword or by meaning, then narrow by publication date, work type, open-access status, language, author, institution, country, journal, topic, funder, UN Sustainable Development Goal, licence or citation count. Sort by citations or date, page through any number of results, take a random sample, or turn the whole thing into counts with 'Count by' - works per year, per country, per journal.

**Inputs**

- Search term (`search`, text): Words to look for in the title, abstract and full text. Supports quoted phrases and uppercase AND, OR and NOT. Leave empty to filter without searching, which is also ten times cheaper.
- Search mode (`search_mode`, text): How the search term is matched. Keywords is the default and the one to use unless you need something else. Only one mode applies per request. One of: `smart` (Keywords (matches word stems; supports AND/OR/NOT)), `exact` (Exact words (no stemming; the only mode wildcards work in)), `semantic` (By meaning (AI; best for a paragraph-long description)).
- Published on or after (`from_publication_date`, date): Only works published on or after this date.
- Published on or before (`to_publication_date`, date): Only works published on or before this date.
- Work types (`work_types`, list): Only works of these types. Choosing none means every type, which includes paratext such as covers and tables of contents. One or more of: `article`, `book`, `book-chapter`, `book-review`, `conference-abstract`, `conference-paper`, `data-paper`, `dataset`, `dissertation`, `editorial`, and 15 more.
- Open access only (`is_open_access`, true/false): Only works with a free-to-read copy somewhere. Tick for open access, untick for paywalled, leave empty for both.
- Open access types (`oa_statuses`, list): Only works whose openness is one of these. More precise than the open-access checkbox: gold is published open in a fully open journal, green is a free copy in a repository. One or more of: `diamond` (Diamond: free to read, free to publish), `gold` (Gold: published open in a fully open journal), `green` (Green: free in a repository), `hybrid` (Hybrid: open in a subscription journal), `bronze` (Bronze: free to read, no open licence), `closed` (Closed: no free copy).
- Languages (`languages`, list): Only works whose title and abstract are in these languages.
- Author countries (`country_codes`, list): Only works with an author affiliated in these countries.
- Continents (`continents`, list): Only entities on these continents. Choosing none means anywhere. One or more of: `africa`, `antarctica`, `asia`, `europe`, `north_america` (North America), `oceania`, `south_america` (South America).
- Institution IDs (`institution_ids`, list): Only works with an author at these institutions. OpenAlex ids (I27837315) or ROR ids both work - find them with Search institutions or Autocomplete.
- Institution types (`institution_types`, list): Only works with an author at an institution of these kinds - universities, hospitals, companies and so on. One or more of: `education`, `healthcare`, `company`, `archive`, `nonprofit`, `government`, `facility`, `other`.
- Author IDs (`author_ids`, list): Only works by these authors. OpenAlex ids (A5023888391) or ORCID iDs both work. Look the author up first: filtering by a name never works, because names are ambiguous.
- Journal / repository IDs (`source_ids`, list): Only works whose main copy sits in these sources. OpenAlex ids (S1983995261) or an ISSN both work.
- Source types (`source_types`, list): Only works published in this kind of venue - a journal, a repository, a conference. One or more of: `journal`, `repository`, `ebook platform`, `book series`, `conference`, `other`.
- Topic IDs (`topic_ids`, list): Only records on these topics. Topic ids look like T10017 - find them with Search topics or Autocomplete. Filtering by a subject's name never works; OpenAlex matches ids.
- Funder IDs (`funder_ids`, list): Only works acknowledging these funders. OpenAlex ids (F4320332161) or ROR ids both work.
- Sustainable Development Goals (`sdgs`, list): Only works a classifier tagged as relevant to these UN goals. One or more of: `1` (1. No poverty), `2` (2. Zero hunger), `3` (3. Good health and well-being), `4` (4. Quality education), `5` (5. Gender equality), `6` (6. Clean water and sanitation), `7` (7. Affordable and clean energy), `8` (8. Decent work and economic growth), `9` (9. Industry, innovation and infrastructure), `10` (10. Reduced inequalities), and 7 more.
- Licences (`licenses`, list): Only works with a copy under one of these licences, anywhere. The filter to use when you need works you are allowed to reuse. One or more of: `cc-by`, `cc-by-sa`, `cc-by-nd`, `cc-by-nc`, `cc-by-nc-sa`, `cc-by-nc-nd`, `public-domain`, `mit`, `apache-2-0`, `gpl-v2`, and 4 more.
- Indexed in (`indexed_in`, list): Only works listed in these bibliographic indexes. One or more of: `crossref`, `pubmed`, `datacite`, `doaj`, `arxiv`.
- Minimum citations (`min_cited_by_count`, number): Only records cited at least this many times. At least 0.
- Full text searched (`has_fulltext`, true/false): Only works whose full text OpenAlex has indexed, so the search term is matched against the whole paper rather than the title and abstract.
- Has an abstract (`has_abstract`, true/false): Only works that carry an abstract. Worth ticking when a later step summarises or classifies what comes back.
- Retracted (`is_retracted`, true/false): Tick for retracted works only, untick to exclude them, leave empty for both.
- Saved collection (`collection_id`, text): Narrow the results to the entities in one of your saved OpenAlex collections. Needs an API key on this connection: without one OpenAlex answers with no results rather than an error, so an empty result here usually means the key is missing. The collection also has to hold this kind of entity.
- Which corpus (`corpus`, text): Which body of works to search. The curated core is the default and is what published counts refer to; the expansion corpus adds roughly 190 million lower-confidence records, mostly datasets and single-repository entries. One of: `core` (Curated core only (the default)), `all` (Core plus the expansion corpus), `expansion` (The expansion corpus only).
- Extra filters (advanced) (`filters`, text): Any OpenAlex filter this action does not already offer a field for, written the API's way: field:value, several separated by commas, | between values for 'any of', ! in front for 'not'. Merged with whatever the fields above set. The full filter list is in OpenAlex's docs.
- Sort by (`sort_by`, text): How to order the results. Leave empty for OpenAlex's own default, which is search relevance when there is a search term and id order otherwise. One of: `relevance_score` (Search relevance), `cited_by_count` (Citation count), `publication_date` (Publication date), `publication_year` (Publication year), `display_name` (Name (A-Z)), `created_date` (Date added to OpenAlex), `updated_date` (Date last changed).
- Sort direction (`sort_direction`, text): Which way round to sort. OpenAlex sorts ascending unless told otherwise, so pick highest/newest first for a top-of-the-list query. One of: `desc` (Highest / newest first), `asc` (Lowest / oldest first).
- Results per page (`per_page`, number): How many records to return, 1 to 100. Defaults to 25. Asking for 100 is the cheapest way to read a lot: every page costs the same. From 1 to 100.
- Page (`page`, number): Which page to return, counting from 1. This way of paging reaches the first 10,000 records only (page times page size); past that, use the cursor. At least 1.
- Cursor (`cursor`, text): Pages past the 10,000-record limit. Send * on the first step, then feed the previous step's next_cursor back in. next_cursor comes back empty on the last page. Use this or Page, not both.
- Random sample size (`sample`, number): Return this many records drawn at random from everything that matches, instead of the first page. Up to 10,000. From 1 to 10000.
- Random seed (`seed`, number): Makes a random sample repeatable: the same seed returns the same records. Only used alongside Random sample size. At least 0.
- Details to return (`select_fields`, list): Which fields to return for each record. Leave empty for the whole record, which can be very large. The id is always included. One or more of: `id`, `ids` (External ids (DOI, PubMed, MAG...)), `doi`, `title`, `display_name`, `type`, `language`, `publication_date`, `publication_year`, `biblio` (Volume, issue and page numbers), and 39 more.
- Count by (instead of listing) (`group_by`, text): Return counts instead of records: how many match, broken down by this field. Pick one from the list, or type any other field OpenAlex can group by. One of: `publication_year`, `type`, `open_access.is_oa`, `open_access.oa_status`, `language`, `is_retracted`, `has_fulltext`, `indexed_in`, `authorships.author.id`, `authorships.institutions.id`, and 20 more.
- Include records with no value (`include_unknown`, true/false): When grouping, also count the records that have no value for the field. Left out by default.

**Outputs**

- `applied_filter` (text)
- `cost_usd` (number)
- `entity` (text)
- `group_count` (number)
- `groups` (list)
- `next_cursor` (text)
- `page` (number)
- `per_page` (number)
- `result_count` (number)
- `results` (list)
- `total_count` (number)

**Example output**

```json
{
  "applied_filter": "is_oa:true",
  "cost_usd": 0.0001,
  "entity": "works",
  "group_count": 0,
  "groups": [],
  "next_cursor": null,
  "page": 1,
  "per_page": 25,
  "result_count": 1,
  "results": [
    {
      "abstract": "Despite growing interest in Open Access (OA) to scholarly literature, there is an unmet need for large-scale, up-to-date, and reproducible studies assessing the prevalence and characteristics of OA.",
      "cited_by_count": 1245,
      "display_name": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "doi": "https://doi.org/10.7717/peerj.4375",
      "id": "https://openalex.org/W2741809807",
      "language": "en",
      "open_access": {
        "any_repository_has_fulltext": true,
        "is_oa": true,
        "oa_status": "gold",
        "oa_url": "https://doi.org/10.7717/peerj.4375"
      },
      "primary_topic": {
        "display_name": "scientometrics and bibliometrics research",
        "id": "https://openalex.org/T10102"
      },
      "publication_date": "2018-02-13",
      "publication_year": 2018,
      "title": "The state of OA: a large-scale analysis of the prevalence and impact of Open Access articles",
      "type": "article"
    }
  ],
  "total_count": 32540
}
```

### Translate and check a query

Translate a query between the three ways OpenAlex spells one - readable OQL, a JSON query object, and a classic /works?filter=... URL - and validate it, without running it. An invalid query comes back with the character position and a suggested fix rather than a silent empty result. Costs nothing at all, so it is the cheap check before spending credits, and the way to turn a URL somebody sent you into something readable.

**Inputs**

- Query (`query`, text, required): The query to translate and check.
- Query format (`query_format`, text): How the query above is written. Defaults to OQL. The result carries all three spellings whichever you send. One of: `oql` (OQL: works where year is (2020)), `oqo` (Query object (JSON): {"get_rows": "works", ...}), `oxurl` (Classic URL: /works?filter=publication_year:2020).

**Outputs**

- `errors` (list)
- `is_valid` (true/false)
- `oql` (text)
- `oqo` (object)
- `oxurl` (text)
- `warnings` (list)

**Example output**

```json
{
  "errors": [],
  "is_valid": true,
  "oql": "works where year is (2020)",
  "oqo": {
    "filter_rows": [
      {
        "column_id": "publication_year",
        "value": 2020
      }
    ],
    "get_rows": "works"
  },
  "oxurl": "/works?filter=publication_year:2020",
  "warnings": []
}
```

### Update a saved collection

Rename a saved collection, change its description, or change what kind of entity it holds. Only the fields you fill in change. The entity type can only be changed while the collection is empty. Needs an API key.

**Inputs**

- Collection ID (`collection_id`, text, required): The collection to update.
- New name (`display_name`, text): A new name, up to 30 characters. Leave empty to keep it.
- New description (`description`, text): New notes, up to 500 characters. Leave empty to keep what is there.
- New kind of entity (`entity_type`, text): Change what the collection holds. Only possible while it is empty. One of: `works`, `authors`, `sources`, `institutions`, `topics`, `sdgs`, `funders`, `publishers`, `keywords`, `concepts`.

**Outputs**

- `collection` (object)

**Example output**

```json
{
  "collection": {
    "created_at": "2026-05-26T14:00:00",
    "description": "Papers I'm tracking for the altmetrics review",
    "display_name": "My altmetrics papers",
    "entity_count": 2,
    "entity_type": "works",
    "id": "col_beNWUTw6qY",
    "updated_at": "2026-05-26T14:00:00",
    "user_id": "user-TSamuHxDbnhn"
  }
}
```
