Skip navigation

Restrict public access to your content

5 min read

Protect your content with secure access. You might want to use this with sensitive content, content hidden behind sign-in walls, or for projects that are not public facing.

Table of contents

    Enable secure access

    Using secure access means you'll need to provide an API key with each request to the Delivery API. The Delivery API allows you to use two concurrent API keys, Primary and Secondary.

    Primary vs. Secondary key

    The following instructions work equally for both the Primary key and the Secondary key. Both API keys are generated per project and have no expiration date. For continuous use, we recommend using the Primary key. Use the Secondary key only when revoking the Primary key to prevent downtime.

    By activating secure access, Kontent will generate two API keys.

    1. In Kentico Kontent, go to  Project settings > API keys.
    2. In the Secure access box, toggle the Inactive switch to activate secure access.
    Secure access keys in Kontent's settings

    Use the Primary key to authenticate your requests.

    Get your API key

    Every request to the Delivery API with secure access enabled must be authenticated with an API key. This key is unique to each project in Kentico Kontent.

    1. In Kentico Kontent, go to  Project settings > API keys.
    2. In the Secure access box, click  for one of the API keys.

    You can now use the key to authenticate your requests to the Delivery API.

    Authenticate requests

    Every request you make must be sent with an API key in the Authorization header. The Authorization header uses the following format: Authorization: Bearer <YOUR_API_KEY>.

    Retrieve content securely

    Tips for staying secure

    Here are a few tips to help you when using Delivery API with secure access enabled:

    • Retrieve content on the server side and NOT client side to prevent leaking your API keys.
    • Store your API Keys outside your source code. For example, store them as environment variables. Make sure they're encrypted too.
    • Regenerate only one key at a time to prevent downtime.
    • Regenerate your API keys periodically. The older a key is, the higher the probability it could have been compromised.

    When getting content items, add an API key on top of your requests. For example, the code below shows how to securely retrieve content of an article named My article.

    • Swift
    // Tip: Find more about Swift SDK at https://docs.kontent.ai/ios import KenticoKontentDelivery let client = DeliveryClient.init(projectId: "<YOUR_PROJECT_ID>", secureApiKey: "<YOUR_API_KEY>") // Create strongly typed models according to https://docs.kontent.ai/strongly-typed-models client.getItem(modelType: Article.self, itemName: "my_article") { (isSuccess, deliveryItem, error) in if isSuccess { if let article = deliveryItem.item { // Use your item here } } else { if let error = error { print(error) } }
    // Tip: Find more about Swift SDK at https://docs.kontent.ai/ios import KenticoKontentDelivery let client = DeliveryClient.init(projectId: "<YOUR_PROJECT_ID>", secureApiKey: "<YOUR_API_KEY>") // Create strongly typed models according to https://docs.kontent.ai/strongly-typed-models client.getItem(modelType: Article.self, itemName: "my_article") { (isSuccess, deliveryItem, error) in if isSuccess { if let article = deliveryItem.item { // Use your item here } } else { if let error = error { print(error) } }
    • Java
    // Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.*; // Initializes a DeliveryClient with secure access key DeliveryClient client = new DeliveryClient( DeliveryOptions.builder() .projectId("<YOUR_PROJECT_ID>") .productionApiKey("<YOUR_API_KEY>") .build() ); // Gets the latest version of an item CompletionStage<ContentItemResponse> item = client.getItem("my_article"); // To use the code for Android projects, see http://docs.kontent.ai/android
    // Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.*; // Initializes a DeliveryClient with secure access key DeliveryClient client = new DeliveryClient( DeliveryOptions.builder() .projectId("<YOUR_PROJECT_ID>") .productionApiKey("<YOUR_API_KEY>") .build() ); // Gets the latest version of an item CompletionStage<ContentItemResponse> item = client.getItem("my_article"); // To use the code for Android projects, see http://docs.kontent.ai/android
    • JavaScript
    // 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>', globalQueryConfig: { useSecuredMode: true, // Queries the Delivery API using secure access. }, secureApiKey: '<YOUR_API_KEY>', 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 const KontentDelivery = require('@kentico/kontent-delivery'); const deliveryClient = new KontentDelivery.DeliveryClient({ projectId: '<YOUR_PROJECT_ID>', globalQueryConfig: { useSecuredMode: true, // Queries the Delivery API using secure access. }, secureApiKey: '<YOUR_API_KEY>', 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));
    • C#
    // Tip: Find more about .NET SDKs at https://docs.kontent.ai/net using Kentico.Kontent.Delivery; // Creates an instance of the delivery client // ProTip: Use DI for this in your apps https://docs.kontent.ai/net-register-client IDeliveryClient client = DeliveryClientBuilder .WithOptions(builder => builder .WithProjectId("<YOUR_PROJECT_ID>") .UseProductionApi("<YOUR_API_KEY>") .Build()) .Build(); // Gets a specific content item // Create strongly typed models according to https://docs.kontent.ai/net-strong-types IDeliveryItemResponse<Article> response = await client.GetItemAsync<Article>("my_article"); Article item = response.Item;
    // Tip: Find more about .NET SDKs at https://docs.kontent.ai/net using Kentico.Kontent.Delivery; // Creates an instance of the delivery client // ProTip: Use DI for this in your apps https://docs.kontent.ai/net-register-client IDeliveryClient client = DeliveryClientBuilder .WithOptions(builder => builder .WithProjectId("<YOUR_PROJECT_ID>") .UseProductionApi("<YOUR_API_KEY>") .Build()) .Build(); // Gets a specific content item // Create strongly typed models according to https://docs.kontent.ai/net-strong-types IDeliveryItemResponse<Article> response = await client.GetItemAsync<Article>("my_article"); Article item = response.Item;
    • PHP
    // 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>', null, '<YOUR_API_KEY>'); $item = $client->getItem('my_article');
    // 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>', null, '<YOUR_API_KEY>'); $item = $client->getItem('my_article');
    • cURL
    curl --request GET \ --url https://deliver.kontent.ai/<YOUR_PROJECT_ID>/items/my_article \ --header 'authorization: Bearer <YOUR_API_KEY>'
    curl --request GET \ --url https://deliver.kontent.ai/<YOUR_PROJECT_ID>/items/my_article \ --header 'authorization: Bearer <YOUR_API_KEY>'
    • Ruby
    # 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>', secure_key: '<YOUR_API_KEY>' delivery_client.item('my_article').execute do |response| item = response.item end
    # 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>', secure_key: '<YOUR_API_KEY>' delivery_client.item('my_article').execute do |response| item = response.item end
    • TypeScript
    // 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/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>', globalQueryConfig: { useSecuredMode: true // Queries the Delivery API using secure access. }, secureApiKey: '<YOUR_API_KEY>', typeResolvers: [new TypeResolver('article', (rawData) => new Article())] }); deliveryClient .item<Article>('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/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>', globalQueryConfig: { useSecuredMode: true // Queries the Delivery API using secure access. }, secureApiKey: '<YOUR_API_KEY>', typeResolvers: [new TypeResolver('article', (rawData) => new Article())] }); deliveryClient .item<Article>('my_article') .toObservable() .subscribe(response => console.log(response));

    After performing the request, you receive a single content item in the JSON format. You can filter your requests to, for example, retrieve only specific elements or items.

    Revoke the API keys

    When you suspect unauthorized key usage, you need to revoke one of the API keys and generate a new one. For example, when a developer with access to the API keys had left your company. In such cases, 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. Any requests made with a revoked API key receive the 401 Unauthorized error.

    1. In Kentico Kontent, go to  Project settings > API keys.
    2. In the Delivery API box, regenerate the Secondary key to ensure it's new and secure.
    3. Update your applications using secure access to use the newly generated Secondary key.
    4. Validate that your applications using work correctly with the new key.
    5. Regenerate the Primary key to make sure unauthorized users cannot use this key to access your content.
    6. (Optional) Switch back to using the regenerated Primary key in all of your applications.

    The last step is optional because switching back to the regenerated Primary key might seem unnecessarily complicated. The reason behind this is simple – you can easily keep track of the API key you are currently using for your application. If you only use the Secondary key to prevent downtime when revoking the Primary key, it can keep things simple in the long run.