changedInput schema / properties / cursor / description
Previous value: -"Pagination cursor from a previous response. Only relevant when order is \"key\" — count-descending results have no next page. Pass the next_cursor from the previous response to advance. Omit it on the first call — an empty string is rejected, since a supplied-but-blank cursor is a caller mistake rather than a request for the first page."New value: +"Pagination cursor from a previous response. A supplied cursor selects key order even if order is omitted or \"count\". Pass the next_cursor from the previous response to advance, subject to the stop conditions below. Omit it on the first call — an empty string is rejected, since a supplied-but-blank cursor is a caller mistake rather than a request for the first page. OpenAlex can wrap a key-ordered walk to earlier groups. Stop when a page's first key repeats an earlier key, or when a page is short or empty."
changedInput schema / properties / filters / description
Previous value: -"Filter criteria (same syntax as openalex_search_entities filters). Narrows the population before aggregation. Country fields take ISO 3166-1 alpha-2 codes (\"DE\") and `language` takes ISO 639-1 codes (\"en\"); alpha-3, numeric, ISO 639-2, and English-name forms are converted — a multi-word name is one value, so \"South Korea|Japan\" ORs two countries — and a value that cannot be a country code is rejected. A multi-word value on a field matched as whole text (display_name, awards.funder_display_name, geo.city, raw_affiliation_strings) matches as one phrase (\"National Science Foundation\"; a comma, as in \"University of California, Berkeley\", is part of it, and it cannot contain a double quote of its own), \"!\" and \"|\" included, but cannot be ANDed with \"+\" in the same field. A value mixing \"|\" with an AND operator — a \"+\", or a space on a field where words mean AND — is rejected, since OpenAlex drops every \"|\" alternative that ANDs more than one value; put the AND in a second key instead. For full-text within filters, use abstract.search, title.search, or default.search — there is no bare 'search' filter key. Example: group works by year filtered to a specific topic."New value: +"Filter record object, using the same value syntax as openalex_search_entities; native string input is unavailable here. Narrows the population before aggregation. Country fields take ISO 3166-1 alpha-2 codes (\"DE\") and `language` takes ISO 639-1 codes (\"en\"); alpha-3, numeric, ISO 639-2, and English-name forms are converted — a multi-word name is one value, so \"South Korea|Japan\" ORs two countries — and a value that cannot be a country code is rejected. A multi-word value on a field matched as whole text (display_name, awards.funder_display_name, geo.city, raw_affiliation_strings) matches as one phrase (\"National Science Foundation\"; a comma, as in \"University of California, Berkeley\", is part of it, and it cannot contain a double quote of its own), \"!\" and \"|\" included, but cannot be ANDed with \"+\" in the same field. A value sent unquoted must have paired double quotes; balanced search phrases remain valid. A value mixing \"|\" with an AND operator — a \"+\", or a space on a field where words mean AND — is rejected, since OpenAlex drops every \"|\" alternative that ANDs more than one value; put the AND in a second key instead. For full-text within filters, use abstract.search, title.search, or default.search — there is no bare 'search' filter key. Example: group works by year filtered to a specific topic."
changedInput schema / properties / group_by / description
Previous value: -"Field to group by. Works examples: \"publication_year\", \"type\", \"oa_status\", \"primary_topic.field.id\", \"authorships.institutions.country_code\", \"is_retracted\". OpenAlex builds authorships.countries groups from only the first 100 authorships of each work; authorships.institutions.country_code counts every authorship. Authors: \"last_known_institutions.country_code\", \"has_orcid\". Sources: \"type\", \"is_oa\", \"country_code\". Not all fields support group_by — call openalex_describe_fields(entity_type, \"group_by\") for the groupable set."New value: +"Field to group by. Works examples: \"publication_year\", \"type\", \"oa_status\", \"primary_topic.field.id\", \"authorships.institutions.country_code\", \"is_retracted\". The native \":include_unknown\" suffix also enables include_unknown, even when the boolean is false; passing both adds the suffix once. OpenAlex builds authorships.countries groups from only the first 100 authorships of each work; authorships.institutions.country_code counts every authorship. Authors: \"last_known_institutions.country_code\", \"has_orcid\". Sources: \"type\", \"is_oa\", \"country_code\". Not all fields support group_by — call openalex_describe_fields(entity_type, \"group_by\") for the groupable set."
changedInput schema / properties / include_unknown / description
Previous value: -"Add a group for entities with no value for the grouped field. Hidden by default. That group carries `is_unknown: true`; OpenAlex keys it -111 or -111.0 on numeric fields, \"unknown\" on text fields and under order \"key\", and an ID ending in /unknown on ID fields — a sentinel, not a measured value. The key is not a filter value: passing -111 as a filter matches a numeric range, not the entities with no value. Boolean fields have no separate group — a missing value counts as false."New value: +"Add a group for entities with no value for the grouped field. Hidden by default unless group_by has the native \":include_unknown\" suffix, which enables this setting even when the boolean is false; passing both adds the suffix once. That group carries `is_unknown: true`; OpenAlex keys it -111 or -111.0 on numeric fields, \"unknown\" on text fields and under order \"key\", and an ID ending in /unknown on ID fields — a sentinel, not a measured value. The key is not a filter value: passing -111 as a filter matches a numeric range, not the entities with no value. Boolean fields have no separate group — a missing value counts as false."
changedInput schema / properties / order / description
Previous value: -"Sort order for groups. Omit or pass \"count\" (default) to return the top-N groups by count descending — no further pages. Pass \"key\" to enumerate all distinct values in key-ascending order with cursor pagination. Use \"key\" only when you need a full traversal; most analysis calls want \"count\"."New value: +"Sort order for groups. Without a cursor, omit or pass \"count\" (default) to return the top-N groups by count descending — no further pages. Pass \"key\" to enumerate distinct values in key-ascending order with cursor pagination. Boolean fields keep count order even with \"key\" and do not support cursor pagination. A supplied cursor selects key order even if order is omitted or \"count\". OpenAlex can wrap a key-ordered walk to earlier groups. Stop when a page's first key repeats an earlier key, or when a page is short or empty."
changedInput schema / properties / per_page / description
Previous value: -"Maximum groups per page (1-200). Default 200 (the upstream cap). A real top-N knob when order is count (the default) — reduce to return only the highest-count groups."New value: +"Maximum groups per page. Default 200 (the upstream cap); positive integers above 200 clamp to 200 with a notice unless OPENALEX_CLAMP_PER_PAGE=false restores rejection. A real top-N knob in count order without a cursor (the default) — reduce to return only the highest-count groups."
changedInput schema / properties / per_page / maximum
Previous value: -200New value: +9007199254740991
changedOutput schema / properties / echo / description
Previous value: -"Compact echo of the input criteria (entity_type, group_by, filters) — surfaces what was actually requested when no groups are returned."New value: +"Compact echo of the criteria (entity_type, group_by, filters) and effective include_unknown and order settings — surfaces what was actually requested when no groups are returned."
changedOutput schema / properties / error / properties / data / properties / reason / description
Previous value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: OpenAlex throttled the request for exceeding its per-second ceiling (HTTP 429). `upstream_budget_exhausted`: The OpenAlex daily usage budget is spent (HTTP 429). `upstream_plan_required`: A filter is one OpenAlex serves only on a paid plan — created_date, updated_date, or a from_/to_ form of either (HTTP 429 \"Plan upgrade required\"). `upstream_timeout`: OpenAlex did not respond within the request deadline. `upstream_unavailable`: OpenAlex was unreachable or unusable — HTTP 503, a connection failure, or a body that was empty, HTML, or unparseable JSON. `upstream_unauthorized`: OpenAlex rejected the API key (HTTP 401). `upstream_forbidden`: OpenAlex denied access to the requested resource (HTTP 403). `comma_in_filter_value`: A filter value contains a comma, which collides with the OpenAlex filter separator, on a field that takes no phrase. Free-text search filters (any `.search` key, such as title.search or abstract.search.exact) and fields matched as whole text (display_name, awards.funder_display_name, awards.funder_award_id, geo.city, geo.region, raw_affiliation_strings, block_key, parsed_longest_name, biblio fields) are exempt: a comma there is sent quoted, as part of the phrase. `invalid_country_code`: A country filter (a key ending in country_code, country_codes, or countries) holds a segment that cannot be a country code, such as a misspelled name, an unassigned number, \"unknown\", or two codes joined by a space (\"DE US\"). `mixed_and_or_in_filter_value`: A filter value puts \"|\" (OR) beside an AND operator — a \"+\", or a space on a field where words mean AND (on a country field a space is always part of a country name, and inside a language name it is part of the name). OpenAlex splits the value on \"|\" first and drops every alternative that ANDs more than one value, so no single value can carry both. `quote_in_filter_value`: A filter value sent to OpenAlex double-quoted holds a double quote inside its outer pair — a value the server quotes (a multi-word value on a field matched as whole text, or a value holding a comma on such a field or on a free-text search filter), or one the caller wrapped in double quotes on any filter but a free-text search. `upstream_invalid_params`: OpenAlex rejected an invalid group_by or filter field name (HTTP 400). `upstream_invalid_id_value`: An entity-ID filter received a value that is not an OpenAlex ID — usually a name (HTTP 400). `upstream_ungroupable_group_by`: group_by targets a field OpenAlex cannot aggregate — a raw date, a decimal score, a *.search operator, a field such as display_name, doi, or referenced_works, or a concept key on authors, which OpenAlex reports as an invalid OpenAlex ID (HTTP 400). `upstream_invalid_params_other`: OpenAlex rejected the request (HTTP 400) for a reason other than an invalid field name. `upstream_validation_failed`: OpenAlex rejected the request as semantically invalid (HTTP 422). `upstream_missing_group_by`: OpenAlex answered with its plain list shape, carrying no aggregation for the requested group_by. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `unmatched_quote_in_filter_value`: A filter value sent unquoted has an unmatched double quote. `rate_limited`: OpenAlex throttled the request for exceeding its per-second ceiling (HTTP 429). `upstream_budget_exhausted`: The OpenAlex daily usage budget is spent (HTTP 429). `upstream_plan_required`: A filter is one OpenAlex serves only on a paid plan — created_date, updated_date, or a from_/to_ form of either (HTTP 429 \"Plan upgrade required\"). `upstream_timeout`: OpenAlex did not respond within the request deadline. `upstream_unavailable`: OpenAlex was unreachable or unusable — HTTP 503, a connection failure, or a body that was empty, HTML, or unparseable JSON. `upstream_unauthorized`: OpenAlex rejected the API key (HTTP 401). `upstream_forbidden`: OpenAlex denied access to the requested resource (HTTP 403). `comma_in_filter_value`: A filter value contains a comma, which collides with the OpenAlex filter separator, on a field that takes no phrase. Free-text search filters (any `.search` key, such as title.search or abstract.search.exact) and fields matched as whole text (display_name, awards.funder_display_name, awards.funder_award_id, geo.city, geo.region, raw_affiliation_strings, block_key, parsed_longest_name, biblio fields) are exempt: a comma there is sent quoted, as part of the phrase. `invalid_country_code`: A country filter (a key ending in country_code, country_codes, or countries) holds a segment that cannot be a country code, such as a misspelled name, an unassigned number, \"unknown\", or two codes joined by a space (\"DE US\"). `mixed_and_or_in_filter_value`: A filter value puts \"|\" (OR) beside an AND operator — a \"+\", or a space on a field where words mean AND (on a country field a space is always part of a country name, and inside a language name it is part of the name). OpenAlex splits the value on \"|\" first and drops every alternative that ANDs more than one value, so no single value can carry both. `quote_in_filter_value`: A filter value sent to OpenAlex double-quoted holds a double quote inside its outer pair — a value the server quotes (a multi-word value on a field matched as whole text, or a value holding a comma on such a field or on a free-text search filter), or one the caller wrapped in double quotes on any filter but a free-text search. `upstream_invalid_params`: OpenAlex rejected an invalid group_by or filter field name (HTTP 400). `upstream_invalid_id_value`: An entity-ID filter received a value that is not an OpenAlex ID — usually a name (HTTP 400). `upstream_ungroupable_group_by`: group_by targets a field OpenAlex cannot aggregate — a raw date, a decimal score, a *.search operator, a field such as display_name, doi, or referenced_works, or a concept key on authors, which OpenAlex reports as an invalid OpenAlex ID (HTTP 400). `upstream_invalid_params_other`: OpenAlex rejected the request (HTTP 400) for a reason other than an invalid field name. `upstream_validation_failed`: OpenAlex rejected the request as semantically invalid (HTTP 422). `upstream_missing_group_by`: OpenAlex answered with its plain list shape, carrying no aggregation for the requested group_by. Other values are possible when a failure originates below the handler."
changedOutput schema / properties / error / properties / data / properties / reason / examples
Previous value: -[
- "rate_limited",
- "upstream_budget_exhausted",
- "upstream_plan_required",
- "upstream_timeout",
- "upstream_unavailable",
- "upstream_unauthorized",
- "upstream_forbidden",
- "comma_in_filter_value",
- "invalid_country_code",
- "mixed_and_or_in_filter_value",
- "quote_in_filter_value",
- "upstream_invalid_params",
- "upstream_invalid_id_value",
- "upstream_ungroupable_group_by",
- "upstream_invalid_params_other",
- "upstream_validation_failed",
- "upstream_missing_group_by"
-]New value: +[
+ "unmatched_quote_in_filter_value",
+ "rate_limited",
+ "upstream_budget_exhausted",
+ "upstream_plan_required",
+ "upstream_timeout",
+ "upstream_unavailable",
+ "upstream_unauthorized",
+ "upstream_forbidden",
+ "comma_in_filter_value",
+ "invalid_country_code",
+ "mixed_and_or_in_filter_value",
+ "quote_in_filter_value",
+ "upstream_invalid_params",
+ "upstream_invalid_id_value",
+ "upstream_ungroupable_group_by",
+ "upstream_invalid_params_other",
+ "upstream_validation_failed",
+ "upstream_missing_group_by"
+]
changedOutput schema / properties / groups / items / properties / key_display_name / description
Previous value: -"Human-readable group label as plain text, with HTML entities decoded and markup removed."New value: +"Human-readable group label as plain text, with HTML entities decoded and markup removed; null when OpenAlex supplies no label. Text output uses the group key when the label is null."
changedOutput schema / properties / groups / items / properties / key_display_name / type
Previous value: -"string"New value: +[
+ "string",
+ "null"
+]
changedOutput schema / properties / meta / properties / next_cursor / description
Previous value: -"Cursor for next page of groups. null if no more groups."New value: +"Upstream continuation cursor; null when OpenAlex supplies none. A non-null cursor does not guarantee unseen groups. OpenAlex can wrap a key-ordered walk to earlier groups. Stop when a page's first key repeats an earlier key, or when a page is short or empty."
changedOutput schema / properties / notice / description
Previous value: -"Guidance notice. Set when a first call returns no groups (recovery suggestions), when a `cursor` continuation returns none because the traversal is already finished, when the page is full and more groups likely exist (truncation signal with narrowing advice), or when works are grouped by authorships.countries, which OpenAlex counts from only the first 100 authorships of each work. Absent otherwise."New value: +"Guidance notice. Set when per_page was clamped (requested and applied sizes), on every effective key-order call (upstream wrap warning and stopping conditions), when a first call returns no groups (recovery suggestions), when a cursor continuation returns none because the traversal is already finished, when a count-order page is full and more groups likely exist (truncation signal with narrowing advice), or when works are grouped by authorships.countries, which OpenAlex counts from only the first 100 authorships of each work. Absent otherwise."