Kentico to Kontent.ai Migration: A Technical Guide
A technical guide to migrating from Kentico to Kontent.ai — content model mapping, SQL extraction, rich text transformation, and Management API import constraints.
Planning a migration?
Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.
Schedule a free call- 1,500+ migrations completed
- Zero downtime guaranteed
- Transparent, fixed pricing
- Project success responsibility
- Post-migration support included
Kentico to Kontent.ai Migration: A Technical Guide
Kentico and Kontent.ai share a founder and a name, but they are architecturally different systems. Kentico (Xperience 13 and its predecessors) is a traditional .NET CMS built around a SQL Server database, a content tree, page types, and tightly coupled server-side rendering. Kontent.ai is a headless, API-first content platform that stores structured content independently of any presentation layer and delivers it via REST and GraphQL APIs. Migrating between them means extracting relational data from SQL Server, redesigning your content model for a headless paradigm, transforming rich text and media references, and importing everything through the Kontent.ai Management API.
There is no built-in tool that moves content from Kentico to Kontent.ai. Despite their shared origin, the two platforms have been separate companies since July 2022, and no vendor-provided migration path exists. This guide covers the extraction, transformation, and loading process — the technical constraints, the model-mapping decisions, and the failure modes we see most often.
Scope clarification: This article covers the data migration — moving content, media, and metadata from Kentico into Kontent.ai. It does not cover the front-end rebuild required to consume Kontent.ai's APIs, which is a separate engineering effort.
How Kentico and Kontent.ai are related
Kontent.ai became a separate company in July 2022, when Kentico Xperience refreshed its name to Kentico, returning to its roots. The product started as Kentico Draft in 2016, relaunched as Kentico Cloud in 2017, rebranded to Kentico Kontent in 2019, and finally became Kontent.ai in 2022 after raising $40 million in growth capital to operate as a standalone company.
This history matters because teams on older Kentico versions sometimes assume there is a built-in upgrade path to Kontent.ai. There is not. Following the investment and split, Kentico Software continued development of its CMS product under the name Kentico Xperience, while Kontent by Kentico was rebranded as Kontent.ai. The two platforms share no database schema, no migration tooling, and no content model format. Moving between them is not an upgrade — it is a complete replatforming.
What the Kentico content model looks like on the source side
Kentico Xperience 13 stores content across multiple SQL Server tables. The CMS_Tree table stores data that determines the position of pages in the content tree and basic page properties shared between all language versions. CMS_Document stores page properties with unique values for each language version, plus page builder widget data. The DocumentNodeID column in CMS_Document references the related CMS_Tree record.
Page types use fields to define a data structure, and each page type has a separate database table storing the values of its defined fields. A page type called Article might store its custom fields in a table named SITE_Article, joined to CMS_Tree and CMS_Document via NodeID and DocumentForeignKeyValue.
Key source-side structures you need to extract:
- Page content — joined from
View_CMS_Tree_Joinedplus the page-type-specific table - Media library files — stored on the filesystem under
~/media/or in Azure Blob Storage, with metadata inMedia_LibraryandMedia_Filetables - Attachments — page-level attachments in
CMS_Attachment; unlike media library files, attachments are page-scoped and stored as binary blobs directly in the database (not on the filesystem), requiring a different extraction path - Page builder widgets — serialized JSON in
CMS_Document.DocumentPageBuilderWidgets - Categories / Taxonomies —
CMS_CategoryandCMS_DocumentCategorytables - Custom tables and modules — separate tables with their own schemas
- Relationships — node-level parent-child hierarchy, plus any relationship names defined in
CMS_RelationshipName
For a deep dive on extraction methods, see our guide on how to export data from Kentico.
What the Kontent.ai content model looks like on the target side
Kontent.ai limits you to 250 content types per environment, with 250 elements per content type and 50 content groups per type. That sounds generous until you realize a large Kentico site might have 80+ page types, dozens of custom tables, and widgets that each need their own content type in Kontent.ai.
Core building blocks in Kontent.ai:
- Content types — the equivalent of Kentico's page types, but presentation-agnostic; they define no URL, no tree position, and no template binding
- Content items — individual pieces of content based on a content type
- Linked items — explicit, reusable references between content items; replaces Kentico's content tree hierarchy and relationship names. Linked items can appear in multiple content items simultaneously.
- Components — inline, non-reusable content blocks embedded within a rich text element. Unlike linked items, a component exists only within its parent item and cannot be referenced elsewhere. Getting this distinction wrong during model design causes structural rework.
- Content type snippets — reusable groups of content elements shared across multiple types
- Taxonomies — flat or hierarchical classification applied to any content type
- Assets — binary files (images, PDFs, etc.) managed in a central library
Kontent.ai technical limits that affect migration
| Resource | Limit |
|---|---|
| Content types per environment | 250 |
| Elements per content type | 250 |
| Rich text element length | 100,000 characters |
| Language variant size | 450 kB (sum of all elements in a single language variant, including inline components) |
| Linked items per variant | 1,000 |
| Assets per environment | 1,000,000 |
| Max asset file size | 2 GB |
| Management API rate limit | 10 calls/sec, 400 calls/min |
| Bulk publish batch | 200 items at once |
| Languages per environment | 50 |
The Management API rate limit of 10 calls per second and 400 calls per minute is the primary throughput constraint. Each content item requires roughly 3–5 API calls (create item, upsert variant, upload asset, set workflow, publish), so you can import approximately 80–130 items per minute under ideal conditions. A 5,000-item migration takes approximately 40–60 minutes of pure API time, not accounting for asset upload time or retry delays.
How to map Kentico page types to Kontent.ai content types
This is the hardest part of the migration and cannot be automated. Kentico page types are page-centric — they assume a URL, a position in a tree, and often carry presentation logic (e.g., a "Hero Banner" page type or a "Two-Column Layout" page type). Kontent.ai content types are channel-agnostic — they have no inherent URL, no tree position, and no template binding.
Common mapping patterns:
-
One-to-one — A Kentico
Articlepage type maps to a Kontent.aiArticlecontent type. Field-by-field mapping. Straightforward when the page type is already semantically clean. -
Split — A Kentico page type with embedded widget data or mixed concerns gets split into a primary content type plus linked component types. A
LandingPagewith inline hero, CTA, and feature-grid widgets might becomeLanding_page+Hero+CTA+Feature_gridcontent types. Use linked items (not inline components) for elements that may be reused across pages; use components only for one-off inline blocks that will never be referenced elsewhere. -
Merge — Multiple Kentico page types that represent minor variations of the same content (e.g.,
NewsArticle,BlogPost,PressRelease) get merged into a single Kontent.ai type with a taxonomy or multiple-choice element to distinguish them. -
Flatten — Kentico's tree hierarchy (folder → subfolder → page) rarely maps directly. In Kontent.ai, hierarchy is expressed through linked items or taxonomy terms, not parent-child nesting.
Key structural changes to account for:
- Navigation: Kentico's
CMS_Treedictates navigation and URL structure. In Kontent.ai, you must build explicit "Navigation Item" content types that link to pages, or use taxonomies to drive menu structures. - Page URLs: Kentico generates URLs dynamically based on the tree path. In Kontent.ai, you must store the URL slug as a specific text element and handle routing in your front-end application.
- Inline widgets: Kentico allows editors to drop widgets directly into rich text or widget zones. In Kontent.ai, these become components (non-reusable, inline) or linked items (reusable references) within a Rich Text element, depending on whether the content needs to appear in multiple locations.
Page builder widget content is the most painful extraction. All content added directly to a page builder widget is stored in a single database field (CMS_Document.DocumentPageBuilderWidgets), making it difficult to reuse. You need to parse this JSON, identify each widget type, and extract its properties into separate content items in Kontent.ai.
How to extract content from Kentico
Direct SQL extraction from the Kentico database is the most reliable method. The native Kentico export is designed for Kentico-to-Kentico transfers only and does not include files from a separate MVC project. The REST API in KX13 supports pagination for objects but not for pages, making it unreliable for bulk extraction.
Direct SQL extraction (recommended)
For enterprise migrations, querying the Kentico SQL database directly bypasses Kentico's caching layers, avoids API rate limits, and lets you join custom page type data with system metadata in a single query.
A practical extraction query for a page type called Article:
SELECT
t.NodeGUID,
t.NodeAliasPath,
t.NodeLevel,
d.DocumentCulture,
d.DocumentName,
d.DocumentPublishFrom,
d.DocumentPublishTo,
d.DocumentModifiedWhen,
a.ArticleTitle,
a.ArticleSummary,
a.ArticleBody,
a.ArticleTeaserImage
FROM View_CMS_Tree_Joined t
INNER JOIN CMS_Document d ON t.NodeID = d.DocumentNodeID
INNER JOIN SITE_Article a ON d.DocumentForeignKeyValue = a.ArticleID
WHERE t.ClassName = 'SITE.Article'
AND d.DocumentIsArchived = 0
ORDER BY t.NodeAliasPathNote the inclusion of DocumentModifiedWhen — this is the field used to detect changed records in delta sync runs (covered below). Export results as JSON (preferred) or CSV. For media library files, query Media_File joined to Media_Library to get file paths and metadata, then copy the binary files from the filesystem or blob storage. For page attachments, binary data is stored directly in the CMS_Attachment table (not on disk), so extraction requires reading the AttachmentBinary column rather than reading from the filesystem.
Kentico REST API
If you do not have direct database access, the Kentico REST API can retrieve objects. It requires significant pagination logic and struggles with deep relational joins. Extracting a single article often requires separate calls for the page data, the linked categories, and the attached images. At scale, this introduces heavy latency and increases the risk of timeout errors.
For the complete extraction playbook, including API methods and their constraints, see How to Export Data from Kentico.
How to transform rich text for Kontent.ai
The highest risk of data corruption in a Kentico to Kontent.ai migration lies in the rich text fields. Kentico stores rich text as arbitrary HTML — inline styles, custom CSS classes, <iframe> embeds, raw <img> tags with relative URLs, and proprietary macros (e.g., {% CurrentUser.UserName %}). Kontent.ai's rich text element accepts a restricted subset of HTML: headings (h1–h6), paragraphs, bold, italic, links, ordered/unordered lists, tables, and images wrapped in <figure> tags.
If you push raw Kentico HTML into Kontent.ai, the Management API will either silently strip unsupported elements or return a 400 Bad Request for malformed rich text. A typical 400 response body looks like:
{
"requestId": "...",
"error_code": 5,
"message": "The provided value is not valid. The element 'body' contains invalid HTML."
}Your front end will also break on unresolved macros and hardcoded media URLs after asset migration changes all CDN paths.
The transformation pipeline:
-
Strip disallowed HTML. Remove
<div>wrappers,<span>tags with inline styles, custom CSS classes,<script>tags, and<iframe>embeds. None of these pass Kontent.ai's rich text validation. -
Remove proprietary macros. Identify and strip Kentico-specific macros (
{% ... %}) that have no equivalent in a headless front end. -
Convert inline images to asset references. Kontent.ai does not allow
<img>tags inside<p>tags in rich text. Images in rich text must be represented with a<figure>tag referencing an item in Kontent.ai's asset library. Each inline image must be uploaded as an asset first, then referenced by its asset ID:
<figure data-asset-id="asset-id-from-kontent"></figure>-
Replace media URLs. Find all
~/getattachment/,~/getmedia/, and media library paths in rich text. Replace them with the new Kontent.ai CDN URLs (assets.kontent.ai) after asset upload. -
Extract inline widgets as components. Parse Kentico inline widgets from
DocumentPageBuilderWidgetsJSON. Extract each widget's properties, create a Kontent.ai content item or component for it, and replace the original widget HTML with Kontent.ai's object tag:
<object type="application/kenticocloud" data-type="item" data-rel="component" data-codename="my_extracted_widget"></object>- Convert internal links. Kentico internal links typically use
NodeAliasPathorNodeGUID. In Kontent.ai, internal links in rich text use a specific format referencing content item IDs or codenames.
Kontent.ai provides the @kontent-ai/rich-text-resolver npm package for this work. As of v2.x, the package provides RichTextToHtmlConverter and browserParse utilities that handle traversal of the rich text AST and resolution of linked items and assets. However, it does not handle Kentico-specific HTML patterns — custom <div> wrappers, Kentico macros, and media URL rewriting are transformations you must write before passing content to the resolver. Test your sanitizer against the Management API on 50–100 representative rich text samples before running the full import.
What happens when language variant size is exceeded: If a content item's total element data exceeds 450 kB, the Management API returns a 400 error with a message indicating the variant size limit. The remedy is to split the oversized rich text into multiple linked content items (e.g., split a long article body into sections) and reference them via a linked items element in the parent type.
Migrating media and assets
Media must be migrated before content. Kontent.ai content items cannot reference assets that do not yet exist in the project.
Two distinct Kentico media sources with different extraction paths:
- Media library files — stored on the filesystem (or Azure Blob Storage) with metadata in
Media_LibraryandMedia_Filetables. Extract by reading the physical file path fromFileLocationinMedia_File, then copying the binary from disk or blob storage. - Page attachments — stored as binary data in the
AttachmentBinarycolumn ofCMS_Attachment, scoped to a specific page. These are not on the filesystem. Extract by reading the binary column directly from SQL.
The asset migration sequence:
- Extract the binary file from the Kentico filesystem, Azure Blob Storage, or
CMS_Attachment.AttachmentBinary. - Call the Kontent.ai Management API to create a new file reference:
POST /files/{filename}. - Upload the binary data. Kontent.ai requires chunked uploads for files over a certain size threshold.
- Call the API to create the asset metadata (title, description) and link it to the uploaded file:
POST /assets. - Store the resulting Kontent.ai Asset ID in your mapping table — you need this to resolve image references in content items and rich text fields.
The maximum file size is 2 GB, and you can store up to 1,000,000 assets per environment. Asset upload time is a significant factor for media-heavy sites and is not subject to the 400 calls/minute rate limit — it is constrained by bandwidth and file size instead.
How to import content into Kontent.ai
You have two paths: the Kontent.ai Migration Toolkit or the Management API directly.
Migration Toolkit vs. direct Management API: structured comparison
| Capability | Migration Toolkit | Direct Management API |
|---|---|---|
| Deferred references | ✅ Resolves forward references automatically | ❌ Must import in dependency order or use external_id placeholders manually |
| Rate limit handling | ✅ Built-in retry logic | ❌ Must implement exponential backoff yourself |
| Error granularity | ⚠️ Abstracted — harder to inspect per-item failures | ✅ Full HTTP response body per call |
| Logging | ⚠️ Limited to toolkit output | ✅ Full control — log every request/response |
| Asset upload | ✅ Handled via MigrationAsset [] |
✅ Manual — more control over chunking |
| Workflow management | ✅ Automated | ✅ Manual — explicit step transitions |
| Custom retry strategy | ❌ Uses built-in strategy | ✅ Full control |
| Best for | Straightforward migrations, standard workflow | Complex migrations, non-standard workflow, debugging |
Kontent.ai Migration Toolkit
The Migration Toolkit facilitates content migration to and from Kontent.ai environments and can simplify migration from external systems. It provides an abstraction layer handling creation and updates of content items, language variants, moving items through workflow, publishing, archiving, downloading binary data, uploading assets, and ID-to-codename translation.
The import flow with the toolkit:
- Prepare
MigrationItem []— map your textual and structured content toMigrationItemobjects. - Prepare
MigrationAsset []— map your binary files toMigrationAssetobjects. - Call
importAsync()— import the mapped content from theMigrationItemandMigrationAssetobjects to your Kontent.ai project.
If you have a reference to a content item or asset (in linked items, asset elements, or rich text), the Migration Toolkit first checks whether the referenced object exists based on codename. If it does, it sets the reference. If not, it will be referenced by an external_id which creates a placeholder until it becomes available. This deferred-reference mechanism means you do not need to import items in strict dependency order — but verify that all placeholders resolve after import by checking for unresolved external_id references via the Management API's content item listing endpoint.
Direct Management API
If you need finer control, call the Management API directly. The typical sequence per item:
- Upsert content item —
PUT /items/external-id/{external_id} - Upsert language variant —
PUT /items/external-id/{external_id}/variants/codename/{language} - Upload asset binary —
POST /files/{filename}thenPOST /assets - Move through workflow —
PUT /items/{item_id}/variants/{variant_id}/workflow/{step_id} - Publish —
PUT /items/{item_id}/variants/{variant_id}/publish
Kontent.ai enforces workflow states — you cannot create an item in a "Published" state directly. Every item starts in Draft and must be moved through workflow steps explicitly.
Handling rate limit errors: When you exceed the 400 calls/minute limit, Kontent.ai returns 429 Too Many Requests. The response includes a Retry-After header specifying the number of seconds to wait before retrying. Implement exponential backoff with jitter: on first 429, wait Retry-After seconds; on subsequent 429s for the same request, double the wait time up to a maximum of 60 seconds. Log every 429 with the request timestamp and endpoint — this data helps identify which content types or asset sizes are triggering throttling.
Use external_id everywhere. Assign a deterministic external ID to every content item and asset — for example, the NodeGUID from Kentico. This makes your import script idempotent: you can re-run it without creating duplicates. If the script fails halfway through, the API recognizes the external_id and updates the existing item rather than creating a new one.
Import order
Kontent.ai requires that content types exist before you create content items, and assets must be uploaded before they can be referenced in rich text. The correct sequence:
- Taxonomies — create taxonomy groups and terms
- Content types — create all content types (including snippets) via the Management API or Kontent.ai CLI
- Assets — upload all binary files
- Content items — create items with their variants, referencing assets and other items by codename or external ID
- Publish — move items through workflow steps to "Published"
The Migration Toolkit handles steps 3–5 in a single pass using deferred references. Content types (step 2) must still be created separately — you can migrate content items and assets between environments, but for migrating data model and structure, use the Kontent.ai Data Ops tooling instead.
Delta sync mechanics
A delta sync is a subsequent import run that moves only content changed since the initial migration — used when a migration window is long, when you need to keep a staging import current, or when you need to re-sync after editors continue working in Kentico post-migration.
How to identify changed records in Kentico for a delta run:
- Use
CMS_Document.DocumentModifiedWhenas the change timestamp. Store the completion timestamp of your previous import run, then filter:WHERE d.DocumentModifiedWhen > @LastRunTimestamp. - For net-new items,
DocumentModifiedWhenwill be later than your stored timestamp. For modified items, the same condition applies. - For deleted items, query
CMS_Documentagainst your stored inventory of migratedNodeGUIDvalues to detect rows that no longer exist.
Handling deletes in Kontent.ai: The Management API supports DELETE /items/{item_identifier} for content items and DELETE /assets/{asset_identifier} for assets. Build a reconciliation step that compares your Kentico extraction against your migration log and issues delete calls for records removed from the source.
Delta sync limitations: If editors have worked in Kontent.ai directly (not just in Kentico) during the delta window, their changes will be overwritten when you upsert the same content item. Coordinate with editorial teams to freeze Kontent.ai edits during delta runs, or implement a merge strategy based on variant modification timestamps from the Kontent.ai Management API (GET /items/{item_id}/variants/{variant_id} returns last_modified).
Multilingual content: how language handling differs
Kentico stores language versions as separate CMS_Document rows linked to the same CMS_Tree node. Kontent.ai stores them as language variants of the same content item. The mapping is straightforward — one document culture per variant — but watch for these differences:
- Kontent.ai's default language is set at project creation and cannot be changed afterward. Plan this before creating your target environment.
- Only newly added elements can be marked as non-localizable in Kontent.ai, and rich text elements cannot be non-localizable. If your Kentico content has fields shared across all cultures (like a product SKU), design the content type with those elements as non-localizable from the start — you cannot change this after content has been created.
- Kontent.ai supports up to 50 languages per environment — sufficient for most Kentico migrations.
- Map Kentico's
DocumentPublishFromandDocumentPublishTodates to custom date-time elements in Kontent.ai. Kontent.ai's native scheduling (scheduled_toon the publish endpoint) works differently and cannot retroactively represent historical publish dates.
Common failure modes
Rich text rejection
The Management API returns a 400 error for malformed rich text containing <div>, <span class="...">, <iframe>, or other disallowed elements. It may also silently strip some unsupported attributes without returning an error — leaving content that looks correct in the API response but renders differently than expected. Build and test your HTML sanitizer on a representative sample of 50–100 rich text fields before running the full import.
Asset URL breakage
Kentico serves media from /getmedia/, /getattachment/, or media library paths. After migration, all asset URLs change to Kontent.ai's CDN (assets.kontent.ai). Hardcoded media URLs in rich text, email templates, or external systems will break. Run a grep-equivalent scan across all rich text fields for these URL patterns and rewrite them during transformation, not after import.
Language variant size exceeded
If a content item's total element data exceeds 450 kB (including inline components in rich text), the Management API returns a 400 error. The error message references the variant size limit. Remedy: split oversized rich text into multiple linked content items and reference them via a linked items element.
Unresolved deferred references
When using the Migration Toolkit's deferred reference mechanism, placeholders are created for items that don't yet exist. After import completes, audit for unresolved external_id references by listing content items and checking for items whose linked item or asset elements contain placeholder IDs rather than resolved codenames. The Management API's list endpoints support filtering to identify items in incomplete states.
Page builder widget data loss
Widget content serialized in DocumentPageBuilderWidgets has no structured schema exposed to external tools. Each widget type needs custom parsing logic written against that widget type's known JSON structure. If you skip widgets, you lose content that editors added through the page builder — and editors may not realize it is missing until after cutover.
Taxonomy term depth
Kontent.ai taxonomies support hierarchical terms, but the platform limits terms to a maximum nesting depth. If your Kentico site uses deeply nested categories, flatten them during taxonomy design. Map the full breadcrumb path as the term name if you need to preserve the original hierarchy semantically.
Should you migrate to Kontent.ai or Xperience by Kentico?
This is a legitimate question for teams on KX13, especially with the KX13 end-of-support deadline approaching. If you are evaluating the broader market, you might also be considering a Kentico to Contentful migration for an alternative headless approach, or a Kentico to Optimizely migration if you want to stay on an enterprise .NET DXP.
Choose Kontent.ai if:
- You want a headless, API-first CMS decoupled from your front end
- You are building (or already have) a custom front end in Next.js, Nuxt, Gatsby, or another framework
- You need multi-channel content delivery (web, mobile app, digital signage)
- Your team is comfortable owning the front-end hosting and delivery infrastructure
Choose Xperience by Kentico if:
- You want an integrated DXP with built-in marketing automation, forms, and email
- You prefer a .NET-based stack with server-side rendering
- You want Kentico's official migration tooling (the Kentico Migration Tool) for a KX13 → XbyK upgrade
- Your team's core skill set is .NET development
If you are evaluating the official Kentico Migration Tool for the XbyK path, be aware of its documented limitations — what Kentico's migration tool doesn't move is a longer list than most teams expect. Teams requiring heavier enterprise personalization often pivot to a Kentico to Sitecore migration at this juncture.
Pre-migration checklist
- Audit Kentico page types — count types, fields, and content items per type
- Identify all media sources — media library (filesystem/blob), page attachments (database binary), page builder inline images
- Map Kentico page types to Kontent.ai content types (document every field mapping, decide linked items vs. components per relationship)
- Design Kontent.ai taxonomy groups to replace Kentico categories
- Catalog all rich text patterns — inline images, iframes, custom macros, dynamic controls
- Decide default language before creating the Kontent.ai environment (cannot be changed after creation)
- Create a Kontent.ai test environment (never import directly into production first)
- Build and test the HTML sanitizer against the Management API on 50–100 representative samples
- Set up URL redirects from old Kentico paths to new front-end routes
- Implement exponential backoff with
Retry-Afterheader handling in your import script - Record
DocumentModifiedWhenbaseline timestamp for delta sync runs - Coordinate a designated migration maintenance window with relevant stakeholders — halt editorial work in Kentico during the import to avoid delta sync conflicts
Start scoping at least 3–4 months before any internal deadline. Content model redesign and rich text transformation take iteration — they are not tasks you can compress into the final week.
How long does a Kentico to Kontent.ai data migration take?
The data migration — extracting from Kentico and importing into Kontent.ai — depends on content volume, the number of page types requiring model redesign, and the complexity of rich text transformation.
- 1–500 content items: 1–2 business days, including model mapping and validation
- 500–5,000 items: 3–7 business days, with rich text transformation as the primary time sink
- 5,000+ items: Usually requires an initial bulk migration followed by delta syncs. Larger engagements typically run 7–13+ business days depending on API rate limits, data complexity, and customer availability for review cycles
At the Management API's ceiling of 400 calls per minute and 3–5 calls per item, the hard throughput floor for 5,000 items is approximately 40–60 minutes of pure API time — before accounting for asset upload time, 429 retries, and validation failures that require re-processing.
These figures describe the data migration only. The front-end rebuild to consume Kontent.ai's APIs is a separate effort measured in months, not days. Separate the two timelines and scope both early.
The Kontent.ai Management API rate limit of 400 calls per minute is a hard constraint on import throughput. For large migrations, implement Retry-After header handling for 429 responses and budget separately for asset upload time on media-heavy sites.
What ClonePartner handles in a Kentico-to-Kontent.ai migration
We extract content from Kentico via direct SQL and transform it for Kontent.ai's Management API. Our transfer preference is API > JSON > CSV; CSV is the least preferred option. Each project gets a dedicated migration engineer — not a ticket queue — and that engineer is the only person who can view the data.
The process: connect accounts → migration checklist → sample migration → full migration → delta sync. We run unlimited sample migrations until the data mapping is right, and re-migration comes at no additional cost. One fixed price per project, starting at $500 — no hourly billing, no hidden fees, no change orders.
Frequently Asked Questions
- Is there a migration tool from Kentico to Kontent.ai?
- No. Despite their shared origin, Kentico and Kontent.ai have been separate companies since July 2022 and share no migration tooling. You need to extract from Kentico (direct SQL is the most reliable method), transform your content model and rich text, and import via the Kontent.ai Management API or Migration Toolkit.
- How long does a Kentico to Kontent.ai data migration take?
- The data migration typically takes 1–5 business days depending on volume, complexity, and API rate limits. Small datasets under 10,000 records can finish in under 24 hours. Larger engagements with 5,000+ items run approximately 7–13+ business days. This does not include the front-end rebuild to consume Kontent.ai's APIs, which is a separate effort.
- What are the Kontent.ai Management API rate limits for migration?
- The Management API allows 10 calls per second and 400 calls per minute per environment. Since each content item requires 3–5 API calls (create, upsert variant, upload assets, workflow, publish), expect to import roughly 80–130 items per minute.
- Can Kentico rich text be imported directly into Kontent.ai?
- No. Kentico stores arbitrary HTML including custom CSS classes, iframes, inline styles, and proprietary macros. Kontent.ai rich text accepts only a restricted HTML subset (headings, paragraphs, lists, tables, links, and asset-referenced images). You must sanitize the HTML, strip macros, and convert inline images to Kontent.ai asset references before import.
- Should I migrate from Kentico to Kontent.ai or Xperience by Kentico?
- Choose Kontent.ai if you want a headless, API-first CMS with a custom front end and multi-channel delivery. Choose Xperience by Kentico if you want an integrated DXP with built-in marketing tools and prefer to stay in the .NET ecosystem. Kentico offers an official Migration Tool for the KX13-to-XbyK path, though it has documented gaps.