> ## Documentation Index
> Fetch the complete documentation index at: https://developers.openalex.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Group

> Aggregate entities into faceted counts using group_by

The `group_by` parameter aggregates entities into groups and counts how many are in each group.

```bash theme={"dark"}
# Count works by type
https://api.openalex.org/works?group_by=type
```

Response:

```json theme={"dark"}
{
  "meta": {
    "count": 246136992,
    "groups_count": 15
  },
  "group_by": [
    {
      "key": "article",
      "key_display_name": "article",
      "count": 202814957
    },
    {
      "key": "book-chapter",
      "key_display_name": "book-chapter",
      "count": 21250659
    },
    {
      "key": "dissertation",
      "key_display_name": "dissertation",
      "count": 6055973
    }
  ]
}
```

## Group properties

Each group object contains:

| Property           | Description                                  |
| ------------------ | -------------------------------------------- |
| `key`              | The OpenAlex ID or raw value for this group  |
| `key_display_name` | The display name or raw value for this group |
| `count`            | Number of entities in the group              |

### `key` vs `key_display_name`

When grouping by an OpenAlex entity, `key` is the ID and `key_display_name` is the display name:

```bash theme={"dark"}
# Group works by institution
https://api.openalex.org/works?group_by=authorships.institutions.id
```

Returns groups like:

```json theme={"dark"}
{
  "key": "https://openalex.org/I136199984",
  "key_display_name": "Harvard University",
  "count": 1234567
}
```

For non-entity values (like `level`), both `key` and `key_display_name` are the raw value.

## Including unknowns

The "unknown" group (entities without a value) is hidden by default. Add `:include_unknown` to include it:

<CodeGroup>
  ```bash Without unknowns (default) theme={"dark"}
  https://api.openalex.org/works?group_by=authorships.countries
  ```

  ```bash With unknowns theme={"dark"}
  https://api.openalex.org/works?group_by=authorships.countries:include_unknown
  ```
</CodeGroup>

### How "unknown" is keyed

The bucket's `key` depends on the field type:

| Field type      | Example                            | Unknown `key`                  |
| --------------- | ---------------------------------- | ------------------------------ |
| String / ID     | `primary_location.license`, `type` | `"unknown"`                    |
| Numeric (range) | `apc_paid.value`, `cited_by_count` | `-111` (sentinel)              |
| Boolean         | `is_oa`                            | returned as the `false` bucket |

Numeric fields use the sentinel `-111` because the aggregation bucket can't mix a string key like `"unknown"` into a numeric series. Treat any `-111` (or `-111.0`) bucket key as "unknown."

### What counts as "unknown"

A work is counted in the unknown bucket when the underlying field is missing or empty. For fields nested inside an array — for example `authorships.institutions.type` — the work is also counted as unknown when the array is present but empty (e.g. an authorship with no institutions). If you reproduce `group_by` counts in code by iterating the JSON, treat empty lists the same way to match the API's totals.

## Combining with filters

Group by and filter work together:

```bash theme={"dark"}
# Count work types for 2023 publications
https://api.openalex.org/works?filter=publication_year:2023&group_by=type

# Count open access status for a specific author
https://api.openalex.org/works?filter=author.id:A5023888391&group_by=open_access.is_oa
```

## Paging

A grouped response returns at most 200 groups per page. To page through more, use [cursor paging](/guides/page-through-results#cursor-paging): start with `cursor=*` and follow `meta.next_cursor` until it's `null`, exactly as you would for a list of results.

```bash theme={"dark"}
# First page of groups
https://api.openalex.org/works?group_by=authorships.author.id&per_page=200&cursor=*

# Next page: use the next_cursor value from the previous response
https://api.openalex.org/works?group_by=authorships.author.id&per_page=200&cursor=<next_cursor>
```

<Note>
  Basic `page`-based paging (`page=2`, …) is **not** supported with `group_by` — use cursor paging. When paging through groups, results are sorted by `key` (not by `count`).
</Note>

## Meta properties

| Property            | Description                                          |
| ------------------- | ---------------------------------------------------- |
| `meta.count`        | Total entities matching the filter                   |
| `meta.groups_count` | Number of groups in current page (or `null` if none) |

<Note>
  Due to technical limitations, `groups_count` only reports groups in the current page, not the total number of groups.
</Note>
