# Parameters ::: warning By default, the filters can only be used from `find` and `count` endpoints generated by the Content Type Builder and the [CLI](../cli/CLI.md). ::: ## Available operators The available operators are separated in five different categories: - [Filters](#filters) - [Sort](#sort) - [Limit](#limit) - [Start](#start) - [Publication State](#publication-state) ## Filters When using filters you can either pass simple filters in the root of the query parameters or pass them in a `_where` parameter. Filters are used as a suffix of a field name: - No suffix or `eq`: Equals - `ne`: Not equals - `lt`: Less than - `gt`: Greater than - `lte`: Less than or equal to - `gte`: Greater than or equal to - `in`: Included in an array of values - `nin`: Isn't included in an array of values - `contains`: Contains - `ncontains`: Doesn't contain - `containss`: Contains case sensitive - `ncontainss`: Doesn't contain case sensitive - `null`: Is null/Is not null ### Examples #### Find users having `John` as first name. `GET /users?firstName=John` or `GET /users?firstName_eq=John` #### Find restaurants having a price equal or greater than `3`. `GET /restaurants?price_gte=3` #### Find multiple restaurant with id 3, 6, 8. `GET /restaurants?id_in=3&id_in=6&id_in=8` #### Using `_where` `GET /restaurants?_where[price_gte]=3` `GET /restaurants?_where[0][price_gte]=3&[0][price_lte]=7` ## Complex queries ::: tip NOTE `OR` and `AND` operations are available starting from v3.1.0 ::: When building more complex queries you must use the `_where` query parameter in combination with the [`qs`](https://github.com/ljharb/qs) library. We are taking advantage of the capability of `qs` to parse nested objects to create more complex queries. This will give you full power to create complex queries with logical `AND` and `OR` operations. ::: tip NOTE We strongly recommend using `qs` directly to generate complex queries instead of creating them manually. ::: ### `AND` operator The filtering implicitly supports the `AND` operation when specifying an array of expressions in the filtering. **Examples** Restaurants that have 1 `stars` and a `pricing` less than or equal to 20: ```js const query = qs.stringify({ _where: [{ stars: 1 }, { pricing_lte: 20 }], }); await request(`/restaurants?${query}`); // GET /restaurants?_where[0][stars]=1&_where[1][pricing_lte]=20 ``` Restaurants that have a `pricing` greater than or equal to 20 and a `pricing` less than or equal to 50: ```js const query = qs.stringify({ _where: [{ pricing_gte: 20 }, { pricing_lte: 50 }], }); await request(`/restaurants?${query}`); // GET /restaurants?_where[0][pricing_gte]=20&_where[1][pricing_lte]=50 ``` ### `OR` operator To use the `OR` operation, you will need to use the `_or` filter and specify an array of expressions on which to perform the operation. **Examples** Restaurants that have 1 `stars` OR a `pricing` greater than 30: ```js const query = qs.stringify({ _where: { _or: [{ stars: 1 }, { pricing_gt: 30 }] } }); await request(`/restaurant?${query}`); // GET /restaurants?_where[_or][0][stars]=1&_where[_or][1][pricing_gt]=30 ``` Restaurants that have a `pricing` less than 10 OR greater than 30: ```js const query = qs.stringify({ _where: { _or: [{ pricing_lt: 10 }, { pricing_gt: 30 }] } }); await request(`/restaurant?${query}`); // GET /restaurants?_where[_or][0][pricing_lt]=10&_where[_or][1][pricing_gt]=30 ``` ### Implicit `OR` operator The query engine implicitly uses the `OR` operation when you pass an array of values in an expression. **Examples** Restaurants that have 1 or 2 `stars`: `GET /restaurants?stars=1&stars=2` or ```js const query = qs.stringify({ _where: { stars: [1, 2] } }); await request(`/restaurant?${query}`); // GET /restaurants?_where[stars][0]=1&_where[stars][1]=2 ``` ::: tip NOTE When using the `in` and `nin` filters the array is not transformed into a OR. ::: ### Combining AND and OR operators Restaurants that have (2 `stars` AND a `pricing` less than 80) OR (1 `stars` AND a `pricing` greater than or equal to 50) ```js const query = qs.stringify({ _where: { _or: [ [{ stars: 2 }, { pricing_lt: 80 }], // implicit AND [{ stars: 1 }, { pricing_gte: 50 }], // implicit AND ], }, }); await request(`/restaurants?${query}`); // GET /restaurants?_where[_or][0][0][stars]=2&_where[_or][0][1][pricing_lt]=80&_where[_or][1][0][stars]=1&_where[_or][1][1][pricing_gte]=50 ``` **This also works with deep filtering** Restaurants that have (2 `stars` AND a `pricing` less than 80) OR (1 `stars` AND serves French food) ```js const query = qs.stringify({ _where: { _or: [ [{ stars: 2 }, { pricing_lt: 80 }], // implicit AND [{ stars: 1 }, { 'categories.name': 'French' }], // implicit AND ], }, }); await request(`/restaurants?${query}`); // GET /restaurants?_where[_or][0][0][stars]=2&_where[_or][0][1][pricing_lt]=80&_where[_or][1][0][stars]=1&_where[_or][1][1][categories.name]=French ``` ::: warning When creating nested queries, make sure the depth is less than 20 or the query string parsing will fail for now. ::: ## Deep filtering Find restaurants owned by a chef who belongs to a restaurant with star equal to 5 `GET /restaurants?chef.restaurant.star=5` ::: warning 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 your query. ::: ::: tip This feature doesn't allow you to filter nested models, e.g. `Find users and only return their posts older than yesterday`. To achieve this, there are three options: - Build a custom route. - Modify your services. - Use [GraphQL](../plugins/graphql.md#query-api). ::: ::: warning This feature isn't available for **polymorphic** relations. This relation type is used in `media`, `component` and `dynamic zone` fields. ::: ## Sort Sort according to a specific field. ### Example #### Sort users by email. - ASC: `GET /users?_sort=email:ASC` - DESC: `GET /users?_sort=email:DESC` #### Sorting on multiple fields - `GET /users?_sort=email:asc,dateField:desc` - `GET /users?_sort=email:DESC,username:ASC` ## Limit Limit the size of the returned results. The default limit is `100` ### Example #### Limit the result length to 30. `GET /users?_limit=30` You can require the full data set by passing a limit equal to `-1`. ## Start Skip a specific number of entries (especially useful for pagination). ### Example #### Get the second page of results. `GET /users?_start=10&_limit=10` ## Publication State ::: tip NOTE This parameter can only be used on models with the **Draft & Publish** feature activated ::: Only select entries matching the publication state provided. Handled states are: - `live`: Return only published entries (default) - `preview`: Return both draft entries & published entries ### Example #### Get published articles `GET /articles` OR `GET /articles?_publicationState=live` #### Get both published and draft articles `GET /articles?_publicationState=preview` ::: tip NOTE If you only want to retrieve your draft entries, you can combine the `preview` mode and the `published_at` field. `GET /articles?_publicationState=preview&published_at_null=true` :::