Importing to Kentico Kontent

If you have a lot of content and want to move it over to your Kentico Kontent project, you can leverage the Content Management API (CM API) to automate a one-time import. This usually means writing a script or an application that parses the content from its original format (be it a database from another CMS such as WordPress, or an XML, CSV or text file) into JSON and sends it to Kentico Kontent.

Premium feature 

The Content Management API requires a Professional plan or higher.

Table of contents

    In this tutorial, you will import a single content item – imagine it as a single step in a longer content migration process. First, you will define a Cafe content type that is identical to the one that can be found in the Sample Project. (If you do not have access to the Sample Project, a subscription admin can generate the project and invite you to it.) Then, you'll add a cafe based on that type.

    Note: The CM API currently has two versions. While CM API v2 is in BETA, it is not expected that its behavior will substantially change just that more features will be added (all changes will be noted in the API changelog). For this reason, the cURL and JavaScript examples here use v2. For v1, you can only manage content items, their language variants, and assets. Until the .Net SDK is updated to v2, the examples here for .Net use v1.

    Enabling the API for your project

    The CM API is disabled by default for new projects and you need to activate it. By activating the CM API, the system will also generate a new API key.

    1. In Kentico Kontent, choose Project settings from the app menu.
    2. Under Development, choose API Keys.
    3. Click the Inactive switch to activate the Content Management API.
    4. Copy the API key.

    You will use the API key to authenticate your requests. For more information see API key scope and validity.

    Getting your API key.

    Importing your content

    Importing content is a 3 step process:

    1. Creating a content type to define the structure of your content.
    2. Creating a content item, which serves as a wrapper for your content.
    3. Adding content inside a language variant of the content item.

    In the Kentico Kontent UI, step 2 is the equivalent of clicking Create new content item, while step 3 would translate to filling in the content elements.

    Each content item can consist of several localized variants. The content itself is always part of a specific language variant, even if your project only uses one language.

    A model of a content item.

    Now import a single Cafe content item into your project. Assume that the Cafe content type is already prepared.

    1. Creating a content type

    Before importing your content, you need to define the content type for the items you want to import. The Sample Project already has the Cafe content type set up. Or you can define the same type in the UI.

    A Cafe content type.

    If you plan to organize your content with taxonomies, you should add the taxonomy groups in advance as well.

    Before importing your content, you need to define the content type for the items you want to import. 

    To add a content type to your project, send a POST request to the <YOUR_PROJECT_ID>/types endpoint with your project ID. In the body of the request, specify these properties:

    • name – string with a display name of the new content item.
    • (Optional) codename – the codename for the type that will be shown in the Kontent UI.
    • (Optional) external_id – the unique id of the content type you define (or the ID it had in your original system).
    • elements  – a collection of all the elements you'd like to have in your type.

    Use your CM API Key in the authorization header of the request (in place of <YOUR_API_KEY> in the examples).

    • JavaScript
    // Using ES6 syntax import { ManagementClient, ElementModels } from "@kentico/kontent-management"; const client = new ManagementClient({ projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_API_KEY>" }); client.addContentType() .withData( { codename: "cafe", name: "Cafe", external_id: "cafe", elements: [ { name: "Price per unit", type: "number", codename: "price_per_unit" }, { guidelines: "<h2>Keep Guidelines where the creative process happens.</h2>\n<p>These are sample guidelines that you can place for the whole content item. It’s a place where you can include your content brief, voice and tone recommendations or the URL to a wireframe, so the author will have all the relevant instructions at hand before writing a single line.</p>\n<p>Besides overview guidelines, you can include instructions for each particular content element, as you will see below.</p>", type: ElementModels.ElementType.guidelines, codename: "n2f836bce_e062_b2cd_5265_f5c3be3aa6f5" }, { name: "Street", type: ElementModels.ElementType.text, codename: "street" }, { name: "City", type: ElementModels.ElementType.text, codename: "city" }, { name: "Country", type: ElementModels.ElementType.text, codename: "country" }, { name: "State", type: ElementModels.ElementType.text, codename: "state" }, { name: "ZIP Code", type: ElementModels.ElementType.text, codename: "zip_code" }, { name: "Phone", type: ElementModels.ElementType.text, codename: "phone" }, { name: "Email", type: ElementModels.ElementType.text, codename: "email" }, { name: "Photo", type: ElementModels.ElementType.asset, codename: "photo" } ] } ) .toObservable() .subscribe((response) => { console.log(response); }, (error) => { console.log(error); });
    // Using ES6 syntax import { ManagementClient, ElementModels } from "@kentico/kontent-management"; const client = new ManagementClient({ projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_API_KEY>" }); client.addContentType() .withData( { codename: "cafe", name: "Cafe", external_id: "cafe", elements: [ { name: "Price per unit", type: "number", codename: "price_per_unit" }, { guidelines: "<h2>Keep Guidelines where the creative process happens.</h2>\n<p>These are sample guidelines that you can place for the whole content item. It’s a place where you can include your content brief, voice and tone recommendations or the URL to a wireframe, so the author will have all the relevant instructions at hand before writing a single line.</p>\n<p>Besides overview guidelines, you can include instructions for each particular content element, as you will see below.</p>", type: ElementModels.ElementType.guidelines, codename: "n2f836bce_e062_b2cd_5265_f5c3be3aa6f5" }, { name: "Street", type: ElementModels.ElementType.text, codename: "street" }, { name: "City", type: ElementModels.ElementType.text, codename: "city" }, { name: "Country", type: ElementModels.ElementType.text, codename: "country" }, { name: "State", type: ElementModels.ElementType.text, codename: "state" }, { name: "ZIP Code", type: ElementModels.ElementType.text, codename: "zip_code" }, { name: "Phone", type: ElementModels.ElementType.text, codename: "phone" }, { name: "Email", type: ElementModels.ElementType.text, codename: "email" }, { name: "Photo", type: ElementModels.ElementType.asset, codename: "photo" } ] } ) .toObservable() .subscribe((response) => { console.log(response); }, (error) => { console.log(error); });
    • cURL
    curl --request POST \ --url https://manage.kontent.ai/v2/projects/<YOUR_PROJECT_ID>/types \ --header "Authorization: Bearer <YOUR_API_KEY>" \ --header "Content-type: application/json" \ --data " { "codename": "cafe", "name": "Cafe", "external_id": "cafe", "elements": [ { "name": "Price per unit", "type": "number", "codename": "price_per_unit" }, { "guidelines": "<h2>Keep Guidelines where the creative process happens.</h2>\n<p>These are sample guidelines that you can place for the whole content item. It’s a place where you can include your content brief, voice and tone recommendations or the URL to a wireframe, so the author will have all the relevant instructions at hand before writing a single line.</p>\n<p>Besides overview guidelines, you can include instructions for each particular content element, as you will see below.</p>", "type": "guidelines", "codename": "n2f836bce_e062_b2cd_5265_f5c3be3aa6f5" }, { "name": "Street", "type": "text", "codename": "street" }, { "name": "City", "type": "text", "codename": "city" }, { "name": "Country", "type": "text", "codename": "country" }, { "name": "State", "type": "text", "codename": "state" }, { "name": "ZIP Code", "type": "text", "codename": "zip_code" }, { "name": "Phone", "type": "text", "codename": "phone" }, { "name": "Email", "type": "text", "codename": "email" }, { "name": "Photo", "type": "asset", "codename": "photo" } ] }"
    curl --request POST \ --url https://manage.kontent.ai/v2/projects/<YOUR_PROJECT_ID>/types \ --header "Authorization: Bearer <YOUR_API_KEY>" \ --header "Content-type: application/json" \ --data " { "codename": "cafe", "name": "Cafe", "external_id": "cafe", "elements": [ { "name": "Price per unit", "type": "number", "codename": "price_per_unit" }, { "guidelines": "<h2>Keep Guidelines where the creative process happens.</h2>\n<p>These are sample guidelines that you can place for the whole content item. It’s a place where you can include your content brief, voice and tone recommendations or the URL to a wireframe, so the author will have all the relevant instructions at hand before writing a single line.</p>\n<p>Besides overview guidelines, you can include instructions for each particular content element, as you will see below.</p>", "type": "guidelines", "codename": "n2f836bce_e062_b2cd_5265_f5c3be3aa6f5" }, { "name": "Street", "type": "text", "codename": "street" }, { "name": "City", "type": "text", "codename": "city" }, { "name": "Country", "type": "text", "codename": "country" }, { "name": "State", "type": "text", "codename": "state" }, { "name": "ZIP Code", "type": "text", "codename": "zip_code" }, { "name": "Phone", "type": "text", "codename": "phone" }, { "name": "Email", "type": "text", "codename": "email" }, { "name": "Photo", "type": "asset", "codename": "photo" } ] }"

    Kontent will generate any properties not included and return them in the response.

    • JSON
    { "id": "f15799a1-dff0-5216-a014-e963f9ea6bbc", "codename": "cafe", "last_modified": "2019-10-08T12:47:27.4261844Z", "external_id": "cafe", "name": "Cafe", "content_groups": [], "elements": [ { "name": "Price per unit", "guidelines": null, "is_required": false, "type": "number", "id": "965cf18c-998a-456b-bee3-91defdf39782", "codename": "price_per_unit" }, { "guidelines": "<h2>Keep Guidelines where the creative process happens.</h2>\n<p>These are sample guidelines that you can place for the whole content item. It’s a place where you can include your content brief, voice and tone recommendations or the URL to a wireframe, so the author will have all the relevant instructions at hand before writing a single line.</p>\n<p>Besides overview guidelines, you can include instructions for each particular content element, as you will see below.</p>", "type": "guidelines", "id": "8816e7d0-ca5e-4cfa-88b4-c1944862ff9f", "codename": "n8e317a38_e3bc_4d98_a63d_f1e336c5a9e6" }, { "maximum_text_length": null, "name": "Street", "guidelines": null, "is_required": false, "type": "text", "id": "2b7b256c-73cc-4be0-b749-4c410209df02", "codename": "street" }, { "maximum_text_length": null, "name": "City", "guidelines": null, "is_required": false, "type": "text", "id": "fa17f73a-833c-4cf2-aa7b-3b5c4edad6b3", "codename": "city" }, { "maximum_text_length": null, "name": "Country", "guidelines": null, "is_required": false, "type": "text", "id": "2b36b05e-5f4f-4630-b502-154f5b3b90c3", "codename": "country" }, { "maximum_text_length": null, "name": "State", "guidelines": null, "is_required": false, "type": "text", "id": "3638f2cd-3fea-4a4e-a6b6-bdd39f3b9f66", "codename": "state" }, { "maximum_text_length": null, "name": "ZIP Code", "guidelines": null, "is_required": false, "type": "text", "id": "35ad677a-cfe5-4573-814d-5895e3de8396", "codename": "zip_code" }, { "maximum_text_length": null, "name": "Phone", "guidelines": null, "is_required": false, "type": "text", "id": "4ec54355-4177-4b29-9a16-b25a7c8fba26", "codename": "phone" }, { "maximum_text_length": null, "name": "Email", "guidelines": null, "is_required": false, "type": "text", "id": "9bc4b679-4353-40c7-bcfd-145110ced7d9", "codename": "email" }, { "asset_count_limit": null, "maximum_file_size": null, "allowed_file_types": "any", "image_width_limit": null, "image_height_limit": null, "name": "Photo", "guidelines": null, "is_required": false, "type": "asset", "id": "1693ecd3-fb15-4d56-975a-4b8dbdedf65b", "codename": "photo" } ] }
    { "id": "f15799a1-dff0-5216-a014-e963f9ea6bbc", "codename": "cafe", "last_modified": "2019-10-08T12:47:27.4261844Z", "external_id": "cafe", "name": "Cafe", "content_groups": [], "elements": [ { "name": "Price per unit", "guidelines": null, "is_required": false, "type": "number", "id": "965cf18c-998a-456b-bee3-91defdf39782", "codename": "price_per_unit" }, { "guidelines": "<h2>Keep Guidelines where the creative process happens.</h2>\n<p>These are sample guidelines that you can place for the whole content item. It’s a place where you can include your content brief, voice and tone recommendations or the URL to a wireframe, so the author will have all the relevant instructions at hand before writing a single line.</p>\n<p>Besides overview guidelines, you can include instructions for each particular content element, as you will see below.</p>", "type": "guidelines", "id": "8816e7d0-ca5e-4cfa-88b4-c1944862ff9f", "codename": "n8e317a38_e3bc_4d98_a63d_f1e336c5a9e6" }, { "maximum_text_length": null, "name": "Street", "guidelines": null, "is_required": false, "type": "text", "id": "2b7b256c-73cc-4be0-b749-4c410209df02", "codename": "street" }, { "maximum_text_length": null, "name": "City", "guidelines": null, "is_required": false, "type": "text", "id": "fa17f73a-833c-4cf2-aa7b-3b5c4edad6b3", "codename": "city" }, { "maximum_text_length": null, "name": "Country", "guidelines": null, "is_required": false, "type": "text", "id": "2b36b05e-5f4f-4630-b502-154f5b3b90c3", "codename": "country" }, { "maximum_text_length": null, "name": "State", "guidelines": null, "is_required": false, "type": "text", "id": "3638f2cd-3fea-4a4e-a6b6-bdd39f3b9f66", "codename": "state" }, { "maximum_text_length": null, "name": "ZIP Code", "guidelines": null, "is_required": false, "type": "text", "id": "35ad677a-cfe5-4573-814d-5895e3de8396", "codename": "zip_code" }, { "maximum_text_length": null, "name": "Phone", "guidelines": null, "is_required": false, "type": "text", "id": "4ec54355-4177-4b29-9a16-b25a7c8fba26", "codename": "phone" }, { "maximum_text_length": null, "name": "Email", "guidelines": null, "is_required": false, "type": "text", "id": "9bc4b679-4353-40c7-bcfd-145110ced7d9", "codename": "email" }, { "asset_count_limit": null, "maximum_file_size": null, "allowed_file_types": "any", "image_width_limit": null, "image_height_limit": null, "name": "Photo", "guidelines": null, "is_required": false, "type": "asset", "id": "1693ecd3-fb15-4d56-975a-4b8dbdedf65b", "codename": "photo" } ] }

    If you plan to organize your content with taxonomies, you should add the taxonomy groups in advance as well.

    For the sake of simplicity, this tutorial will proceed without any taxonomies in the examples.

    2. Creating a content item

    To add a content item to your project, send a PUT request to the <YOUR_PROJECT_ID>/items/external-id/<YOUR_ITEM_EXTERNAL_ID> endpoint with your project ID. In the body of the request, specify these properties:

    • name – string with a display name of the new content item.
    • type – reference to a content type.

    In the URL, you also have to specify the external-id – the unique id of the content item you define (or the ID it had in your original system).

    Use your CM API Key in the authorization header of the request (in place of <YOUR_API_KEY> in the examples).

    • JavaScript
    // Using ES6 syntax import { ManagementClient } from "@kentico/kontent-management"; const client = new ManagementClient({ projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_API_KEY>" }); client.upsertContentItem() .byItemExternalId("ext-cafe-brno") .withData( { name: "Brno", type: "cafe" } ) .toObservable() .subscribe((response) => { console.log(response); }, (error) => { console.log(error); });
    // Using ES6 syntax import { ManagementClient } from "@kentico/kontent-management"; const client = new ManagementClient({ projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_API_KEY>" }); client.upsertContentItem() .byItemExternalId("ext-cafe-brno") .withData( { name: "Brno", type: "cafe" } ) .toObservable() .subscribe((response) => { console.log(response); }, (error) => { console.log(error); });
    • C#
    // Using CM API v1 using KenticoCloud.ContentManagement; ContentManagementOptions options = new ContentManagementOptions { ApiKey = "<YOUR_API_KEY>", ProjectId = "<YOUR_PROJECT_ID>" }; ContentManagementClient client = new ContentManagementClient(options); ContentItemCreateModel item = new ContentItemCreateModel { Name = "Brno", Type = ContentTypeIdentifier.ByCodename("cafe"), SitemapLocations = new[] { SitemapNodeIdentifier.ByCodename("cafes"), SitemapNodeIdentifier.ByCodename("europe") }, ExternalId = "ext-cafe-brno"; }; ContentItemModel responseItem = await client.CreateContentItemAsync(item);
    // Using CM API v1 using KenticoCloud.ContentManagement; ContentManagementOptions options = new ContentManagementOptions { ApiKey = "<YOUR_API_KEY>", ProjectId = "<YOUR_PROJECT_ID>" }; ContentManagementClient client = new ContentManagementClient(options); ContentItemCreateModel item = new ContentItemCreateModel { Name = "Brno", Type = ContentTypeIdentifier.ByCodename("cafe"), SitemapLocations = new[] { SitemapNodeIdentifier.ByCodename("cafes"), SitemapNodeIdentifier.ByCodename("europe") }, ExternalId = "ext-cafe-brno"; }; ContentItemModel responseItem = await client.CreateContentItemAsync(item);
    • cURL
    curl --request PUT \ --url https://manage.kontent.ai/v2/projects/<YOUR_PROJECT_ID>/items/external-id/ext-cafe-brno \ --header "Authorization: Bearer <YOUR_API_KEY>" \ --header "Content-type: application/json" \ --data " { "name": "Brno", "type": { "codename": "cafe" } }"
    curl --request PUT \ --url https://manage.kontent.ai/v2/projects/<YOUR_PROJECT_ID>/items/external-id/ext-cafe-brno \ --header "Authorization: Bearer <YOUR_API_KEY>" \ --header "Content-type: application/json" \ --data " { "name": "Brno", "type": { "codename": "cafe" } }"

    See our API Reference for more details on upserting content items.

    Best practice: Upsert by external ID 

    You can use a simple POST to /items request to add the content item. But using an UPSERT operation and defining an external ID for your item has advantages and makes the import process much smoother:

    • You can run the same request repeatedly. If the item doesn't exist, it will be created. If it does, it will be updated.
    • You can reference or link to your item, even if it hasn't been imported yet (and has no internal ID or codename). You might have other content items that reference this one in Rich text or Linked items elements. But if you are using external IDs you don't need to worry about the order in which the content items are imported.

    Kentico Kontent will generate an internal ID and codename for the content item and include it in the response.

    • JSON
    { "id":"8ceeb2d8-9676-48ae-887d-47ccb0f54a79", "name":"Brno", "codename":"brno", "type":{ "id":"fe41ae5a-5fe2-420a-8560-f7d6d3533dc2" }, "sitemap_locations":[ { "id":"a60fe91c-88ea-6990-fe3b-cf8f8504cd33" }, { "id":"ef86a740-9e4c-0b33-4275-ae78558e71a7" } ], "external_id": "ext-cafe-brno", "last_modified":"2017-11-09T16:51:09.041611Z" }
    { "id":"8ceeb2d8-9676-48ae-887d-47ccb0f54a79", "name":"Brno", "codename":"brno", "type":{ "id":"fe41ae5a-5fe2-420a-8560-f7d6d3533dc2" }, "sitemap_locations":[ { "id":"a60fe91c-88ea-6990-fe3b-cf8f8504cd33" }, { "id":"ef86a740-9e4c-0b33-4275-ae78558e71a7" } ], "external_id": "ext-cafe-brno", "last_modified":"2017-11-09T16:51:09.041611Z" }

    If your request fails, you will receive a 400 Bad request response with a specific error message telling you why.

    To verify that the (still empty) content item has been added, you have two options:

    A screenshot of a content list with a newly imported item.

    The created item will show up as Not translated inside your project.

    So far, you have only specified the general attributes of the content item such as its Name, Content type, and External ID. In the next step, we will add the actual (localized) content.

    3. Adding localized content

    To add content to a specific language to your new content item (even if your project only has one language), you need to perform another upsert operation.

    This means sending a PUT request to the correct endpoint specifying the language variant you want to insert or update. The language variant will contain the values of individual content elements.

    In the request URL, you need to specify the content item you are importing to (for example, <YOUR_PROJECT_ID>/items/external-id/ext-cafe-brno) and the language of the variant (for example, <YOUR_PROJECT_ID>/variants/codename/en-US). To get the codename of the language, you can list your languages or check the UI under Project settings -> Localization.

    A screenshot of where you can copy a language codename in the UI.

    The request body must contain a single attribute, the elements object. In this object, you specify only the content elements you want to update. Omitted elements will remain unchanged.

    • JavaScript
    // Using ES6 syntax import { ManagementClient } from "@kentico/kontent-management"; const client = new ManagementClient({ projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_API_KEY>" }); client.upsertLanguageVariant() .byItemExternalId("ext-cafe-brno") .byLanguageCodename("en-US") .withElements([ { element: { codename: "street" }, value: "Nove Sady 25" }, { element: { codename: "city" }, value: "Brno" }, { element: { codename: "country" }, value: "Czech Republic" }, { element: { codename: "state" }, value: "Jihomoravsky kraj" }, { element: { codename: "zip_code" }, value: "60200" }, { element: { codename: "phone" }, value: "+420 555 555 555" }, { element: { codename: "email" }, value: "brnocafe@kontent.ai" } ]) .toObservable() .subscribe((response) => { console.log(response); }, (error) => { console.log(error); });
    // Using ES6 syntax import { ManagementClient } from "@kentico/kontent-management"; const client = new ManagementClient({ projectId: "<YOUR_PROJECT_ID>", apiKey: "<YOUR_API_KEY>" }); client.upsertLanguageVariant() .byItemExternalId("ext-cafe-brno") .byLanguageCodename("en-US") .withElements([ { element: { codename: "street" }, value: "Nove Sady 25" }, { element: { codename: "city" }, value: "Brno" }, { element: { codename: "country" }, value: "Czech Republic" }, { element: { codename: "state" }, value: "Jihomoravsky kraj" }, { element: { codename: "zip_code" }, value: "60200" }, { element: { codename: "phone" }, value: "+420 555 555 555" }, { element: { codename: "email" }, value: "brnocafe@kontent.ai" } ]) .toObservable() .subscribe((response) => { console.log(response); }, (error) => { console.log(error); });
    • C#
    // Using CM API v1 using KenticoCloud.ContentManagement; ContentManagementOptions options = new ContentManagementOptions { ApiKey = "<YOUR_API_KEY>", ProjectId = "<YOUR_PROJECT_ID>" }; ContentManagementClient client = new ContentManagementClient(options); // Elements to update CafeContentTypeModel stronglyTypedElements = new CafeContentTypeModel { Street = "Nove Sady 25", City = "Brno", Country = "Czech Republic", State = "Jihomoravsky kraj", ZipCode = "60200", Phone = "+420 555 555 555", Email = "brnocafe@kontent.ai" }; ContentItemIdentifier itemIdentifier = ContentItemIdentifier.ByExternalId("ext-cafe-brno"); LanguageIdentifier languageIdentifier = LanguageIdentifier.ByCodename("en-US"); ContentItemVariantIdentifier identifier = new ContentItemVariantIdentifier(itemIdentifier, languageIdentifier); ContentItemVariantModel<CafeContentTypeModel> responseVariant = await client.UpsertContentItemVariantAsync<CafeContentTypeModel>(identifier, stronglyTypedElements);
    // Using CM API v1 using KenticoCloud.ContentManagement; ContentManagementOptions options = new ContentManagementOptions { ApiKey = "<YOUR_API_KEY>", ProjectId = "<YOUR_PROJECT_ID>" }; ContentManagementClient client = new ContentManagementClient(options); // Elements to update CafeContentTypeModel stronglyTypedElements = new CafeContentTypeModel { Street = "Nove Sady 25", City = "Brno", Country = "Czech Republic", State = "Jihomoravsky kraj", ZipCode = "60200", Phone = "+420 555 555 555", Email = "brnocafe@kontent.ai" }; ContentItemIdentifier itemIdentifier = ContentItemIdentifier.ByExternalId("ext-cafe-brno"); LanguageIdentifier languageIdentifier = LanguageIdentifier.ByCodename("en-US"); ContentItemVariantIdentifier identifier = new ContentItemVariantIdentifier(itemIdentifier, languageIdentifier); ContentItemVariantModel<CafeContentTypeModel> responseVariant = await client.UpsertContentItemVariantAsync<CafeContentTypeModel>(identifier, stronglyTypedElements);
    • cURL
    curl --request PUT \ --url https://manage.kontent.aiv2/projects/<YOUR_PROJECT_ID>/items/external-id/ext-cafe-brno/variants/codename/en-US \ --header "authorization: Bearer <YOUR_API_KEY>" \ --header "content-type: application/json" \ --data " { "elements": [ { "element": { codename: "street" }, "value": "Nove Sady 25" }, { "element": { codename: "city" }, "value": "Brno" }, { "element": { codename: "country" }, "value": "Czech Republic" }, { "element": { codename: "state" }, "value": "Jihomoravsky kraj" }, { "element": { codename: "zip_code" }, "value": "60200" }, { "element": { codename: "phone" }, "value": "+420 555 555 555" }, { "element": { codename: "email" }, "value": "brnocafe@kontent.ai" } ] }"
    curl --request PUT \ --url https://manage.kontent.aiv2/projects/<YOUR_PROJECT_ID>/items/external-id/ext-cafe-brno/variants/codename/en-US \ --header "authorization: Bearer <YOUR_API_KEY>" \ --header "content-type: application/json" \ --data " { "elements": [ { "element": { codename: "street" }, "value": "Nove Sady 25" }, { "element": { codename: "city" }, "value": "Brno" }, { "element": { codename: "country" }, "value": "Czech Republic" }, { "element": { codename: "state" }, "value": "Jihomoravsky kraj" }, { "element": { codename: "zip_code" }, "value": "60200" }, { "element": { codename: "phone" }, "value": "+420 555 555 555" }, { "element": { codename: "email" }, "value": "brnocafe@kontent.ai" } ] }"

    See our API Reference for details on how to Upsert a language variant of a content item.

    In the example above, we have used an external ID to specify the content item and a codename to specify its language variant. But you can also use their internal IDs or a combination of the two.

    The response will include the updated language variant.

    • JSON
    { "item":{ "id":"8ceeb2d8-9676-48ae-887d-47ccb0f54a79" }, "elements":{ "street":"Nove Sady 25", "city":"Brno", "country":"Czech Republic", "state":"Jihomoravsky kraj", "zip_code":"60200", "phone":"+420 444 444 444", "email":"brnocafe@kentico.com", "photo": [] }, "language":{ "id":"00000000-0000-0000-0000-000000000000" }, "last_modified":"2017-11-14T09:10:48.4469012Z" }
    { "item":{ "id":"8ceeb2d8-9676-48ae-887d-47ccb0f54a79" }, "elements":{ "street":"Nove Sady 25", "city":"Brno", "country":"Czech Republic", "state":"Jihomoravsky kraj", "zip_code":"60200", "phone":"+420 444 444 444", "email":"brnocafe@kentico.com", "photo": [] }, "language":{ "id":"00000000-0000-0000-0000-000000000000" }, "last_modified":"2017-11-14T09:10:48.4469012Z" }

    If your request fails, you will receive a 400 Bad request response with a specific error message telling you why.

    Kentico Kontent assigns an ID to each language in your project. The ID of the default language is always 00000000-0000-0000-0000-000000000000.

    To verify that the language variant has been imported, you have two options:

    How your Brno content item might look after import.

    What's next?

    In this tutorial, you imported a set of plain text content elements into a new content item. You can use the same process to import any number of more complex content items.