The Delivery API is a read-only REST API that serves published content from your Kentico Kontent projects.
Use the API to deliver large amounts of content to your website or app. The content is cached on the CDN level, which makes it quickly available from wherever you are. The Delivery API provides content filtering options that allow you to retrieve only the parts of the content you need.
All requests to the API must be made securely over HTTPS with TLS 1.2.
You can work with the Delivery API in two ways – either retrieve published versions of content items or preview their yet unpublished versions. In both cases, you use the same methods to request data but with a different base URL.
Retrieve published content items from your project using the production URL:https://deliver.kontent.ai/<YOUR_PROJECT_ID>/items
Protecting your content
The Delivery API is public by default. To protect your published content, use the Delivery API with secure access enabled.
Preview unpublished content items from your project using the preview URL:https://preview-deliver.kontent.ai/<YOUR_PROJECT_ID>/items
If you want to preview unpublished content in your project, you need to authorize your request.
// Tip: Find more about JS/TS SDKs at https://docs.kontent.ai/javascript const KontentDelivery = require('@kentico/kontent-delivery'); const deliveryClient = new KontentDelivery.DeliveryClient({ projectId: '<YOUR_PROJECT_ID>', previewApiKey: '<YOUR_PREVIEW_API_KEY>', globalQueryConfig: { usePreviewMode: true, // Queries the Delivery Preview API. }, typeResolvers: [ // Create strongly typed models according to https://docs.kontent.ai/strongly-typed-models new KontentDelivery.TypeResolver('article', (rawData) => new Article) ] }); deliveryClient.item('my_article') .toObservable() .subscribe(response => console.log(response));
// Tip: Find more about JS/TS SDKs at https://docs.kontent.ai/javascript import { ContentItem, DeliveryClient, Elements, TypeResolver } from '@kentico/kontent-delivery'; // Create strongly typed models according to https://docs.kontent.ai/tutorials/develop-apps/get-content/using-strongly-typed-models export class Article extends ContentItem { public title: Elements.TextElement; public summary: Elements.TextElement; public post_date: Elements.DateTimeElement; public teaser_image: Elements.AssetsElement; public related_articles: Article[]; } const deliveryClient = new DeliveryClient({ projectId: '<YOUR_PROJECT_ID>', previewApiKey: '<YOUR_PREVIEW_API_KEY>', globalQueryConfig: { usePreviewMode: true, // Queries the Delivery Preview API. }, typeResolvers: [ new TypeResolver('article', (rawData) => new Article) ] }); deliveryClient.item<Article>('on_roasts') .toObservable() .subscribe(response => console.log(response));
// Tip: Find more about .NET SDKs at https://docs.kontent.ai/net using Kentico.Kontent.Delivery; // Initializes a delivery client for previewing content IDeliveryClient client = DeliveryClientBuilder .WithOptions(builder => builder .WithProjectId("<YOUR_PROJECT_ID>") .UsePreviewApi("<YOUR_PREVIEW_API_KEY>") .Build()) .Build(); // Generate strongly typed models via https://github.com/Kentico/kontent-generators-net IDeliveryItemResponse<Article> response = await client.GetItemAsync<Article>("my_article"); Article item = response.Item;
// Tip: Find more about PHP SDKs at https://docs.kontent.ai/php // Defined by Composer to include required libraries require __DIR__ . '/vendor/autoload.php'; use Kentico\Kontent\Delivery\DeliveryClient; $client = new DeliveryClient('<YOUR_PROJECT_ID>', '<YOUR_PREVIEW_API_KEY>'); $item = $client->getItem('my_article');
// Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.*; // Initializes a Delivery client for preview DeliveryClient client = new DeliveryClient( DeliveryOptions.builder() .projectId("<YOUR_PROJECT_ID>") .previewApiKey("<YOUR_PREVIEW_API_KEY>") .usePreviewApi(true) .build() ); // Registers the model class for articles // Tip: Create strongly typed models according to https://docs.kontent.ai/strongly-typed-models client.registerType(Article.class); // Gets an article CompletionStage<Article> article = client.getItem("my_article", Article.class); // To use the code for Android projects, see http://docs.kontent.ai/android
# Tip: Find more about Ruby SDKs at https://docs.kontent.ai/ruby require 'delivery-sdk-ruby' delivery_client = Kentico::Kontent::Delivery::DeliveryClient.new project_id: '<YOUR_PROJECT_ID>', preview_key: '<YOUR_PREVIEW_API_KEY>' delivery_client.item('my_article').execute do |response| puts response.to_s end
// Tip: Find more about Swift SDK at https://docs.kontent.ai/ios import KenticoKontentDelivery let client = DeliveryClient.init(projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_PREVIEW_API_KEY>") // More about strongly-typed models https://github.com/Kentico/kontent-delivery-sdk-swift#using-strongly-typed-models client.getItem(modelType: Article.self, itemName: "my_article") { (isSuccess, itemResponse, error) in if isSuccess { if let article = itemResponse.item { // Use your item here } } else { if let error = error { print(error) } } }
curl --request GET \ --url https://preview-deliver.kontent.ai/<YOUR_PROJECT_ID>/items/my_article \ --header 'authorization: Bearer <YOUR_PREVIEW_API_KEY>'
For the Delivery Preview API, you can use two concurrent API keys, Primary and Secondary. For more details on how to work with the keys and content preview as a whole, see configuring preview for items.
By default, the Delivery API does not require authentication. However, if you enable secure access for the Delivery API or use the Delivery Preview API, you need to authenticate your requests with valid API keys.
To work with the Delivery API with secure access enabled or the Delivery Preview API, send your requests over HTTPS using the Authorization header in the following format: Authorization: Bearer <YOUR_API_KEY>
. Requests with an incorrect or missing Authorization
header will fail with an error.
To get your API key for the API, go to Kentico Kontent > Project settings > API keys. The API keys provide access to a single Kentico Kontent project. You will need different API keys for each of your projects.
We offer several SDKs to help you interact with the API. However, no SDK is required to use the API.
If you want to create your own SDK, see our guidelines for SDK developers.
Kentico Kontent returns standard HTTP status codes to indicate the success or failure of a request. In general, status codes in the 2xx
range indicate a successful request, status codes in the 4xx
range indicate errors caused by an incorrect input (for example, providing incorrect API key), and status codes in the 5xx
range indicate an error on our side.
Status code |
Description |
|
The request was not understood. Check your request for a missing required parameter or an invalid query parameter value. |
|
The provided API key is invalid or missing. |
|
The provided API key is invalid for the requested project. |
|
The requested resource doesn't exist. Try checking the resource name for typos. |
|
The requested HTTP method is not supported for the specified resource. Try performing a GET request. |
|
The rate limit for the API has been exceeded. Try your request again after a few seconds as specified in the |
|
Something went wrong on our side. Try your request again after a few seconds and use a retry policy. |
For troubleshooting failed requests, the API provides error messages defined in a consumable format to help you identify and fix the issue.
message required | string The error message explaining what caused the error. |
request_id required | string Nullable The performed request's unique ID. |
error_code required | integer <int32> [ 1 .. 500 ] The specific internal code for the type of error. Only useful for finding patterns among error requests. |
specific_code required | integer <int32> Only useful for finding reasons behind failed requests in specific cases. |
{- "message": "The requested content item 'sample_item' was not found.",
- "request_id": "|657e8eba55d8bf4a9a5ad9074038cd2e.813e828d_",
- "error_code": 100,
- "specific_code": 0
}
If you cannot identify and resolve an issue with your API call, you can contact us with the response status and the request ID you get in the error response.
By default, the Delivery API does not require authentication but you can enable secure access for the project to force authenticated requests.
With secure access, you can use two concurrent API keys, Primary and Secondary. For more details on how to work with the keys, see how to restrict public access.
Because the Delivery API is designed for continuous retrieval of published content, there is no expiration date for the Primary or Secondary API key.
The API keys are scoped per project. This means you need a separate API key for each project in Kentico Kontent. All users within a single project share the same Delivery API keys.
The Delivery API with secure access enabled and the Delivery Preview API both use two concurrent API keys, Primary and Secondary. In certain situations, you may need to revoke one of these keys and generate a new one. For example, when you suspect unauthorized key use or when a developer with access to the API key has left your company.
For situations like these, one or both of the API keys can be regenerated. Generating a new key will replace the old key. This process can take up to a couple of minutes. Requests made with a revoked API key will then receive a 401 Unauthorized
HTTP status in the response.
Keep your API keys secure
There is no expiration date for the Primary or Secondary API key. However, we recommend that you regenerate the API keys periodically to prevent the keys from being compromised.
Learn more in Securing public access and Configuring content preview.
Requests made to the Delivery API count towards the overall API Calls limit set in our Fair Use Policy.
Requests made to the Delivery Preview API, which lets you preview unpublished content, do NOT count towards the API Calls limit.
Rate limits specify the number of requests you can make to the Delivery API within a specific time window.
We don't enforce any limits for requests that hit our CDN, i.e, requests for cached data. You can make an unlimited number of requests to the CDN and they don't count towards the rate limit.
For uncached requests that reach the Delivery API, we enforce a rate limitation of 100 requests per second and 2000 requests per minute. When you reach this limit, the API rejects the request and responds with a 429 HTTP error.
The error response will include the Retry-After
header that tells you how many seconds you need to wait before retrying your requests. Each failed request is perfectly safe to retry. If you begin to receive 429 errors, reduce the frequency of your requests.
When you request a single content item or list of items, the Delivery API limits the maximum number of items returned within a response to 2000 items. This number covers both the items that directly match the specified query and the linked items returned in the response's modular_content
property.
You can find whether your requests are close to the limit by looking at the X-Request-Charge
header.
If the X-Request-Charge
value of your requests exceeds 1000, we recommend applying more specific filters and checking if a lower value for the depth
parameter works for you. Fewer items returned per response means shorter response times and better performance for your app.
When getting content items, you can filter your items by building query parameters from content elements and system properties. Check out our tutorial on filtering content items, which covers the basic use of common filtering parameters. Or read on for a deep dive.
Filtering does not apply to content items returned in the modular_content
object property.
If you want to get only a specific set of elements from content items, use projection.
system
valuesTo filter by system property values, you need to use a query parameter in the system.<property_name>
format. The system properties are id
, collection
, name
, codename
, language
, type
, and last_modified
. For example, to retrieve only content items based on the Article content type, use system.type=article
as a query parameter.
element
valuesTo filter by content element values, you need to use a query parameter in the elements.<element_codename>=<value>
format. For example, to retrieve only content items whose number element named Price has a value of 16, use elements.price=16
as a query parameter.
You can join multiple query parameters using the &
character. Queries with two or more filtering parameters are more restrictive because the individual query parameters are merged with a logical conjunction (AND).
For example, the query system.type=article&elements.category[contains]=nature
will return article content items that are tagged with the word Nature.
You can use the following filtering operators with both the system properties and element values.
All operators are case-sensitive.
Operator |
Description |
Example |
Use with |
|
Property value equals the specified value. |
|
Simple types |
|
Property value does not equal the specified value. |
|
Simple types |
|
Property value is empty. |
For rich text, use the equals operator, |
Simple types and arrays |
|
Property value is not empty. |
|
Simple types and arrays |
|
Property value is less than the specified value. |
|
Simple types |
|
Property value is less than or equal to the specified value. |
|
Simple types |
|
Property value is greater than the specified value. |
|
Simple types |
|
Property value is greater than or equal to the specified value. |
|
Simple types |
|
Property value falls within the specified range of two values, both inclusive. |
|
Simple types |
|
Property value is in the specified list of values. |
|
Simple types |
|
Property value is not in the specified list of values. |
|
Simple types |
|
Property with an array of values contains the specified value. |
|
Arrays |
|
Property with an array of values contains at least one value from the specified list of values. |
|
Arrays |
|
Property with an array of values contains all of the specified values. |
|
Arrays |
You can use the [contains]
, [any]
, and [all]
filtering operators only on arrays. The content elements that support these operators are custom elements (conditions apply), linked items, multiple choice, and taxonomy. The operators can be used on custom elements if the element's value is a stringified array of strings, such as "[\"DE\",\"US\",\"UK\"]"
. The [contains]
, [any]
, and [all]
operators can NOT be used on asset elements.
The [lt]
, [lte]
, [gt]
, [gte]
, and [range]
filtering operators work best with numbers. For example, you can retrieve products with price larger or equal to 15 by using elements.price[gte]=15
.
Filtering by date-time values
Properties that store dates are represented as strings. For example, this includes the last_modified
system property and date & time content elements.
If you use filtering operators on properties with string values, the Delivery API tries to perform a string comparison. For instance, you can retrieve content items modified during February and March by using a query such as system.last_modified[range]=2020-02-01,2020-04-01
, specifying the start date within the range and end date outside the range.
When getting content items or content types, you can specify which elements to return by using the elements
query parameter.
items
array and modular_content
collection.types
array.By using elements=title
as a query parameter, the elements
collection in each content item will contain only the element with the codename title
, or, if the item doesn't have an element with such codename, the elements
collection will be empty.
For multiple elements, you can use a query parameter such as elements=title,summary,related_articles
to retrieve only the elements with codenames title
, summary
, and related_articles
.
Excluding the system properties
Projection does not apply to the system properties. This means that you cannot omit the system
object from the response using any query.
Kentico Kontent offers several ways to compose and structure your content through rich text and linked items elements.
Components 101
Rich text elements can contain components.
When retrieving items using the Delivery API, the contents of all components and content items in the rich text and linked items elements are stored in the modular_content
object property of the API response.
When enumerating the items in your project using the Delivery API, the modular_content
object property will contain only components, not content items used in linked items elements.
The contents of modular_content
, that is the individual components and content items, are not ordered. See linked items and rich text elements for details on how ordering is done within the elements.
For historical reasons, the property is called "modular_content" instead of "linked_content".
Content items can reference other content items using linked items or rich text elements. These linked items can reference other items recursively. By default, the API returns only one level of linked items.
depth
query parameter to 2 or more.depth
query parameter to 0.When retrieving content, linked items cannot be filtered.
Components are not affected by the depth
query parameter as they are an integral part of their rich text element. Components are always present in the API response. Components can be nested up to six levels deep.
Content items represent specific pieces of content based on a specific content type. To retrieve specific items from your project, either provide a codename for one item or filter all items using parameters. By default, the Delivery API returns content items in the default language.
system required | object The content item's system properties. |
elements required | object The item's elements with values for the specific language. The order of the element objects might not match the content element order in the UI. |
{- "system": {
- "id": "335d17ac-b6ba-4c6a-ae31-23c1193215cb",
- "collection": "default",
- "name": "My article",
- "codename": "my_article",
- "language": "en-US",
- "type": "article",
- "sitemap_locations": [
- "string"
], - "last_modified": "2019-03-27T13:21:11.38Z"
}, - "elements": {
- "property1": {
- "type": "asset",
- "name": "Teaser image",
- "value": [
- {
- "name": "name-of-the-uploaded-file.jpg",
- "type": "image/jpeg",
- "size": 90895,
- "description": "Description of what the asset represents.",
- "width": 1000,
- "height": 666
}
]
}, - "property2": {
- "type": "asset",
- "name": "Teaser image",
- "value": [
- {
- "name": "name-of-the-uploaded-file.jpg",
- "type": "image/jpeg",
- "size": 90895,
- "description": "Description of what the asset represents.",
- "width": 1000,
- "height": 666
}
]
}
}
}
Delivery API
Delivery Preview API
Retrieve a list of content items from your project. By default, the API returns an unfiltered paginated list of content items ordered alphabetically by codename. The response size is limited to 2000 items.
If you need to export all content items from your project, we recommend using the Enumerate content item endpoint.
You can change the order by specifying the order
query parameter. You can customize pagination by specifying both the skip
and limit
query parameters.
Get only the items you need
To retrieve specific content items, use the filtering parameters in your requests. For example, you can request items tagged with a taxonomy term, items of a specific type, or items modified in the past three days.
project_id required | string Identifies your project. |
language | string Determines which language variant of content items to return. By default, the API returns content in the default language. If the requested content is not available in the specified language variant, the API follows the language fallbacks as configured in the Localization settings of your project. |
elements | Array of strings Determines the elements to retrieve using a comma-separated list of element codenames. The If not specified, all elements are retrieved. For more details, see Projection. |
order | string Determines the order of the retrieved objects. By default, the objects are sorted alphabetically by their codenames from A to Z in descending order. To sort the requested objects in ascending order, set the Examples
|
depth | integer <int32> >= 0 Determines the level of nesting for content items that the API returns. By default, only the first level of linked items is returned, which is the same as setting If you want to include more than one level of linked items in response, set the If you need to exclude all linked items from the response, set the parameter to Components are always present in response. See Linked content and components for more details. |
skip | integer <int32> >= 0 Sets the number of objects to skip when requesting a list of objects. The You can combine the |
limit | integer <int32> >= 0 Sets the number of objects to retrieve in a single request. If the If |
includeTotalCount | boolean Example: includeTotalCount=false Adds the information about the total number of content items matching your query. Only the content filtering parameters affect the resulting number. Other parameters in your query, such as The number doesn't include linked items returned as part of the When set to |
X-KC-Wait-For-Loading-New-Content | boolean Example: false Determines whether the API waits while fetching content, if the requested content has changed since the last request. This is useful when retrieving changed content in reaction to a webhook call. By default, when the header is not set, the API serves stale content (if cached by the CDN) while it's fetching the new content to minimize wait time. To always fetch new content, set the header value to |
A paginated list of content items matching the specified criteria.