> This page is for API Reference.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://contentful-staging.ferndocs.com/developers/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://contentful-staging.ferndocs.com/developers/docs/_mcp/server.

# Introduction

> **Info**
>
> **Note**: The use of Contentful is subject to the [Fair Usage Policy](https://www.contentful.com/r/knowledgebase/fair-use/) and to ensure uninterrupted functionality of the shared-service infrastructure, adhere to [Technical Limits](https://www.contentful.com/developers/docs/technical-limits/).

The Content Delivery API (CDA), available at *cdn.contentful.com*, is a read-only API for delivering content from Contentful to apps, websites and other media. Content is delivered as JSON data, and images, videos and other media as files.

The API is available via a globally distributed content delivery network (CDN). The server closest to the user serves all content, which minimizes latency and especially benefits mobile apps. Hosting content in multiple global data centers also improves the availability of content.

You'll need a free Contentful account and Contentful space to get started. You can sign up [here](https://www.contentful.com/sign-up/).

> **Info**
>
> **Note:** For EU data residency customers, the Base URL is **[https://cdn.eu.contentful.com](https://cdn.eu.contentful.com)**.

## Basic API information

API Base URL `https://cdn.contentful.com`
*This is a read-only API*

## Authentication

Any client requesting content from the CDA needs to provide an access token that has access to the environment you're requesting content from. For example, if you create an access token that only has access to the `master` environment of your space, you will not be able to use this token to access content from any other environment.

You have two options to supply the access token, either as an `Authorization` request header field, or as an `access_token` URI query parameter. The CDA implements the standardized OAuth 2.0 bearer token specification already supported by many HTTP clients.

You create access tokens in the *APIs* tab of each space in the Contentful web app. [Our reference guide](/references/authentication) has more details on how authentication works with Contentful.

## API rate limits

API rate limits specify the number of requests a client can make to Contentful APIs in a specific time frame.
Every request counts against a per-second rate limit.

There are no limits enforced on requests that hit our CDN cache, i.e. the request doesn't count towards your rate limit
and you can make an unlimited amount of cache hits. For requests that do hit the Content Delivery API, a rate limit of **55** requests per second is enforced. Higher rate limits may apply depending on your current plan.

When a client gets rate limited, the API responds with the **429 Too Many Requests** HTTP status code
and sets the `X-Contentful-RateLimit-Reset` header that tells the client when it can make its next single request.
The value of this header is an integer specifying the time before the limit resets and another request will be accepted.
As the client is rate-limited per second, the header will return 1, which means the next second.

**Example**

The current rate limit for a client is the default 55 per second.
Client: 85 uncached requests in 1 second

```
HTTP/1.1 429
X-Contentful-RateLimit-Reset: 1
```

Meaning: wait 1 second before making more requests.

The following table lists all headers returned in every response by the Content Delivery API which give a client information on rate limiting:

| Header                                | Description                                                   |
| ------------------------------------- | ------------------------------------------------------------- |
| `X-Contentful-RateLimit-Second-Limit` | The maximum amount of requests which can be made in a second. |
| `X-Contentful-RateLimit-Reset`        | The number of seconds until the next request can be made.     |

## Common resource attributes

Every resource returned by the Content Delivery API will have a `sys` property, which is an object containing system managed metadata. The exact metadata available depends on the resource type, but at minimum it defines the `sys.type` property.

**Note**: None of the `sys` fields are editable and you can only specify the `sys.id` in the creation of an item (If it's not a \*space\_).

Contentful defines the `sys.id` property for every resource that is not a collection. For example, a `Space` resource will have a `sys.type` and `sys.id`:

```json
{
  "sys": {
    "type": "Space",
    "id": "yadj1kx9rmg0"
  }
}
```

| Field                | Type    | Description                                                | Applies to                     |
| -------------------- | ------- | ---------------------------------------------------------- | ------------------------------ |
| sys.type             | String  | Resource type.                                             | All                            |
| sys.linkType         | String  | Type of an entity the link is referring to.                | Links                          |
| sys.id               | String  | Unique ID of resource.                                     | All except arrays              |
| sys.space            | Link    | Link to resource's space.                                  | Entries, assets, content types |
| sys.environment      | Link    | Link to a resource's environment.                          | Entries, assets, content types |
| sys.contentType      | Link    | Link to entry's content type.                              | Entries                        |
| sys.revision         | Integer | Publish counter of the resource.                           | Entries, assets, content types |
| sys.createdAt        | Date    | Date and time a resource was published for the first time. | Entries, assets, content types |
| sys.updatedAt        | Date    | Date and time a resource was published after an update.    | Entries, assets, content types |
| sys.locale           | String  | Locale of the resource.                                    | Entries and assets             |
| sys.publishedVersion | Integer | Published version of the resource                          | Entries, assets, content types |

**Note**: The `revision` field refers to the current number of published revisions of an entry. [Find out more in the Content Management API documentation.](/references/content-management-api/overview)

> **Info**
>
> **Sys properties - difference in meaning in Contentful APIs**
>
> Some of `sys` properties, while having the same label, render different kinds of data depending on the API. Please see the descriptions of these properties per API in the table below:
>
> <table>
>   <thead>
>     <tr>
>       <th colspan="4">
>         Property name per API
>       </th>
>     </tr>
>
>     <tr>
>       <th>
>         CMA
>       </th>
>
>       <th>
>         CDA
>       </th>
>
>       <th>
>         CPA
>       </th>
>
>       <th>
>         Description
>       </th>
>     </tr>
>   </thead>
>
>   <tbody>
>     <tr>
>       <td>
>         firstPublishedAt
>       </td>
>
>       <td>
>         createdAt
>       </td>
>
>       <td>
>         \-
>       </td>
>
>       <td>
>         Date and time a resource was published for the first time.
>       </td>
>     </tr>
>
>     <tr>
>       <td>
>         publishedAt
>       </td>
>
>       <td>
>         updatedAt
>       </td>
>
>       <td>
>         \-
>       </td>
>
>       <td>
>         Date and time a resource was published after an update.
>       </td>
>     </tr>
>
>     <tr>
>       <td>
>         createdAt
>       </td>
>
>       <td>
>         \-
>       </td>
>
>       <td>
>         createdAt
>       </td>
>
>       <td>
>         Date and time a resource was generated in the system.
>       </td>
>     </tr>
>
>     <tr>
>       <td>
>         updatedAt
>       </td>
>
>       <td>
>         \-
>       </td>
>
>       <td>
>         updatedAt
>       </td>
>
>       <td>
>         Date and time a resource was updated in the system.
>       </td>
>     </tr>
>   </tbody>
> </table>

## Date and time format

Date and time must be formatted according to [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).

> **Info**
>
> **Important**: When setting time, ensure to indicate timezone. With no timezone specified, UTC+0 is applied as a default one.

The table below displays the supported date and time formatting:

| Data type              | Format                                                | Examples                                                                       |
| ---------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------ |
| Date only              | "YYYY-MM-DD"                                          | "2015-11-06"                                                                   |
| Date + time            | "YYYY-MM-DDThh:mm:ss" "YYYY-MM-DDThh:mm:ss.sss"       | "2015-11-06T09:45"                                                             |
| Date + time + timezone | "YYYY-MM-DDThh:mm:ssZ" "YYYY-MM-DDThh:mm:ss±\[hh:mm]" | "2015-11-06T09:45:27Z" "2015-11-06T09:45:27+00:00" "2015-11-06T09:45:27-08:00" |

## Collection resources and pagination

Contentful returns collections of resources in a wrapper object that contains extra information useful for paginating over large result sets:

```json
{
  "sys": { "type": "Array" },
  "skip": 0,
  "limit": 100,
  "total": 1256,
  "items": [ /* 100 individual resources */ ]
}
```

In the above example, a client retrieves the next 100 resources by repeating the same request, changing the `skip` query parameter to `100`. You can use the `order` parameter when paging through larger result sets to keep ordering predictable. For example, `order=sys.createdAt` will order results by the time the resource was first published.

## Cursor pagination

#### Overview

Cursor pagination is an approach to paginating datasets in Contentful APIs. Unlike traditional offset-based pagination, which uses skip and limit parameters, cursor-based pagination uses opaque cursor tokens and dedicated next/prev links to mark the position in the dataset. This can dramatically improve performance, especially for datasets with large numbers of items.

#### How cursor pagination works

* **Initial Request:**\
  Add the query parameter `cursor=true` to your API request, e.g.

  ```
  GET /spaces/:space_id/entries?cursor=true
  ```

  The response contains:

  * `items`: The current page of resources.
  * `pages`: Contains `next` (and optionally `prev`) URLs for paginating forward and backward.

* **Paginate forward:**\
  Use the `pages.next` URL from the previous response for the next page request:

  ```
  GET /spaces/:space_id/entries?pageNext={cursor_token}
  ```

  Continue this process until the `next` link is omitted, which means you've reached the end of the dataset.

* **Paginate backward:**
  If the response contains a `pages.prev` link, you can fetch previous pages:

  ```
  GET /spaces/:space_id/entries?pagePrev={cursor_token}
  ```

* **Consistency:**
  All query parameters used in the initial request apart from `limit` are locked and encoded in the cursor token. They cannot be changed between pages.

  The `limit` parameter can be updated, and the new value will be persisted for subsequent pages until it's updated again.

  ```
  GET /spaces/:space_id/entries?pageNext={cursor_token}&limit={limit}
  ```

  This can be useful when you need to adjust the page size, for example, if a page size (in bytes) exceeds the response limit.

* **Total count:**
  The response does not include a total count or a skip property. This is a key feature for performance, as the API avoids costly full counts on large datasets.

#### Example response

```json
{
  "sys": { "type": "Array" },
  "limit": 100,
  "items": [ ... ],
  "pages": {
    "next": "/spaces/:space_id/entries?pageNext=cursor_token",
    "prev": "/spaces/:space_id/entries?pagePrev=cursor_token"
  }
}
```

#### Advantages

* Considerable performance improvements, particularly for large datasets.

If your environment contains 10s of thousands of entries or assets, consider switching to cursor pagination, it can make requests to fetch lists of entries or assets of such an environment much faster.

If you don't paginate at all, particularly when working with CDA and you don't need the `total` property from the response, we highly recommend using requests with `cursor=true`.

#### Limitations

* **The "total" property is not included in the API responses.** Make sure you don't rely on it in your workflow prior to making the switch.

#### Enablement and access

* The feature is currently available in the CMA, CPA and CDA.