Go to main content

Multiple requests to Kentico Cloud Delivery API in Node.js

In this article I will give you a code example that demonstrates how to make multiple endpoint requests and get one response object. 

Multiple requests to Kentico Cloud Delivery API in Node.js

In the Request Kentico Cloud Delivery API in Node.js article I have demostrated how to get content from your Kentico Cloud project with use of the Delivery API. The article describes how to make one endpoint request at a time. In the real world where you create websites in Node.js you probably need to request multiple endpoints to render a single page.

Imagine we have a website and need to render a page. The page consists of:

  • Master page which is content that is shared across all pages. E. g. navigation, company logo and footer. 
  • Page specific content which is unique for each page.
  • Resource strings which are small pieces of text that might be shared across multiple pages.

All of these elements are kept separate in our Kentico Cloud project because we don't want to have repetitions in our content storage. 

I would like to share an elegant approach how get all the data with a single method call. Imagine that we make a request with a simple object:

    masterPage: '?system.type=master',
    page: '?system.type=home',
    resourceStrings: '?system.type=resource_strings'

And get a response in the same format:

    masterPage: {items: [...]},
    page:{items: [...]},
    resourceStrings: {items: [...]}

Exactly this is possible with the code example below. I won't explain the code step by like I did in the previous article because the example in this article is just an enhanced version of the previous one. 

See live demo on Runkit.

const request = require('request'),
    requestPromise = require("request-promise"),
    Promise = require('bluebird');

'use strict';

 * Initilizes class with Project ID and Preview API Key that represent a Kentico Cloud project.
 * @constructor Delivery
 * @param {string} projectID Project ID, see details in the Kentico Cloud Developers Hub: https://developer.kenticocloud.com/docs/using-delivery-api#section-getting-project-id.
 * @param {string} previewKey Preview API Key, see details in the Kentico Cloud Developers Hub: https://developer.kenticocloud.com/docs/preview-content-via-api.
 * @example
 * var project = new Delivery('82594550-e25c-8219-aee9-677f600bad53', 'ew0KICAiYWxnIjo...QvV8puicXQ');
class Delivery {
    constructor(projectID, previewKey) {
        this.projectID = projectID;
        this.previewKey = typeof previewKey === 'undefined' ? null : previewKey;

     * Returns promise with data from the Kentico Cloud storage specified by the passed object of filtering url parameters.
     * @method getContent
     * @param {object} params Object that contains filtering url parameters that are used for requesting Kentico Cloud storage. See details about filtering url parameters: https://developer.kenticocloud.com/v1/reference#delivery-api
     * @param {boolean} isPreview Flag that controls whether only published or all items should be requested.
     * @return {promise} with object of responses for each passed parameter from the Kentico Cloud storage.
     * @example
     * // returns
     * // {
     * //   master: {items: [...]},
     * //   page: {items: [...]}
     * // }
     * project.getContent({
     *   master: '?system.type=master',
     *   page: '?system.type=home'
     * }, true)
    getContent(params, isPreview) {
        // Reject operation if params parameter in not provided
        if (typeof params === 'undefined') {
            Promise.reject('Please, specify the params parameter in the getContent method.');

        // Set default state if maethod parameter are not provided
        if (typeof isPreview === 'undefined') {
            isPreview = false;

        // Split categories and filtering urls in separate arrays
        var categories = [],
            values = [];

        Object.keys(params).forEach((key, index) => {

        params = values.slice();

        // Create options that will represent your request to the Kentico Cloud storage
        let options = Delivery.getOptions(params, this.projectID, this.previewKey, isPreview);

        // Request the Kentico Cloud storage and get content from it
        return Delivery.getRawData(options)
            .then(function(data) {
                // And assemble an object structure of the original object
                return Delivery.categorizeContent(data, categories);

     * Helper methods section

    // Retrun array of promises with objects obtained from the Kentico Cloud storage
    static getRawData(options) {
        return Promise.map(options, (item) => {
            return requestPromise(item).catch(console.error);

    // Return url that should be requested
    static getDeliveryUrl(projectID, isPreview) {
        let url = '';

        // If we want to preview our content we need request a slightly different url
        if (isPreview) {
            url = 'https://preview-deliver.kenticocloud.com/' + projectID + '/items';
        } else {
            url = 'https://deliver.kenticocloud.com/' + projectID + '/items';

        return url;

    // Returns options for the request
    // Structure of the options object is defined by the request-promise package (https://www.npmjs.com/package/request-promise)
    static getOptions(params, projectID, previewKey, isPreview) {
        var options = [];

        // Create request options of each param
        if (isPreview && previewKey !== null) {
            params.forEach((item) => {
                    uri: Delivery.getDeliveryUrl(projectID, isPreview) + item,
                    json: true,
                    simple: false,
                    headers: {
                        Authorization: 'Bearer ' + previewKey
        } else {
            params.forEach((item) => {
                    uri: Delivery.getDeliveryUrl(projectID, isPreview) + item,
                    json: true,
                    simple: false

        return options;

    // Join array of category names and array of responses to fit the original object structure
    static categorizeContent(content, categories) {
        let categorizedContent = {};

        content.forEach((item, index) => {
            categorizedContent[categories[index]] = item;

        return categorizedContent;

 * Usage

// Initialize Delivery with Project ID and Preview API Key
let kenticoCloudProject = new Delivery('2548121d-cad8-4458-a910-5e4b54cb0956', 'ew0KICAiYWxnIjogIkhTMjU2IiwNCiAgInR5cCI6ICJKV1QiDQp9.ew0KICAidWlkIjogInVzcl8wdlVJVzkwTnRQSVNxNm1GSDN2ZFhiIiwNCiAgImVtYWlsIjogImhlbGxvQG1pbGFubHVuZC5jb20iLA0KICAicHJvamVjdF9pZCI6ICIyNTQ4MTIxZC1jYWQ4LTQ0NTgtYTkxMC01ZTRiNTRjYjA5NTYiLA0KICAianRpIjogInhrU1BLUjlzbzgxSV9rel8iLA0KICAidmVyIjogIjEuMC4wIiwNCiAgImdpdmVuX25hbWUiOiAiTWlsYW4iLA0KICAiZmFtaWx5X25hbWUiOiAiTHVuZCIsDQogICJhdWQiOiAicHJldmlldy5kZWxpdmVyLmtlbnRpY29jbG91ZC5jb20iDQp9.PpBh6wTk57e1_tPHzROiqWPTpr3IjrEoGN8J4rtfPIg');

// Request the Kentico Cloud storage with filtering url parameters and a boolean flag defining whether you want preview content or not
        master: '?system.type=master',
        page: '?system.type=home'
    }, true)
    .then(console.log) // Show results
    .catch(console.error); // Or error
Milan Lund

is a freelance web developer and a proud Basenji owner. His specialties are Kentico CMS/EMS and Kentico Cloud.

Further reading

all posts
  • Front-end & JavaScript

    Simple cookie bar

    EU cookie legislation requires website owners to inform visitors about the use of cookies. In this article, I will provide you with a simple solution of an informative cookie bar.

  • Front-end & JavaScript

    Simple scroll parallax

    Recently, a designer asked me to add a parallax background image on a website. I researched the web to find a suitable solution. Regrettably, I found only massive libraries that wo…

  • Kentico CMS & EMS

    Social media share urls enhanced by Kentico macros

    Requirements of nearly every website ask us to incorporate links for sharing content on social media. There are tools out there which generates these links for us. But wh…