# REST API: Filtering, Locale, and Publication State

The REST API offers the ability to filter results found with its "Get entries" method.
Using optional Strapi features can provide some more filters:

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

# Filtering

Queries can accept a filters parameter with the following syntax:

GET /api/:pluralApiId?filters[field][operator]=value

The following operators are available:

Operator Description
$eq Equal
$eqi Equal (case-insensitive)
$ne Not equal
$lt Less than
$lte Less than or equal to
$gt Greater than
$gte Greater than or equal to
$in Included in an array
$notIn Not included in an array
$contains Contains
$notContains Does not contain
$containsi Contains (case-insensitive)
$notContainsi Does not contain (case-insensitive)
$null Is null
$notNull Is not null
$between Is between
$startsWith Starts with
$endsWith Ends with
$or Joins the filters in an "or" expression
$and Joins the filters in an "and" expression

Example request: Find users having 'John' as first name

GET /api/users?filters[username][$eq]=John

Example response

[
  {
    "id": 1,
    "username": "John",
    "email": "john@test.com",
    "provider": "local",
    "confirmed": true,
    "blocked": false,
    "createdAt": "2021-12-03T20:08:17.740Z",
    "updatedAt": "2021-12-03T20:08:17.740Z"
  }
]
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({
  filters: {
    username: {
      $eq: 'John',
    },
  },
}, {
  encodeValuesOnly: true, // prettify URL
});

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

Example request: Find multiple restaurants with ids 3, 6, 8

GET /api/restaurants?filters[id][$in][0]=3&filters[id][$in][1]=6&filters[id][$in][2]=8

Example response

{
  "data": [
    {
      "id": 3,
      "attributes": {
        "name": "test3",
        // ...
      }
    },
    {
      "id": 6,
      "attributes": {
        "name": "test6",
        // ...
      }
    },
    {
      "id": 8,
      "attributes": {
        "name": "test8",
        // ...
      }
    }
  ],
  "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({
  filters: {
    id: {
      $in: [3, 6, 8],
    },
  },
}, {
  encodeValuesOnly: true, // prettify URL
});

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

✋ CAUTION

By default, the filters can only be used from find endpoints generated by the Content-type Builder and the CLI.

# Complex filtering

Complex filtering is combining multiple filters using advanced methods such as combining $and & $or. This allows for more flexibility to request exactly the data needed.

Example request: Find books with 2 possible dates and a specific author

GET /api/books?filters[$or][0][date][$eq]=2020-01-01&filters[$or][1][date][$eq]=2020-01-02&filters[author][name][$eq]=Kai%20doe

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "test1",
        "date": "2020-01-01",
        // ...
      }
    },
    {
      "id": 2,
      "attributes": {
        "name": "test2",
        "date": "2020-01-02",
        // ...
      }
    }
  ],
  "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({
  filters: {
    $or: [
      {
        date: {
          $eq: '2020-01-01',
        },
      },
      {
        date: {
          $eq: '2020-01-02',
        },
      },
    ],
    author: {
      name: {
        $eq: 'Kai doe',
      },
    },
  },
}, {
  encodeValuesOnly: true, // prettify URL
});

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

# Deep filtering

Deep filtering is filtering on a relation's fields.

Example request: Find restaurants owned by a chef who belongs to a 5-star restaurant

GET /api/restaurants?filters[chef][restaurants][stars][$eq]=5

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "GORDON RAMSAY STEAK",
        "stars": 5
        // ...
      }
    },
    {
      "id": 2,
      "attributes": {
        "name": "GORDON RAMSAY BURGER",
        "stars": 5
        // ...
      }
    }
  ],
  "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({
  filters: {
    chef: {
      restaurants: {
        stars: {
          $eq: 5,
        },
      },
    },
  },
}, {
  encodeValuesOnly: true, // prettify URL
});

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

✋ CAUTION

  • Querying your API with deep filters may cause performance issues. If one of your deep filtering queries is too slow, we recommend building a custom route with an optimized version of the query.
  • Deep filtering isn't available for polymorphic relations (eg: Dynamic Zones & Media Fields).

✏️ NOTE

  • Relations, media fields, components, and dynamic zones are not populated by default. Use the populate parameter to populate these data structures (see population documentation)
  • It is not possible to filter on dynamic zones or media fields

# Locale

The locale API parameter can be used to get entries from a specific locale.

# Publication State

PREREQUISITES

The Draft & Publish feature should be enabled.

Queries can accept a publicationState parameter to fetch entries based on their publication state:

  • live: returns only published entries (default)
  • preview: returns both draft entries & published entries

Example request: Get both published and draft articles

GET /api/articles?publicationState=preview

Example response

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "This a Draft",
        "publishedAt": null
        // ...
      }
    },
    {
      "id": 2,
      "attributes": {
        "title": "This is Live",
        "publishedAt": "2021-12-03T20:08:17.740Z"
        // ...
      }
    }
  ],
  "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({
  publicationState: 'preview',
}, {
  encodeValuesOnly: true, // prettify URL
});

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

💡 TIP

To retrieve only draft entries, combine the preview publication state and the publishedAt fields:

GET /api/articles?publicationState=preview&filters[publishedAt][$null]=true

JavaScript query (built with the qs library):
const qs = require('qs');
const query = qs.stringify({
  publicationState: 'preview',
  filters: {
    publishedAt: {
      $null: true,
    },
  },
}, {
  encodeValuesOnly: true, // prettify URL
});

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