# Using Populate with the Document Service API

> Source: https://docs.strapi.io/cms/api/document-service/populate

Use the `populate` parameter with the Document Service API to explicitly load relations, media fields, components, and dynamic zones at one or multiple levels deep, and within `create()`, `update()`, `publish()`, and `delete()` operations.

By default the [Document Service API](/cms/api/document-service) does not populate any relations, media fields, components, or dynamic zones. This page describes how to use the `populate` parameter to populate specific fields.

:::tip
You can also use the `select` parameter to return only specific fields with the query results (see the [`select` parameter](/cms/api/document-service/fields) documentation).
:::

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

<!-- TODO: add link to populate guides (even if REST API, the same logic still applies) -->

## Relations and media fields

Queries can accept a `populate` parameter to explicitly define which fields to populate, with the following syntax option examples. This includes all relation types: one-to-many, many-to-one, many-to-many, and polymorphic relations (morphToOne, morphToMany).

### Populate 1 level for all relations

#### GET strapi.documents( — Populate 1 level for all relations

Populate one-level deep for all relations using the wildcard.

**JavaScript:**
```
const documents = await strapi.documents("api::article.article").findMany({
  populate: "*",
});
```

**Response 200 OK:**
```json
{
  [
    {
      "id": "cjld2cjxh0000qzrmn831i7rn",
      "title": "Test Article",
      "slug": "test-article",
      "body": "Test 1",
      // ...
      "headerImage": {
        "data": {
          "id": 1,
          "attributes": {
            "name": "17520.jpg",
            "alternativeText": "17520.jpg",
            "formats": {
              // ...
            }
            // ...
          }
        }
      },
      "author": {
        // ...
      },
      "categories": {
        // ...
      }
    }
    // ...
  ]
}
```

### Populate 1 level for specific relations

#### GET strapi.documents( — Populate 1 level for specific relations

Populate specific relations one-level deep using an array.

**JavaScript:**
```
const documents = await strapi.documents("api::article.article").findMany({
  populate: ["headerImage"],
});
```

**Response 200 OK:**
```json
[
  {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "title": "Test Article",
    "slug": "test-article",
    "body": "Test 1",
    // ...
    "headerImage": {
      "id": 2,
      "name": "17520.jpg"
      // ...
    }
  }
  // ...
]
```

### Populate several levels deep for specific relations

#### GET strapi.documents( — Populate several levels deep for specific relations

Populate specific relations several levels deep using nested populate.

**JavaScript:**
```
const documents = await strapi.documents("api::article.article").findMany({
  populate: {
    categories: {
      populate: ["articles"],
    },
  },
});
```

**Response 200 OK:**
```json
[
  {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "title": "Test Article",
    "slug": "test-article",
    "body": "Test 1",
    // ...
    "categories": {
      "id": 1,
      "name": "Test Category",
      "slug": "test-category",
      "description": "Test 1"
      // ...
      "articles": [
        {
          "id": 1,
          "title": "Test Article",
          "slug": "test-article",
          "body": "Test 1",
          // ...
        }
        // ...
      ]
    }
  }
  // ...
]
```

### Sort populated relations

Use the `sort` parameter inside a `populate` object to order related entries by an attribute. For many-to-many and other join-table relations, an explicit `sort` takes precedence over the default connect order.

<!-- source: strapi/strapi#26361 packages/core/database/src/query/helpers/populate/apply.ts -->

#### GET strapi.documents( — Sort populated relations

Order related entries by an attribute using the sort parameter inside a populate object.

**JavaScript:**
```
const documents = await strapi.documents("api::article.article").findMany({
  populate: {
    categories: {
      sort: 'name:asc',
    },
  },
});
```

**Response 200 OK:**
```json
[
  {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "title": "Test Article",
    // ...
    "categories": [
      {
        "id": 1,
        "name": "Architecture"
        // ...
      },
      {
        "id": 3,
        "name": "Technology"
        // ...
      }
    ]
  }
  // ...
]
```

:::note
Omit `sort` from a `populate` object to preserve the default connect order (the order in which entries were associated).
:::

## Components & Dynamic Zones

Components are populated the same way as relations:

#### GET strapi.documents( — Populate components

Populate components using the same syntax as relations.

**JavaScript:**
```
const documents = await strapi.documents("api::article.article").findMany({
  populate: ["testComp"],
});
```

**Response 200 OK:**
```json
[
  {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "title": "Test Article",
    "slug": "test-article",
    "body": "Test 1",
    // ...
    "testComp": {
      "id": 1,
      "name": "Test Component"
      // ...
    }
  }
  // ...
]
```

Dynamic zones are highly dynamic content structures by essence. Standard populate queries (like `populate: '*'` or `populate: ['testDZ']`) will only retrieve the default, non-relational scalar fields (e.g., strings, numbers) of components within a dynamic zone. They will **not** automatically fetch nested relations, media fields, or nested components.

To populate component-specific nested relations, media fields, or components within a dynamic zone, you must define per-component populate queries using the `on` property (fragment population syntax).

#### GET strapi.documents( — Populate dynamic zones

Populate dynamic zones using per-component queries with the on property.

**JavaScript:**
```
const documents = await strapi.documents("api::article.article").findMany({
  populate: {
    testDZ: {
      on: {
        "test.test-compo": {
          fields: ["testString"],
          populate: ["testNestedCompo"],
        },
      },
    },
  },
});
```

**Response 200 OK:**
```json
[
  {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "title": "Test Article",
    "slug": "test-article",
    "body": "Test 1",
    // ...
    "testDZ": [
      {
        "id": 3,
        "__component": "test.test-compo",
        "testString": "test1",
        "testNestedCompo": {
          "id": 3,
          "testNestedString": "testNested1"
        }
      }
    ]
  }
  // ...
]
```

## Populating with `create()`

#### GET strapi.documents( — Populate with create

Populate relations in the response when creating a document.

**JavaScript:**
```
strapi.documents("api::article.article").create({
  data: {
    title: "Test Article",
    slug: "test-article",
    body: "Test 1",
    headerImage: 2,
  },
  populate: ["headerImage"],
});
```

**Response 200 OK:**
```json
{
  "id": "cjld2cjxh0000qzrmn831i7rn",
  "title": "Test Article",
  "slug": "test-article",
  "body": "Test 1",
  "headerImage": {
    "id": 2,
    "name": "17520.jpg"
    // ...
  }
}
```

## Populating with `update()`

#### GET strapi.documents( — Populate with update

Populate relations in the response when updating a document.

**JavaScript:**
```
strapi.documents("api::article.article").update({
  documentId: "cjld2cjxh0000qzrmn831i7rn",
  data: {
    title: "Test Article Update",
  },
  populate: ["headerImage"],
});
```

**Response 200 OK:**
```json
{
  "id": "cjld2cjxh0000qzrmn831i7rn",
  "title": "Test Article Update",
  "slug": "test-article",
  "body": "Test 1",
  "headerImage": {
    "id": 2,
    "name": "17520.jpg"
    // ...
  }
}
```

## Populating with `publish()`

Same behavior applies with `unpublish()` and `discardDraft()`.

#### GET strapi.documents( — Populate with publish

Populate relations in the response when publishing a document.

**JavaScript:**
```
strapi.documents("api::article.article").publish({
  documentId: "cjld2cjxh0000qzrmn831i7rn",
  populate: ["headerImage"],
});
```

**Response 200 OK:**
```json
{
  "id": "cjld2cjxh0000qzrmn831i7rn",
  "versions": [
    {
      "id": "cjld2cjxh0001qzrm1q1i7rn",
      "locale": "en",
      // ...
      "headerImage": {
        "id": 2,
        "name": "17520.jpg"
        // ...
      }
    }
  ]
}
```

## Populating with `delete()`

To populate while deleting documents:

#### GET strapi.documents( — Populate with delete

Populate relations in the response when deleting a document.

**JavaScript:**
```
strapi.documents("api::article.article").delete({
  documentId: "cjld2cjxh0000qzrmn831i7rn",
  populate: ["headerImage"],
});
```

**Response 200 OK:**
```json
{
  "documentId": "cjld2cjxh0000qzrmn831i7rn",
  "entries": [
    {
      "id": "cjld2cjxh0000qzrmn831i7rn",
      "title": "Test Article",
      "slug": "test-article",
      "body": "Test 1",
      "headerImage": {
        "id": 2,
        "name": "17520.jpg"
        // ...
      }
      // ...
    }
  ]
}
```
