Import Knowledge Base Articles
POST /import - Import Knowledge Base Articles
Import or update knowledge base articles with multilingual content support. This endpoint handles creating new articles or updating existing ones based on correlation IDs.
Endpoint
POST /v1/knowledgebase/importRequest Headers
Header | Value | Required |
|---|---|---|
|
| Yes |
|
| Yes |
Request Body Parameters
Parameter | Type | Required | Description |
|---|---|---|---|
|
| Yes | Array of articles to import. At least one article is required |
|
| No | Configuration options for the import process |
Article Object (articles[])
Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
|
| No | Unique identifier for article correlation. Use for updates |
|
|
| No | Category correlation ID for article organization |
|
|
| No | Whether article is private (not visible to end users) |
|
|
| No | Whether article is hidden from navigation/search |
|
|
| No | Display order within category (1-based) |
|
|
| No | Whether article should be featured |
|
|
| No | Order for featured articles display |
|
|
| No | Alternative slugs by language for URL redirection |
|
|
| No | Content items in different languages | See Content Object below |
Content Object (contents[])
Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
|
| No | Unique identifier for content correlation |
|
|
| Yes | Language code (ISO 639-1 format) |
|
|
| No | Article title in this language |
|
|
| No | URL-safe slug (auto-generated if not provided) |
|
|
| No | Main article content | `"# Welcome This guide..."` |
|
| No | SEO keywords |
|
|
| No | Article excerpt or summary |
|
|
| Yes | Content format: |
|
|
| No | Create new version instead of updating |
|
|
| No | Publishing status: |
|
|
| No | Featured content display order |
|
Config Object (config)
Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
|
| No | How to handle slug conflicts: |
|
|
| No | Allow partial imports by ignoring non-serious errors |
|
|
| No | Include full content details in response |
|
Example Request
Request Body:
{
"articles": [
{
"correlationId": "getting-started-001",
"categoryCorrelationId": "tutorials",
"isPrivate": false,
"contents": [
{
"lang": "en",
"title": "Getting Started Guide",
"content": "# Welcome\n\nThis guide will help you get started with our platform quickly and easily.",
"keywords": "getting started, tutorial, guide",
"format": "markdown",
"publishStatus": "published"
}
]
}
]
}Response Format
Success Response (200 OK)
{
"errors": [],
"results": [
{
"correlationId": "article-001",
"articleId": 123,
"status": "created",
"categoryId": 456,
"isPrivate": false,
"isHidden": false,
"isFeatured": true,
"featuredOrder": 1,
"order": 5,
"version": "v1",
"alternateSlugs": "{\"en\":[\"old-slug\"]}",
"contents": [
{
"correlationId": "content-en-001",
"lang": "en",
"contentId": 789,
"slug": "getting-started",
"status": "created",
"published": true,
"title": "Getting Started Guide",
"content": "# Welcome...",
"keywords": "tutorial, guide",
"lead": "Learn the basics..."
}
],
"errors": []
}
]
}Status Values
Article Status Values
created: New article was createdupdated: Existing article was updatederror: Article processing failed
Content Status Values
created: New content was createdupdated: Existing content was updatederror: Content processing failed
Article Ordering System
Understanding how article positioning works is crucial for proper content organization:
Order Field
- Scope: Per category (within each category)
- Behavior: Determines the display order of articles within their assigned category
- Auto-assignment: When creating new articles, the order is automatically set to
(current_articles_in_category + 1) - Manual control: You can specify a custom order value to position articles precisely within their category
Featured Order Field
- Scope: Global (across all articles)
- Behavior: Determines the display order for articles marked as
isFeatured: true - Usage: Featured articles appear in a special "featured" section, ordered by this field
- Default:
0(not featured) whenisFeatured: false
Examples
Category-based ordering:
{
"correlationId": "tutorial-basic",
"categoryCorrelationId": "tutorials",
"order": 1, // First article in "tutorials" category
"isFeatured": false
}Featured article ordering:
{
"correlationId": "important-announcement",
"categoryCorrelationId": "news",
"order": 5, // 5th article in "news" category
"isFeatured": true,
"featuredOrder": 1 // First in global featured section
}Content Versioning System
Each article can have multiple content versions in each language. Understanding when to create new versions vs updating existing ones is important for content management:
Create New Version (createNewVersion: true)
- Purpose: Preserves the current version and creates a completely new version
- Use case: Major content updates, A/B testing, keeping revision history
- Behavior: Current version remains unchanged, new version is created with your content
- Publishing: New version starts as unpublished by default (unless you specify
publishStatus: "published")
Update Existing Version (createNewVersion: false or omitted)
- Purpose: Modifies existing content with intelligent version selection
- Selection logic:
- First priority: Published content (only one version per language can be published)
- Fallback: Most recently created content if no published version exists
- Intuitive behavior: Updates the published version when available, as expected by most users
- Fallback behavior: Only updates drafts/unpublished content when no published version exists
- Best practice: Still recommend using content
correlationIdfor precise version targeting - Use case: Minor edits, corrections, updates to existing content
- Behavior: Overwrites the selected existing content version
- Publishing: Maintains current publishing status of the selected version (unless you specify
publishStatus)
Version Management Examples
Creating a new version (keeping history):
{
"correlationId": "user-guide-001",
"contents": [
{
"correlationId": "guide-en-v2",
"lang": "en",
"title": "Updated User Guide",
"content": "# Version 2.0\n\nMajor updates to the user guide...",
"format": "markdown",
"createNewVersion": true, // Creates new version
"publishStatus": "unpublished" // New version starts as draft
}
]
}Updating existing version (quick edit):
{
"correlationId": "user-guide-001",
"contents": [
{
"correlationId": "guide-en-published", // Target specific version by correlation ID
"lang": "en",
"title": "User Guide (Updated)",
"content": "# User Guide\n\nFixed typos and updated screenshots...",
"format": "markdown",
"createNewVersion": false // Updates existing version
// publishStatus omitted = keeps current status
}
]
}Advanced approach for precise version targeting:
// For maximum control, use correlation IDs to target specific versions
{
"correlationId": "user-guide-001",
"contents": [
{
"correlationId": "guide-en-v1-published", // Target specific version by ID
"lang": "en",
"title": "Updated Published Guide",
"content": "Updated content for the live version...",
"format": "markdown",
"createNewVersion": false
}
]
}Version selection behavior:
// Scenario: Article has 3 content versions for language "en"
// Version 1: Created 2024-01-01, Unpublished (draft)
// Version 2: Created 2024-01-15, Unpublished (draft)
// Version 3: Created 2024-01-10, Published ✅ (only one can be published per language)
// This update will modify Version 3 (the published version) ✅
{
"correlationId": "article-001",
"contents": [
{
"lang": "en",
"title": "Updated Title",
"createNewVersion": false // Updates Version 3 (published version)
}
]
}
// If no published versions exist, falls back to most recent
// All drafts scenario: Version A (2024-01-01, Draft), Version B (2024-01-15, Draft)
// Result: Would update Version B (most recent draft)Version workflow example:
- Initial version:
createNewVersion: false(creates first version) - Minor edits:
createNewVersion: false(updates published version if available, otherwise most recent) - Major rewrite:
createNewVersion: true(preserves old, creates new) - Publish new: Update with
publishStatus: "published"
Slug Management System
Slugs are URL-friendly identifiers used to access articles. Understanding how slug generation and conflict resolution works is essential for SEO and URL management:
Auto-Generation from Title
When you don't provide a slug field during content creation, the system automatically generates one from the article title:
- Only on create: Auto-generation happens only when creating new content versions
- On update: When updating existing content, the current slug value is preserved if no slug is provided
- Source: Uses the
titlefield from content - Process: Converts title to URL-safe format (lowercase, spaces to hyphens, special characters removed)
- Language-specific: Each language gets its own slug based on its title
- Uniqueness: Must be unique within the same language
Manual Slug Assignment
You can specify custom slugs for precise URL control:
{
"lang": "en",
"title": "Advanced User Guide for Professionals",
"slug": "pro-user-guide", // Custom slug instead of auto-generated
"content": "...",
"format": "markdown"
}Slug Conflict Resolution
When slug conflicts occur (duplicate slugs in the same language), you have two options:
Option 1: Error on Conflict (Default)
{
"config": {
"slugConflictHandling": "error" // Default behavior
}
}- Behavior: API returns error when slug conflict detected
- Response:
"Slug 'getting-started' for language 'en' is already in use" - Use case: When you want full control and need to resolve conflicts manually
Option 2: Auto-Number Resolution
{
"config": {
"slugConflictHandling": "auto-number"
}
}- Behavior: Automatically appends numbers to make slugs unique
- Examples:
getting-started→getting-started-2→getting-started-3 - Use case: Bulk imports where some conflicts are acceptable
Slug Examples
Auto-generated slugs (on create):
// Creating new content - slug auto-generated from title
{
"lang": "en",
"title": "Getting Started Guide", // → slug: "getting-started-guide" (auto-generated)
"content": "...",
"format": "markdown"
// No slug provided, so auto-generated
}
// More examples:
// "FAQ & Troubleshooting" → slug: "faq-troubleshooting"
// "User Management (Admin)" → slug: "user-management-admin"Slug behavior on update:
// Updating existing content - slug preserved
{
"correlationId": "existing-content-en",
"lang": "en",
"title": "Updated Getting Started Guide", // Title changed
"content": "Updated content...",
"format": "markdown"
// No slug provided → keeps existing slug "getting-started-guide"
// Slug does NOT change to "updated-getting-started-guide"
}
// To change slug on update, explicitly provide it:
{
"correlationId": "existing-content-en",
"lang": "en",
"title": "Updated Getting Started Guide",
"slug": "new-getting-started-guide", // Explicitly change slug
"content": "Updated content...",
"format": "markdown"
}Manual slugs with conflict resolution:
{
"articles": [
{
"correlationId": "guide-1",
"contents": [
{
"lang": "en",
"title": "Getting Started",
"slug": "getting-started" // First article gets this slug
}
]
},
{
"correlationId": "guide-2",
"contents": [
{
"lang": "en",
"title": "Quick Start Guide",
"slug": "getting-started" // Conflict! Will become "getting-started-2"
}
]
}
],
"config": {
"slugConflictHandling": "auto-number"
}
}Multilingual slug management:
{
"contents": [
{
"lang": "en",
"title": "User Guide",
"slug": "user-guide" // English slug
},
{
"lang": "es",
"title": "Guía del Usuario",
"slug": "guia-usuario" // Spanish slug (different from English)
},
{
"lang": "fr",
"title": "Guide Utilisateur"
// No slug provided → auto-generated: "guide-utilisateur"
}
]
}Best Practices for Slugs
- SEO-friendly: Use descriptive, keyword-rich slugs
- Consistent format: Stick to lowercase, hyphens for spaces
- Language appropriate: Use language-specific slugs for better localization
- Avoid conflicts: Check existing slugs before bulk imports
- Auto-numbering for imports: Use
auto-numberfor large batch imports - Manual for important pages: Specify custom slugs for key articles
Best Practices
- Use Correlation IDs: Always provide correlation IDs for articles and content you want to update later
- Handle Conflicts: Set appropriate slug conflict handling based on your needs
- Test First: Use the test environment to validate your import payload before production. ⚠️ Warning: The API can overwrite all your content and changes are not revertible. Always backup your data using GET endpoints before making changes
- Language Consistency: Ensure language codes are consistent across your content
- Content Validation: Validate markdown/HTML content before importing
Common Error Scenarios
- Missing Required Fields: Ensure
langandformatare provided for all content - Invalid Correlation IDs: Check that correlation IDs don't contain invalid characters
- Slug Conflicts: Use auto-numbering or ensure unique slugs when creating content
- Category References: Verify that category correlation IDs exist before referencing them
- Content Format: Ensure content matches the specified format (markdown/html)
Error Response (400 Bad Request)
The API returns different types of errors depending on what went wrong:
- HTTP 400: Validation errors, malformed requests, or business logic violations
- HTTP 401: Authentication failures or invalid API tokens
- HTTP 500: Internal server errors during processing
Error messages include array indices (e.g., Article[0], Article[1].contents[0]) to help you identify exactly which item in your request caused the issue.
Validation Errors
{
"errors": [
"Too many articles for import. Maximum allowed: 50, provided: 75",
"Article[0]: Too many languages per article. Maximum allowed: 20, provided: 25",
"Article[1]: Language 'en' is required for content",
"Article[2]: Content format 'html' is required but not provided",
"Article[3]: Article with correlation ID 'duplicate-id' appears multiple times in request"
]
}Content Validation Errors
{
"errors": [
"Article[0].contents[0]: Title is required when creating new content",
"Article[1].contents[1]: Invalid language code 'english' - use ISO 639-1 format (e.g., 'en')",
"Article[2].contents[0]: Slug 'getting-started' for language 'en' is already in use. Use slugConflictHandling: 'auto-number' to automatically resolve conflicts.",
"Article[3].contents[0]: Manual slug_state requires a non-empty slug value",
"Article[4].contents[0]: Invalid publish status 'draft' - use 'published' or 'unpublished'"
]
}Category Reference Errors
{
"errors": [
"Article[0]: Category with correlation ID 'non-existent-category' not found",
"Article[1]: Category correlation ID cannot be empty string",
"Article[2]: Invalid category correlation ID format"
]
}Content Update Errors
{
"errors": [
"Article[0].contents[0]: Content with correlation ID 'missing-content' not found for update",
"Article[1].contents[0]: Cannot update content - article with correlation ID 'missing-article' not found",
"Article[2].contents[0]: Language 'es' content not found in existing article 'help-guide'"
]
}Request Format Errors
{
"error": "Body not present"
}{
"error": "Invalid request body - malformed JSON"
}Mixed Errors (with ignoreImportErrors: true)
{
"errors": [
"Article[0]: Category 'tutorials' not found - article created without category",
"Article[2]: Slug conflict resolved: 'getting-started' changed to 'getting-started-2'",
"Article[4]: Content validation failed - title missing, using 'Untitled' as default"
],
"results": [
{
"correlationId": "article-001",
"status": "created",
"articleId": 123
},
{
"correlationId": "article-003",
"status": "created",
"articleId": 124
}
]
}Examples
Example 1: Simple Article Import
Create a new article with English content:
{
"articles": [
{
"correlationId": "getting-started-001",
"categoryCorrelationId": "tutorials",
"isPrivate": false,
"contents": [
{
"lang": "en",
"title": "Getting Started Guide",
"content": "# Welcome to Our Platform\n\nThis guide will help you get started with our platform quickly and easily.\n\n## First Steps\n\n1. Create your account\n2. Set up your profile\n3. Explore the dashboard",
"keywords": "getting started, tutorial, guide, setup",
"lead": "Learn the essential steps to get started with our platform",
"format": "markdown",
"publishStatus": "published"
}
]
}
]
}Example 2: Multilingual Article with Features
Create a featured article with multiple languages:
{
"articles": [
{
"correlationId": "advanced-features-001",
"categoryCorrelationId": "advanced",
"isPrivate": false,
"isFeatured": true,
"featuredOrder": 1,
"order": 10,
"alternateSlugs": {
"en": ["advanced-guide", "pro-features"],
"es": ["funciones-avanzadas"]
},
"contents": [
{
"correlationId": "content-en-advanced",
"lang": "en",
"title": "Advanced Features Guide",
"slug": "advanced-features",
"content": "# Advanced Features\n\nExplore the powerful advanced features...",
"keywords": "advanced, features, pro, expert",
"lead": "Master the advanced capabilities of our platform",
"format": "markdown",
"publishStatus": "published"
},
{
"correlationId": "content-es-advanced",
"lang": "es",
"title": "Guía de Funciones Avanzadas",
"slug": "funciones-avanzadas",
"content": "# Funciones Avanzadas\n\nExplora las potentes funciones avanzadas...",
"keywords": "avanzado, funciones, pro, experto",
"lead": "Domina las capacidades avanzadas de nuestra plataforma",
"format": "markdown",
"publishStatus": "published"
}
]
}
]
}Example 3: Batch Import with Configuration
Import multiple articles with auto-numbering for slug conflicts:
{
"articles": [
{
"correlationId": "faq-001",
"categoryCorrelationId": "support",
"contents": [
{
"lang": "en",
"title": "Frequently Asked Questions",
"content": "# FAQ\n\n## How do I reset my password?\n\n...",
"format": "markdown",
"publishStatus": "published"
}
]
},
{
"correlationId": "troubleshooting-001",
"categoryCorrelationId": "support",
"contents": [
{
"lang": "en",
"title": "Troubleshooting Guide",
"content": "# Troubleshooting\n\n## Common Issues\n\n...",
"format": "markdown",
"publishStatus": "unpublished"
}
]
}
],
"config": {
"slugConflictHandling": "auto-number",
"ignoreImportErrors": true,
"includeContentInResponse": true
}
}Example 4: Update Existing Article
Update an existing article by providing its correlation ID:
{
"articles": [
{
"correlationId": "existing-article-001",
"isPrivate": false,
"isFeatured": true,
"contents": [
{
"correlationId": "existing-content-en",
"lang": "en",
"title": "Updated Title",
"content": "# Updated Content\n\nThis article has been updated with new information...",
"format": "markdown",
"createNewVersion": false,
"publishStatus": "published"
}
]
}
]
}Status Values
Article Status Values
created: New article was createdupdated: Existing article was updatederror: Article processing failed
Content Status Values
created: New content was createdupdated: Existing content was updatederror: Content processing failed
Rate Limits
- Maximum 50 articles per import request
- Maximum 20 content languages per article
- Maximum 10 requests per minute
- Maximum 1000 articles per hour
For larger imports, contact support for increased limits.
Additional Examples
Multilingual Article with Config (JSON)
Request Body:
{
"articles": [
{
"correlationId": "advanced-guide-001",
"categoryCorrelationId": "advanced",
"isFeatured": true,
"featuredOrder": 1,
"contents": [
{
"correlationId": "content-en-advanced",
"lang": "en",
"title": "Advanced Features Guide",
"content": "# Advanced Features\n\nExplore powerful advanced capabilities...",
"format": "markdown",
"publishStatus": "published"
},
{
"correlationId": "content-es-advanced",
"lang": "es",
"title": "Guía de Funciones Avanzadas",
"content": "# Funciones Avanzadas\n\nExplora las potentes funciones avanzadas...",
"format": "markdown",
"publishStatus": "published"
}
]
}
],
"config": {
"slugConflictHandling": "auto-number",
"ignoreImportErrors": false,
"includeContentInResponse": true
}
}Multilingual Article with Config (cURL)
curl -X POST "https://api.productfruits.com/v1/knowledgebase/import" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"articles": [
{
"correlationId": "advanced-guide-001",
"categoryCorrelationId": "advanced",
"isFeatured": true,
"featuredOrder": 1,
"contents": [
{
"correlationId": "content-en-advanced",
"lang": "en",
"title": "Advanced Features Guide",
"content": "# Advanced Features\\n\\nExplore powerful advanced capabilities...",
"format": "markdown",
"publishStatus": "published"
},
{
"correlationId": "content-es-advanced",
"lang": "es",
"title": "Guía de Funciones Avanzadas",
"content": "# Funciones Avanzadas\\n\\nExplora las potentes funciones avanzadas...",
"format": "markdown",
"publishStatus": "published"
}
]
}
],
"config": {
"slugConflictHandling": "auto-number",
"ignoreImportErrors": false,
"includeContentInResponse": true
}
}'Images and Media
Using Images in Articles
Images must be uploaded separately using the /upload-image endpoint before referencing them in article content.
Workflow for including images:
- Upload the image using
POST /upload-image - Get the image URL from the upload response
- Reference the image in your article content using markdown or HTML
Example workflow:
# Step 1: Upload image
curl -X POST "https://api.productfruits.com/v1/knowledgebase/upload-image" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "file=@screenshot.png"
# Response: { "imageId": "abc123", "imageUrl": "https://cdn-assets.productfruits.com/abc123" }// Step 2: Use image URL in article import
{
"articles": [{
"correlationId": "tutorial-001",
"contents": [{
"lang": "en",
"title": "Tutorial with Screenshots",
"content": "# Getting Started\n\n\n\nFollow these steps...",
"format": "markdown"
}]
}]
}Supported Image Formats
- JPG/JPEG: Best for photographs
- PNG: Best for screenshots, logos, images with transparency
- GIF: Supported for simple animations
- WebP: Modern format with excellent compression
Video Content
⚠️ Direct video uploads are not supported through the API.
Supported video embedding options:
- YouTube: Embed using YouTube URLs or iframe codes
- Vimeo: Embed using Vimeo URLs or iframe codes
- Loom: Embed using Loom URLs or iframe codes
Example video embedding:
# Tutorial Video
Watch this tutorial to get started:
[Watch on YouTube](https://www.youtube.com/watch?v=VIDEO_ID)
Or embed directly:
<iframe src="https://www.youtube.com/embed/VIDEO_ID" frameborder="0" allowfullscreen></iframe>Media Best Practices
- Upload images first: Always upload images via
/upload-imagebefore importing articles - Use descriptive alt text: Include meaningful alt attributes for accessibility
- Optimize file sizes: Compress images before upload (max 10MB per image)
- External video hosting: Use YouTube, Vimeo, or Loom for video content
- Test media links: Verify all media URLs are accessible before importing
Rate Limiting
Please see our guide for detailed information about API limits and optimization strategies.
Additional Examples
Basic Article Import (cURL)
curl -X POST "https://api.productfruits.com/v1/knowledgebase/import" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"articles": [
{
"correlationId": "getting-started-001",
"categoryCorrelationId": "tutorials",
"isPrivate": false,
"contents": [
{
"lang": "en",
"title": "Getting Started Guide",
"content": "# Welcome\\n\\nThis guide will help you get started with our platform quickly and easily.",
"keywords": "getting started, tutorial, guide",
"format": "markdown",
"publishStatus": "published"
}
]
}
]
}'