# REST API: Population & Field Selection

The REST API by default does not populate any relations, media fields, components, or dynamic zones. Use the populate parameter to populate specific fields and the select parameter to return only specific fields with the query results.

💡 TIP

Strapi takes advantage of the ability of the qs (opens new window) library 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.

# Field selection

Queries can accept a fields parameter to select only some fields. By default, only the following types of fields are returned:

  • 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.

Field selection does not work on relational, media, component, or dynamic zone fields. To populate these fields, use the populate parameter.

Example request: Return only title and body fields

GET /api/users?fields[0]=title&fields[1]=body

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "test1",
        "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

const qs = require('qs');
const query = qs.stringify({
  fields: ['title', 'body'],
}, {
  encodeValuesOnly: true, // prettify URL
});

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

💡 TIP

By default, fields are selected except relations, media, dynamic zones, and components, but you can specify a wildcard * instead of an array.

# Population

Queries can accept a populate parameter to populate various field types:

It is also possible to combine population with multiple operators among various other operators to have much more control over the population.

✏️ NOTE

  • By default Strapi will not populate any type of fields.
  • It's currently not possible to return just an array of IDs. This is something that is currently under discussion

# Relation & Media fields

Queries can accept a populate parameter to explicitly define which fields to populate, with the following syntax option examples.

✋ CAUTION

If the Users & Permissions plugin is installed, the find permission must be enabled for the content-types that are being populated. If a role doesn't have access to a content-type it will not be populated.

# Populate 1 level for all relations

To populate one-level deep for all relations, use the * wildcard in combination with the populate parameter:

Example request

GET /api/articles?populate=%2A

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "Test Article",
        "slug": "test-article",
        "body": "Test 1",
        // ...
        "headerImage": {
          "data": {
            "id": 1,
            "attributes": {
              "name": "17520.jpg",
              "alternativeText": "17520.jpg",
              "formats": {
                // ...
              },
              // ...
            }
          }
        },
        "author": {
          // ...
        },
        "categories": {
          // ...
        }
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

const qs = require('qs');
const query = qs.stringify({
  populate: '*', 
}, {
  encodeValuesOnly: true, // prettify URL
});

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

# Populate 1 level

To populate only specific relations one-level deep, use the relation name (e.g. categories) in combination with the populate parameter.

Example request: populate categories

GET /api/articles?populate[0]=categories

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "Test Article",
        // ...
        "categories": {
          "data": [
            {
              "id": 1,
              "attributes": {
                "name": "Food",
                // ...
              }
            }
          ]
        }
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

const qs = require('qs');
const query = qs.stringify({
  populate: ['categories'], 
}, {
  encodeValuesOnly: true, // prettify URL
});

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

# Populate 2 levels

To populate specific relations, one or several levels deep, use the LHS bracket notation for fields names in combination with the populate parameter.

Example request: populate author and author.company

GET /api/articles?populate[author][populate][0]=company

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "Test Article",
        // ...
        "author": {
          "data": {
            "id": 1,
            "attributes": {
              "name": "Kai Doe",
              // ...
              "company": {
                "data": {
                  "id": 1,
                  "attributes": {
                    "name": "Strapi",
                    // ...
                  }
                }
              }
            }
          }
        }
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

const qs = require('qs');
const query = qs.stringify({
  populate: {
    author: {
      populate: ['company'],
    }
  } 
}, {
  encodeValuesOnly: true, // prettify URL
});

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

# Component & Dynamic Zones

The population parameter is used to explicitly define which Dynamic zones, components, and nested components to populate.

# Deeply populate a 2-level component & media

Example request

GET /api/articles?populate[0]=seoData&populate[1]=seoData.sharedImage&populate[2]=seoData.sharedImage.media

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "Test Article",
        // ...
        "seoData": {
          "id": 1,
          "metaTitle": "Test Article",
          // ...
          "sharedImage": {
            "id": 1,
            "alt": "starSky",
            "media": {
              "data": [
                {
                  "id": 1,
                  "attributes": {
                    "name": "17520.jpg",
                    "formats": {
                      // ...
                    },
                    // ...
                  }
                }
              ]
            }
          }
        }
      }
    }
  ],
  "meta": {
    // ...
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

const qs = require('qs');
const query = qs.stringify({
  populate: [
    'seoData',
    'seoData.sharedImage',
    'seoData.sharedImage.media',
  ],
}, {
  encodeValuesOnly: true, // prettify URL
});

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

# Deeply populate a dynamic zone with 2 components

Example request

GET /api/articles?populate[testDZ][populate]=%2A

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "testString": "test1",
        // ...
        "testDZ": [
          {
            "id": 3,
            "__component": "test.test-compo",
            "testString": "test1",
            "testNestedCompo": {
              "id": 3,
              "testNestedString": "testNested1"
            }
          },
          {
            "id": 1,
            "__component": "test.test-compo2",
            "testInt": 1
          }
        ]
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

const qs = require('qs');
const query = qs.stringify({
  populate: {
    testDZ: {
      populate: '*',
    },
  },
}, {
  encodeValuesOnly: true, // prettify URL
});

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

# Combining Population with other operators

By utilizing the population operator it's possible to combine other operators such as field selection & sort & pagination in the population queries. See the following complex population examples:

# Populate with field selection

Example request

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

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "Test Article",
        "slug": "test-article",
        "headerImage": {
          "data": {
            "id": 1,
            "attributes": {
              "name": "17520.jpg",
              "url": "/uploads/17520_73c601c014.jpg"
            }
          }
        }
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

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}`);

# Populate with filtering

Example request

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

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "Test Article",
        // ...
        "categories": {
          "data": [
            {
              "id": 2,
              "attributes": {
                "name": "Cars",
                // ...
              }
            }
          ]
        }
      }
    }
  ],
  "meta": {
    // ...
  }
}
JavaScript query (built with the qs library):

qs (opens new window) can be used to build the query URL used in the example above:

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}`);