# REST API
The REST API allows accessing the content-types through API endpoints that Strapi automatically creates.
API parameters can be used to filter, sort, and paginate results and to select fields and relations to populate. Additionally, specific parameters related to optional Strapi features can be used, like publication state and locale.
# API Endpoints
Creating a content-type automatically creates some REST API endpoints available to interact with it.
✏️ NOTE
Components don't have API endpoints.
# Endpoints
For each Content-Type, the following endpoints are automatically generated:
Examples
# Unified response format
Whatever the query, the response is always an object with the following keys:
data
: the response data itself, which could be:- a single entry, as an object with the following keys:
id
(number)attributes
(object)meta
(object)
- a list of entries, as an array of objects
- a custom response
- a single entry, as an object with the following keys:
meta
(object): information about pagination, publication state, available locales, etc.error
(object, optional): information about any error thrown by the request
# Get entries
Returns entries matching the query filters (see parameters documentation).
Example request
GET http://localhost:1337/api/restaurants
Example response
{
"data": [
{
"id": 1,
"attributes": {
"title": "Restaurant A",
"description": "Restaurant A's description",
"categories": [
{
"id": 1,
"attributes": {
"name": "My category"
},
"meta": {
"availableLocales": []
}
}
]
},
"meta": {
"availableLocales": []
}
},
{
"id": 2,
"attributes": {
"title": "Restaurant B",
"description": "Restaurant B's description",
"categories": [
{
"id": 1,
"attributes": {
"name": "My category"
},
"meta": {
"availableLocales": []
}
}
]
},
"meta": {
"availableLocales": []
}
},
],
"meta": {}
}
# Get an entry
Returns an entry by id.
Example request
GET http://localhost:1337/api/restaurants/1
Example response
{
"data": {
"id": 1,
"attributes": {
"title": "Restaurant A",
"description": "Restaurant A's description",
"categories": [
{
"id": 1,
"attributes": {
"name": "My category"
},
"meta": {
"availableLocales": []
}
}
]
},
"meta": {
"availableLocales": []
}
},
"meta": {}
}
# Create an entry
Creates an entry and returns its value.
If the Internationalization (i18n) plugin is installed, it's possible to use POST requests to the Content API to create localized entries.
Example request
POST http://localhost:1337/api/restaurants
{
"data": {
"title": "Hello",
"relation": 2,
"relations": [2, 4],
"link": {
"id": 1,
"type": "abc"
}
}
}
Example response
{
"data": {
"id": 1,
"attributes": { … },
"meta": {}
},
"meta": {}
}
# Update an entry
Partially updates an entry by id
and returns its value.
Fields that aren't sent in the query are not changed in the database. Send a null
value if you want to clear them.
Example request
PUT http://localhost:1337/api/restaurants/1
{
"data": {
"title": "Hello",
"relation": 2,
"relations": [2, 4],
}
}
Example response
{
"data": {
"id": 1,
"attributes": {},
"meta": {}
},
"meta": {}
}
✏️ NOTE
If the Internationalization (i18n) plugin is installed, it's currently not possible to update the locale of an entry.
# Delete an entry
Deletes an entry by id and returns its value.
Example request
DELETE http://localhost:1337/api/restaurants/1
Example response
{
"data": {
"id": 1,
"attributes": {},
"meta": {}
},
"meta": {}
}
# API Parameters
Query parameters use the LHS bracket syntax (i.e. they are encoded using square brackets []
).
✋ CAUTION
By default, the filters can only be used from find
endpoints generated by the Content-Type Builder and the CLI.
# Filters
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 |
$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 (case-sensitive) |
$notContains | Does not contain (case-sensitive) |
$containsi | Contains |
$notContainsi | Does not contain |
$null | Is null |
$notNull | Is not null |
$between | Is between |
$startsWith | Starts with |
$endsWith | Ends with |
Example request: Find users having 'John' as first name
GET /api/users?filters[firstName][$eq]=John
Example request: Find restaurants having a price equal or greater than `3`
GET /api/restaurants?filters[price][$gte]=3
Example request: Find multiple restaurant with id 3, 6, 8
GET /api/restaurants?filters[id][$in][0]=3&filters[id][$in][1]=6&filters[id][$in][2]=8
💡 TIP
Strapi takes advantage of the ability of qs
(opens new window) to parse nested objects to create more complex queries.
Use qs
directly to generate complex queries instead of creating them manually.
Example
const qs = require('qs');
const query = qs.stringify({
filters: {
$or: [
{
date: {
$eq: '2020-01-01'
},
},
{
date: {
$eq: '2020-01-02'
},
}
],
title: {
$eq: 'hello'
},
author: {
name: {
$eq: 'Kai doe'
},
},
},
}, {
encodeValuesOnly: true, // prettify url
});
await request(`/api/books?${query}`);
// GET /api/books?filters[$or][0][date][$eq]=2020-01-01&filters[$or][1][date][$eq]=2020-01-02&filters[title][$eq]=hello&filters[author][name][$eq]=Kai%20doe
# 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][restaurant][star][$eq]=5
✋ 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.
# Sorting
Queries can accept a sort
parameter with the following syntax:
GET /api/:pluralApiId?sort=field1,field2
The sorting order can be defined with :asc
(ascending order, default, can be omitted) or :desc
(for descending order).
Example requests: Sort users by email
GET /api/users?sort=email
to sort by ascending order (default)
GET /api/users?sort=email:desc
to sort by descending order
Example requests: Sort books on multiple fields
GET /api/books?sort=title,price:desc
GET /api/books?sort=title,author.name
GET /api/books?sort[0]=title&sort[1][author]=name
using an array format
# Pagination
Queries can accept pagination
parameters. Results can be paginated:
- either by page (i.e. specifying a page number and the number of entries per page)
- or by offset (i.e. specifying how many entries to skip and to return)
✏️ NOTE
Pagination methods can not be mixed. Always use either page
with pageSize
or start
with limit
.
# Pagination by page
Use the following parameters:
Parameter | Type | Description | Default |
---|---|---|---|
pagination[page] | Integer | Page number | 1 |
pagination[pageSize] | Integer | Page size | 100 |
pagination[withCount] | Boolean | Adds the total numbers of entries and the number of pages to the response | True |
Example request
GET /api/:pluralApiId?pagination[page]=1&pagination[pageSize]=10
Example response
{
"data": […],
"meta": {
"pagination": {
"page": 1,
"pageSize": 10,
"pageCount": 5,
"total": 48
}
}
}
# Pagination by offset
Use the following parameters:
Parameter | Type | Description | Default |
---|---|---|---|
pagination[start] | Integer | Start value (first entry to return) value | 0 |
pagination[limit] | Integer | Number of entries to return | 25 |
pagination[withCount] | Boolean | Toggles displaying the total number of entries to the response | true |
💡 TIP
The default and maximum values for pagination[limit]
can be configured in the ./config/api.js
file with the api.rest.defaultLimit
and api.rest.maxLimit
keys.
Example request
GET /api/:pluralApiId?pagination[start]=20&pagination[limit]=30
Example response
{
"data": [],
"meta": {
"pagination": {
"start": 0,
"limit": 10,
"total": 42,
}
}
}
# Fields selection
Queries can accept a fields
parameter to select only some fields. Use one of the following syntaxes:
GET /api/:pluralApiId?fields=field1,field2
or
GET /api/:pluralApiId?fields[0]=field1&fields[1]=field2
To get all fields, use the *
wildcard.
Example request: Get only firstName and lastName of all users
GET /api/users?fields=firstName,lastName
Example request: Get all fields for all users
GET /api/users?fields=*
# Relations population
By default, relations are not populated when fetching entries.
Queries can accept a populate
parameter to explicitly define which fields to populate, with the following syntax:
GET /api/:pluralApiId?populate=field1,field2
Example request: Get books and populate relations with the author's name and address
GET /api/books?populate=author.name,author.address
For convenience, the *
wildcard can be used:
Example request: Get all books and populate all their first level relations
GET /api/books?populate=*
Example request: Get all books and populate with authors and all their relations
GET /api/books?populate[author]=*
💡 TIP
Adding ?populate=*
to the query URL will include dynamic zones in the results.
# 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 requests: Get published articles
GET /api/articles
or
GET /api/articles?publicationState=live
Example request: Get both published and draft articles
GET /api/articles?publicationState=preview
💡 TIP
To retrieve only draft entries, combine the preview
publication state and the published_at
fields:
GET /api/articles?publicationState=preview&published_at_null=true
# Locale
PREREQUISITES
- The Internationalization (i18n) plugin should be installed.
- Localization should be enabled for the content-type.
The locale
API parameter can be used to get entries from a specific locale.
← Laravel GraphQL API →