# Populate and Select

> Source: https://docs.strapi.io/cms/api/rest/populate-select

Use the `populate` parameter to include relations, media fields, components, and dynamic zones in REST API responses. Use the `fields` parameter to return only specific fields.

The [REST API](/cms/api/rest) by default does not populate any relations, media fields, components, or dynamic zones. Use the [`populate` parameter](#population) to populate specific fields. Use the [`fields` parameter](#field-selection) to return only specific fields with the query results.

:::tip

Strapi takes advantage of the ability of [the `qs` library](https://github.com/ljharb/qs) to parse nested objects to create more complex queries.

Use `qs` directly to generate complex queries instead of creating them manually. Examples in this documentation showcase how you can use `qs`.

You can also use the [interactive query builder](/cms/api/rest/interactive-query-builder) if you prefer playing with our online tool instead of generating queries with `qs` on your machine.

:::

## Field selection

Queries can accept a `fields` parameter to select only some fields. By default, the REST API only returns the following [types of fields](/cms/backend-customization/models#model-attributes):

- string types: `string`, `text`, `richtext`, `enumeration`, `email`, `password`, and `uid`,
- date types: `date`, `time`, `datetime`, and `timestamp`,
- number types: `integer`, `biginteger`, `float`, and `decimal`,
- generic types: `boolean`, `array`, and `JSON`.

| Use case              | Example parameter syntax              |
|-----------------------|---------------------------------------|
| Select a single field | `fields=name`                         |
| Select multiple fields| `fields[0]=name&fields[1]=description`|

:::note
Field selection does not work on relational, media, component, or dynamic zone fields. To populate these fields, use the [`populate` parameter](#population).
:::

#### GET /api/restaurants — Return only name and description fields

Use the fields parameter to select only specific fields in the response.

**URL:**
```
GET /api/restaurants?fields[0]=name&fields[1]=description
```

**JavaScript:**
```
const qs = require('qs');
const query = qs.stringify(
  {
    fields: ['name', 'description'],
  },
  {
    encodeValuesOnly: true, // prettify URL
  }
);

await request(\`/api/users?\${query}\`);
```

**Response 200 OK:**
```json
{
  "data": [
    {
      "id": 4,
      "Name": "Pizzeria Arrivederci",
      "Description": [
        {
          "type": "paragraph",
          "children": [
            {
              "type": "text",
              "text": "Specialized in pizza, we invite you to rediscover our classics, such as 4 Formaggi or Calzone, and our original creations such as Do Luigi or Nduja."
            }
          ]
        }
      ],
      "documentId": "lr5wju2og49bf820kj9kz8c3"
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "pageSize": 25,
      "pageCount": 1,
      "total": 4
    }
  }
}
```

## Population

The REST API by default does not populate any type of fields, so it will not populate relations, media fields, components, or dynamic zones unless you pass a `populate` parameter to populate various field types. Populated relations always return full objects; the REST API currently cannot return just an array of IDs.

:::prerequisites
The `find` permission must be enabled for the content-types that are being populated. If a role does not have access to a content-type, the content-type will not be populated (see [Users & Permissions](/cms/features/users-permissions#editing-a-role) for additional information on how to enable `find` permissions for content-types).
:::

You can use the `populate` parameter alone or [in combination with multiple operators](#combining-population-with-other-operators) for more control over the population.

:::caution
`populate=deep` plugins are [not recommended in Strapi](https://support.strapi.io/articles/8544110758-why-populate-deep-plugins-are-not-recommended-in-strapi).
:::

:::note
Large `populate` lists in the query string (many `populate[0]`, `populate[1]`, … entries) are bounded by the query parser `arrayLimit` (default: `100`). To allow a longer list, raise `arrayLimit` on the [`strapi::query` middleware](/cms/configurations/middlewares#query). Higher values increase parsing cost per request.
:::

The following table lists populate use cases with example syntax. Each row links to the Understanding populate guide for details:

| Use case  | Example parameter syntax | Detailed explanations to read |
|-----------| ---------------|-----------------------|
| Populate everything, 1 level deep, including media fields, relations, components, and dynamic zones | `populate=*`| [Populate all relations and fields, 1 level deep](/cms/api/rest/guides/understanding-populate#populate-all-relations-and-fields-1-level-deep) |
| Populate one relation,<br/>1 level deep | `populate=a-relation-name`| [Populate 1 level deep for specific relations](/cms/api/rest/guides/understanding-populate#populate-1-level-deep-for-specific-relations) |
| Populate several relations,<br/>1 level deep | `populate[0]=relation-name&populate[1]=another-relation-name&populate[2]=yet-another-relation-name`| [Populate 1 level deep for specific relations](/cms/api/rest/guides/understanding-populate#populate-1-level-deep-for-specific-relations) |
| Populate some relations, several levels deep | `populate[root-relation-name][populate][0]=nested-relation-name`| [Populate several levels deep for specific relations](/cms/api/rest/guides/understanding-populate#populate-several-levels-deep-for-specific-relations) |
| Populate a component | `populate[0]=component-name`| [Populate components](/cms/api/rest/guides/understanding-populate#populate-components) |
| Populate a component and one of its nested components | `populate[0]=component-name&populate[1]=component-name.nested-component-name`| [Populate components](/cms/api/rest/guides/understanding-populate#populate-components) |
| Populate a dynamic zone (only its first-level scalar fields) | `populate[0]=dynamic-zone-name`| [Populate dynamic zones](/cms/api/rest/guides/understanding-populate#populate-dynamic-zones) |
| Populate a dynamic zone, including component-specific fields, nested components, and relations | `populate[dynamic-zone-name][on][component-category.component-name][populate][relation-name][populate][0]=field-name`| [Populate dynamic zones](/cms/api/rest/guides/understanding-populate#populate-dynamic-zones) |

:::tip
To build complex queries with multiple-level population, use the [interactive query builder](/cms/api/rest/interactive-query-builder) tool. For more detailed explanations and examples, see the [REST API guides](/cms/api/rest/guides/intro).
:::

### Combining population with other operators

You can combine the `populate` operator with other operators such as [field selection](/cms/api/rest/populate-select#field-selection), [filters](/cms/api/rest/filters), and [sort](/cms/api/rest/sort-pagination) in the population queries.

:::note
Top-level pagination parameters (e.g., `pagination[page]` and `pagination[pageSize]`) work alongside `populate` to paginate the main query results. However, you cannot apply pagination parameters directly to populated relations to limit the number of related entries returned within each result (nested pagination on relations is not supported in the REST API).
:::

#### Populate with field selection

`fields` and `populate` can be combined.

#### GET /api/articles — Populate with field selection

Combine fields and populate parameters to select specific fields on both the main entry and its relations.

**URL:**
```
GET /api/articles?fields[0]=title&fields[1]=slug&populate[headerImage][fields][0]=name&populate[headerImage][fields][1]=url
```

**JavaScript:**
```
const qs = require('qs');
const query = qs.stringify(
  {
    fields: ['title', 'slug'],
    populate: {
      headerImage: {
        fields: ['name', 'url'],
      },
    },
  },
  {
    encodeValuesOnly: true, // prettify URL
  }
);

await request(\`/api/articles?\${query}\`);
```

**Response 200 OK:**
```json
{
  "data": [
    {
      "id": 1,
      "documentId": "h90lgohlzfpjf3bvan72mzll",
      "title": "Test Article",
      "slug": "test-article",
      "headerImage": {
        "id": 1,
        "documentId": "cf07g1dbusqr8mzmlbqvlegx",
        "name": "17520.jpg",
        "url": "/uploads/17520_73c601c014.jpg"
      }
    }
  ],
  "meta": {}
}
```

#### Populate with filtering

`filters` and `populate` can be combined.

#### GET /api/articles — Populate with filtering

Combine populate with sort and filter parameters to refine which related entries are returned.

**URL:**
```
GET /api/articles?populate[categories][sort][0]=name%3Aasc&populate[categories][filters][name][$eq]=Cars
```

**JavaScript:**
```
const qs = require('qs');
const query = qs.stringify(
  {
    populate: {
      categories: {
        sort: ['name:asc'],
        filters: {
          name: {
            $eq: 'Cars',
          },
        },
      },
    },
  },
  {
    encodeValuesOnly: true, // prettify URL
  }
);

await request(\`/api/articles?\${query}\`);
```

**Response 200 OK:**
```json
{
  "data": [
    {
      "id": 1,
      "documentId": "a1b2c3d4e5d6f7g8h9i0jkl",
      "title": "Test Article",
      "categories": {
        "data": [
          {
            "id": 2,
            "documentId": "jKd8djla9ndalk98hflj3",
            "name": "Cars"
          }
        ]
      }
    }
  ],
  "meta": {}
}
```

:::note
For many-to-many and other join-table relations, an explicit `sort` within a `populate` object overrides the default connect order. Omit `sort` to preserve the connect order (the order in which entries were associated).
:::

:::tip Performance tip
In production, always use explicit population instead of wildcards like `populate=*`. Limit population depth to 2-3 levels and consider centralizing population logic in route middlewares. See [Building High-Performance Strapi Applications](https://strapi.io/blog/building-high-performance-strapi-applications-common-pitfalls-and-best-practices) on the Strapi blog.
:::
