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

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