Skip to content

LiveAgent to Desk365 Knowledge Base Migration: Technical Guide

Technical guide for migrating your knowledge base from LiveAgent to Desk365 — covering API extraction, hierarchy mapping, image re-hosting, and SEO redirects.

Raaj Raaj · · 19 min read
LiveAgent to Desk365 Knowledge Base Migration: Technical Guide
TALK TO AN ENGINEER

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

LiveAgent to Desk365 Knowledge Base Migration: Technical Guide

Info

TL;DR: LiveAgent → Desk365 Knowledge Base Migration

LiveAgent has no built-in KB export — you must extract articles via the LiveAgent API (v1 GET /knowledgebase/entries or v3 KB endpoints). Desk365's API v3 exposes KB Categories, Folders, and Articles endpoints for programmatic creation. The core structural challenge: LiveAgent uses a Category → Article model with nested sub-categories, while Desk365 enforces a three-level Category → Folder → Article hierarchy. Non-article LiveAgent content (forums, feedback boards, suggestions) has no equivalent in Desk365. LiveAgent's API is capped at 180 requests/minute; Desk365 rate limits are plan-based — as low as 100 calls/hour on Standard. Budget 1–3 weeks depending on article volume, attachment count, and multi-KB complexity.

Quick links:

API behaviors verified against LiveAgent API v1/v3 docs and Desk365 API v3 docs. Validate all endpoint availability against your account tier before running production scripts.

Migrating a knowledge base from LiveAgent to Desk365 is not a copy-paste job. LiveAgent operates as a standalone multi-channel platform with a customer portal model — articles, forums, feedback boards, suggestion categories, and an optional multi-knowledgebase plugin. Desk365 is a Microsoft 365-native helpdesk with a structured KB built around a Category → Folder → Article hierarchy, deep Teams integration, and granular visibility controls.

If you're making this move, you're likely consolidating support into your existing Microsoft infrastructure or replacing LiveAgent's KB with Desk365's tighter integration between tickets and knowledge content. Either way, this is an API-led migration. LiveAgent has no built-in KB export, and the two platforms' data models don't align cleanly enough for a simple dump-and-load.

This guide covers the full extraction, transformation, and loading process — including the structural mismatches, image re-hosting, pagination handling, retry logic, and SEO preservation steps that catch most teams off guard.

LiveAgent and Desk365 Use Different KB Models

LiveAgent KB Data Model

LiveAgent's KB is part of its Customer Portal feature and includes:

  • Categories — support nested sub-categories (categories containing other categories)
  • Articles — HTML content via WYSIWYG editor, with internal (agent-only) and public visibility
  • Forums — community discussion threads
  • Feedback boards — customer feature requests and suggestions
  • Multi-Knowledgebase — optional plugin allowing separate portals with unique domains, designs, and content
Warning

No native export exists. LiveAgent confirms there is "no direct export or download option available within the LiveAgent Knowledgebase interface." You must use the API to retrieve articles programmatically. (support.liveagent.com)

LiveAgent exposes KB operations across two API versions:

  • API v1 (deprecated): Includes GET /knowledgebase/entries for retrieving all articles, returning up to 500 results per call with page and per_page parameters for pagination. Deprecated — no new endpoints will be added — but existing endpoints remain functional.
  • API v3 (active): Under active development. The following KB-relevant endpoints are confirmed in v3: GET /v3/kb/categories, GET /v3/kb/articles. However, several KB entry types (forums, suggestions, feedback) are only retrievable via v1 endpoints. Plan to use both versions during extraction.

The rate limit is 180 requests per minute per API key for cloud accounts. Standalone installations can override this. (support.liveagent.com)

Desk365 KB Data Model

Desk365's KB follows a strict three-level hierarchy:

Level Object Key Attributes
1 Category category_name, category_description, support_portal_visibility (1–4), agent_portal_visibility (1–2), category_order
2 Folder folder_name, category_name, parent_category_name
3 Article article_title, article_content (HTML), status (0=Draft, 1=Published), category_name, folder_name, visibility, attachments

Visibility controls are more granular than LiveAgent's binary internal/public model:

  • Support portal visibility: 1 = Not visible, 2 = Visible to all visitors, 3 = Signed-in users only, 4 = Signed-in users from specific companies
  • Agent portal visibility: 1 = All agents, 2 = Only agents in creator's group(s)

Desk365 allows unlimited KB articles on all paid plans. The API v3 exposes dedicated endpoints for KB Categories (POST /apis/v3/kb/categories), KB Folders (POST /apis/v3/kb/folders), and KB Articles (POST /apis/v3/kb/articles).

Desk365 authentication: All API v3 requests require an Authorization header containing your API key as a plain token — not Bearer, not Basic. The correct format is:

Authorization: YOUR_DESK365_API_KEY

This is a custom header scheme. Requests using Bearer YOUR_KEY or Basic base64(key) will return 401. Retrieve your key from Desk365 Settings → API.

Danger

Desk365 API rate limits are plan-dependent and tight on lower tiers:

  • Standard: 100 API calls per hour
  • Plus: 50 API calls per minute
  • Premium: 50 API calls per minute

Loading 500 articles with attachments on Standard takes a minimum of 5 hours for article creation alone — not counting category/folder creation or attachment uploads. Upgrade to Plus or Premium before running a migration script, or throttle aggressively.

When you exceed the limit, Desk365 returns HTTP 429 with a Retry-After header specifying seconds to wait. Your migration script must handle this explicitly — a silent failure here causes partial loads that are difficult to detect without per-article validation.

Duplicate article handling: If you POST an article with a title identical to an existing Desk365 article in the same folder, Desk365 creates a second article rather than returning an error. This means a failed-and-retried migration run can double your article count silently. Maintain a local record of successfully created article IDs and check against it before each POST.

What Does Not Map 1:1

LiveAgent Element Desk365 Equivalent Migration Decision
Nested sub-categories (3+ levels) No equivalent — max depth is Category → Folder Flatten to two levels; encode deeper path in folder name or article breadcrumb
Forums None Archive, convert high-value threads to articles, or move to Discourse/Canny
Feedback boards None Same options as forums
Suggestion categories None Archive or move to a dedicated feedback tool
Per-article keywords, metadescription Not exposed in Desk365 API Manual QA item; embed keywords in article body
Mixed visibility within one category Categories and folders inherit a single visibility level Must split into separate Desk365 categories by visibility level
article_views, article_likes, article_dislikes Tracked in Desk365 but cannot be seeded via API Analytics reset to zero; export separately if content strategy depends on engagement data

The Folder Problem

This is the most common friction point. LiveAgent stores articles directly under categories (with optional sub-categories). Desk365 requires articles to live inside folders, which live inside categories. You cannot skip the folder level — a POST to /apis/v3/kb/articles without a valid folder_name returns a validation error.

Your options:

  1. Default folder per category. Create a single folder matching the category name inside each Desk365 category. Fast, but you lose the opportunity to restructure.
  2. Content-based restructuring. Audit articles before migration and group them into logical folders. More work upfront, but a cleaner Desk365 KB from day one.
  3. Hybrid. Default folders for small categories (<10 articles), restructured folders for large ones.

For deeper LiveAgent hierarchies, convert root categories to Desk365 categories and second-level sub-categories to folders. For third-level or deeper branches, flatten into the folder name or preserve the breadcrumb in the article body or title:

  • Product A > Billing > Invoices > EU VAT in LiveAgent becomes Category: Billing, Folder: Invoices, Article title: "EU VAT – Invoice FAQ"

For most teams with 200+ articles, option 2 or 3 pays for itself in reduced maintenance later.

Field Mapping: LiveAgent → Desk365

LiveAgent Field Desk365 Field Notes
Category Category Direct map for top-level. Nested sub-categories become folders.
(none) Folder LiveAgent has no folder concept. Create folders per your strategy above.
Article title article_title Direct map.
Article body (HTML) article_content HTML transfer. Inline image URLs must be rewritten before load.
Internal / Public support_portal_visibility + agent_portal_visibility Internal → visibility 1 (not visible to support portal) + agent visibility 1. Public → visibility 2.
Multi-KB portal (kb_id) Multi-brand KB Map each LiveAgent portal to a Desk365 brand. One-to-one is easiest to QA.
Forums (no equivalent) Archive, convert selectively to articles, or migrate to a dedicated tool.
Feedback boards (no equivalent) Same options as forums.
Tags / keywords (limited) Desk365 relies on category/folder structure and search. Embed important keywords in article content.
Attachments Attachments Must download from LiveAgent and re-upload to Desk365. Inline images need URL rewriting.
article_views, article_likes (resets to zero) No API to seed historical engagement data. Export separately if relevant to content decisions.

Step-by-Step Migration Process

Step 1: Audit Your LiveAgent KB

Before writing any code, inventory what you have:

  • Total article count (public + internal), broken down by entry type
  • Number of categories, sub-categories, and multi-KB portals
  • Forum topics and feedback board entries (these won't migrate to Desk365)
  • Articles with inline images or file attachments (estimate image count and total file size — a KB with 2,000 inline images across 300 articles can require 10–50 GB of local staging storage depending on image resolution)
  • Articles with custom CSS or JavaScript embeds
  • Deepest category nesting level

Use the LiveAgent API to pull a complete article list. The v1 endpoint returns up to 500 results per page — you must paginate explicitly:

# First page
curl -X GET "https://yourdomain.ladesk.com/api/v1/knowledgebase/entries?page=1&per_page=500" \
  -H "apikey: YOUR_API_KEY"
 
# Second page
curl -X GET "https://yourdomain.ladesk.com/api/v1/knowledgebase/entries?page=2&per_page=500" \
  -H "apikey: YOUR_API_KEY"

A single GET without pagination parameters returns the first 500 results and silently drops the rest. Any KB with 501+ entries will appear complete when it isn't — this is the most common data loss bug in DIY extractions.

Save results locally as JSON. Store source IDs, parent IDs, entry types (A = article, F = forum, S = suggestion, T = topic), status, access flags, and date_changed values. The date_changed field makes delta sync practical near cutover — replay only articles modified after the initial extraction to keep any authoring freeze short.

Step 2: Extract Articles, Categories, and Attachments

For each article, extract:

  • Title and HTML body
  • Category assignment and parent hierarchy
  • Internal/public visibility flag
  • Attached files and inline image URLs
  • Locale/language identifier (field: lang_id in v1 responses)

Download all attachments and images locally. Inline images hosted on LiveAgent's servers (*.ladesk.com) will return 404 after you cancel your LiveAgent subscription.

Storage estimate before you start: Count your total attachment and inline image references, then multiply by average file size. A migration with 500 articles averaging 4 inline images each at 200 KB per image requires approximately 400 MB of local staging storage — manageable. A media-heavy KB with 3,000 articles and 10 images each at 1 MB each requires 30 GB. Provision accordingly before extraction begins.

import requests
import json
import time
import os
 
API_KEY = "your_liveagent_api_key"
BASE_URL = "https://yourdomain.ladesk.com/api/v1"
HEADERS = {"apikey": API_KEY}
 
def get_all_kb_entries():
    entries = []
    page = 1
    per_page = 500
 
    while True:
        response = requests.get(
            f"{BASE_URL}/knowledgebase/entries",
            headers=HEADERS,
            params={"page": page, "per_page": per_page}
        )
        response.raise_for_status()
        data = response.json()
        batch = data.get("entries", [])
 
        if not batch:
            break
 
        entries.extend(batch)
        print(f"Page {page}: retrieved {len(batch)} entries (total so far: {len(entries)})")
 
        if len(batch) < per_page:
            break  # Last page
 
        page += 1
        time.sleep(0.35)  # Stay safely under 180 req/min
 
    return entries
 
def download_attachment(url, save_path, api_key):
    resp = requests.get(url, headers={"apikey": api_key}, stream=True)
    resp.raise_for_status()
    os.makedirs(os.path.dirname(save_path), exist_ok=True)
    with open(save_path, "wb") as f:
        for chunk in resp.iter_content(chunk_size=8192):
            f.write(chunk)
 
entries = get_all_kb_entries()
with open("liveagent_kb_export.json", "w") as f:
    json.dump(entries, f, indent=2)
 
print(f"Total entries extracted: {len(entries)}")

Build a staging layer between extraction and loading. Don't transform directly from a LiveAgent API response into a Desk365 create call. A staging record separates source facts from target decisions and gives you a clean rollback point:

source_kb_id: kb_defa
source_entry_id: 288
source_type: A
source_path: Product A > Billing > Invoices
source_lang_id: en
target_brand: Product A
target_category: Billing
target_folder: Invoices
target_status: draft
target_visibility: signed_in_users
redirect_from: /288-vat-invoice-faq
desk365_article_id: null   # Populated after successful POST; prevents duplicate creation on retry

The desk365_article_id field is critical. Before each article POST, check whether this field is already populated in your staging record. If it is, skip the create call. This prevents the silent duplicate-creation problem described above.

Step 3: Design the Desk365 Category and Folder Structure

Before loading anything, map out your target structure:

Desk365 Category: "Getting Started"  [support_portal_visibility: 2]
  └── Folder: "Account Setup"
      ├── Article: "How to create your account"
      └── Article: "Configuring your profile"
  └── Folder: "Billing"
      ├── Article: "Payment methods"
      └── Article: "Invoice FAQ"

Desk365 Category: "Internal Ops"  [support_portal_visibility: 1]
  └── Folder: "Escalation Procedures"
      └── Article: "Tier 2 Escalation Guide"   [previously "internal" in LiveAgent]

If your LiveAgent account uses multiple knowledgebases, decide whether each kb_id becomes a separate Desk365 brand or whether you're consolidating. One-to-one mapping is easier to QA and redirect.

Visibility split planning is mandatory at this stage. Identify every LiveAgent category that contains a mix of public and internal articles. Each such category must become two separate Desk365 categories — one with support_portal_visibility: 2 for public content, one with support_portal_visibility: 1 for internal. Discovering this mid-load causes internal documentation to be briefly exposed on the public portal, which has happened in migrations where this step was skipped.

Step 4: Create Categories and Folders via Desk365 API

Create categories first, then folders — the Desk365 API requires parent objects to exist before children can reference them. Set visibility rules before loading any articles so private content never lands under a public branch.

# Create a category
curl -X POST "https://yoursubdomain.desk365.io/apis/v3/kb/categories" \
  -H "Authorization: YOUR_DESK365_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "category_name": "Getting Started",
    "category_description": "Onboarding and setup guides",
    "support_portal_visibility": 2,
    "agent_portal_visibility": 1
  }'
 
# Create a folder within that category
curl -X POST "https://yoursubdomain.desk365.io/apis/v3/kb/folders" \
  -H "Authorization: YOUR_DESK365_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "folder_name": "Account Setup",
    "category_name": "Getting Started"
  }'
Warning

Visibility inheritance is not obvious. Desk365 folders inherit their parent category's visibility setting. There is no folder-level visibility override. A category set to support_portal_visibility: 2 (all visitors) will expose every article in every folder under it — including any internal articles you load before setting visibility correctly. Create the category structure with correct visibility codes before loading a single article.

Step 5: Transform, Re-host Images, and Load Articles

This is where most custom migration scripts fail. Article HTML from LiveAgent contains image tags pointing to LiveAgent's servers:

<img src="https://yourdomain.ladesk.com/scripts/file.php?id=12345">

Push this HTML unchanged into Desk365 and images display fine — until you cancel LiveAgent. Then every image returns 404.

Image processing workflow:

  1. Parse the HTML. Use a DOM parser (BeautifulSoup in Python, Cheerio in Node.js) to find all <img> tags.
  2. Download the binary. Make an authenticated GET request to LiveAgent. Pass your API key in the apikey header — some images require authentication.
  3. Upload to target. Upload to Desk365's attachment endpoint or a CDN you control. Azure Blob Storage is a natural fit if you're already in the Microsoft ecosystem.
  4. Rewrite the HTML. Replace the old src URL with the new URL in the article body.
  5. Load the article. Only after rewriting should you push to Desk365.

For each article, also:

  • Strip LiveAgent-specific CSS classes and markup
  • Check for <script> tags — Desk365's HTML sanitizer strips them; articles relying on inline JavaScript need manual rewrites
  • Check for <iframe> embeds (YouTube, Vimeo, Wistia) — validate these are preserved after load, as iframe allowlists vary by Desk365 configuration
  • Map the internal/public flag to Desk365's numeric visibility codes
  • Assign the correct category_name and folder_name from your staging mapping

Load articles as Draft (status: 0) for review. The following script includes exponential backoff on 429 responses — hardcoded time.sleep() values are insufficient because Desk365's 429 includes a Retry-After header that specifies the actual wait time:

import requests
import time
import json
 
DESK365_API_KEY = "your_desk365_api_key"
DESK365_BASE = "https://yoursubdomain.desk365.io/apis/v3"
HEADERS = {
    "Authorization": DESK365_API_KEY,
    "Content-Type": "application/json"
}
 
def create_article_with_retry(article_data, max_retries=5):
    """
    POST an article to Desk365 with exponential backoff on 429.
    Returns the created article's ID on success, raises on persistent failure.
    """
    for attempt in range(max_retries):
        response = requests.post(
            f"{DESK365_BASE}/kb/articles",
            headers=HEADERS,
            json=article_data
        )
 
        if response.status_code == 201:
            return response.json()
 
        elif response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 60))
            print(f"Rate limited. Waiting {retry_after}s (attempt {attempt + 1}/{max_retries})")
            time.sleep(retry_after)
 
        elif response.status_code == 422:
            # Validation error — log and skip, don't retry
            print(f"Validation error for article '{article_data.get('article_title')}': {response.text}")
            return None
 
        else:
            wait = (2 ** attempt) * 5
            print(f"HTTP {response.status_code}. Retrying in {wait}s...")
            time.sleep(wait)
 
    raise Exception(f"Failed to create article after {max_retries} attempts: {article_data.get('article_title')}")
 
 
def load_staging_records(path="staging.json"):
    with open(path) as f:
        return json.load(f)
 
def save_staging_records(records, path="staging.json"):
    with open(path, "w") as f:
        json.dump(records, f, indent=2)
 
 
staging = load_staging_records()
 
for record in staging:
    # Skip already-created articles to prevent duplicates on retry runs
    if record.get("desk365_article_id"):
        print(f"Skipping already-created: {record['target_title']}")
        continue
 
    article_payload = {
        "article_title": record["target_title"],
        "article_content": record["transformed_html"],
        "category_name": record["target_category"],
        "folder_name": record["target_folder"],
        "status": 0  # Draft
    }
 
    result = create_article_with_retry(article_payload)
 
    if result:
        record["desk365_article_id"] = result.get("id") or result.get("article_id")
        save_staging_records(staging)  # Persist after each success
        print(f"Created: {record['target_title']} → ID {record['desk365_article_id']}")
 
    # Base throttle between successful calls (Standard: 100/hr ≈ 36s apart)
    time.sleep(1.5)
Warning

Standard plan users: 100 API calls/hour means loading 500 articles takes a minimum of 5 hours for article creation alone. Factor this into your timeline or upgrade before migrating.

Article HTML often contains hyperlinks to other LiveAgent articles:

<a href="https://support.yourcompany.com/Knowledgebase/Article/View/50">Billing FAQ</a>

If you don't update these, users clicking them in Desk365 hit dead pages.

Fix programmatically:

  1. During migration, maintain a URL mapping table: {old_liveagent_url: new_desk365_url}. Populate it as each article is created in Desk365.
  2. After loading all articles, run a second pass over Desk365 articles via GET /apis/v3/kb/articles and then PATCH /apis/v3/kb/articles/{id}.
  3. Parse each article's HTML for href attributes matching your old LiveAgent domain pattern.
  4. Look up each old URL in your mapping table, replace with the new Desk365 URL, and update the article via PATCH.
  5. Log any old URLs with no mapping entry — these require manual resolution.

Step 7: Handle Multi-Language Articles

If you used LiveAgent's translation features, each article variant carries a lang_id field in the v1 API response (e.g., en, de, fr). Extract each language variant as a separate record during Step 2.

Desk365's localization support depends on your plan tier — verify whether your Desk365 plan exposes multi-language article creation via the API before assuming a direct mapping. If localization isn't available on your tier, you have two options: create language-specific folders (e.g., "Account Setup – DE") or consolidate multi-language content into English-only articles and handle localization post-migration.

Step 8: Validate and Publish

After loading articles as drafts:

  1. Spot-check rendering. Open 10–20% of articles in the Desk365 support portal preview. Look for broken formatting, missing images, and mangled tables.
  2. Verify visibility. Confirm internal articles aren't publicly visible. Test both agent portal URLs and support portal URLs — Desk365 exposes separate share URLs for each. A visibility misconfiguration here exposed internal documentation to the public portal in at least one migration we observed where the visibility-split step was deferred to post-load.
  3. Check folder structure. Verify no articles landed in the wrong folder. Cross-reference your staging records against the Desk365 article list via GET /apis/v3/kb/articles.
  4. Test search. Run key queries against the Desk365 support portal search. Verify articles surface for expected terms.
  5. Confirm no duplicates. Check article counts per folder against expected counts from your staging records.
  6. Publish in batches. Flip articles from Draft to Published via PATCH or through the Desk365 agent portal. Publish internal categories first to avoid any gap where agents need the content but it isn't live.

Step 9: SEO Redirects and Sitemap

If your LiveAgent KB is public, it's indexed by search engines and bookmarked by customers. Changing platforms changes your URL structure entirely.

LiveAgent article URLs use auto-generated numerical IDs that cannot be customized. Desk365 URLs follow a different routing pattern with no documented mechanism to preserve source URLs. (support.liveagent.com)

Redirect implementation:

Neither platform handles external 301 redirects out of the box. Handle this at your DNS/CDN layer (Cloudflare, AWS CloudFront, Azure Front Door):

  1. Export your final URL mapping (old LiveAgent URL → new Desk365 URL) from your staging records.
  2. Format the list as redirect rules (Cloudflare Bulk Redirect List, Nginx rewrite directives, etc.).
  3. Apply rules at your edge so old URLs issue 301 Permanent Redirects before the request reaches either helpdesk.
  4. Submit an updated sitemap to Google Search Console and monitor crawl coverage of new URLs.

Google's site move guidance is clear: build a one-to-one old→new URL map, enable permanent redirects, update internal links, submit updated sitemaps, and monitor the new URLs in Search Console.

Edge Cases and Failure Modes

Mixed-visibility categories (highest risk). A source LiveAgent category containing both public and internal articles that isn't split before loading will expose internal documentation on the support portal. This is not a hypothetical — in migrations where the visibility split is deferred to "after we confirm the structure looks right," the window between article creation and visibility correction has resulted in internal escalation procedures and agent notes being visible to end users. Split before you load anything.

Duplicate articles on retry. Desk365's article POST creates a new record rather than returning a conflict error when the same title exists in the same folder. A failed migration run retried without checking existing state will double your article count. The staging layer with desk365_article_id tracking in Step 2 prevents this.

Multi-Knowledgebase migration. Each LiveAgent portal (kb_id) maps to a separate Desk365 multi-brand KB. Run extraction and loading once per portal, targeting the correct brand. Cross-portal article references need manual resolution.

Video embeds. Articles containing YouTube, Vimeo, or Wistia iframes may have iframes stripped by Desk365's HTML sanitizer. Test with one embedded article in your Desk365 sandbox before assuming iframes are preserved at scale.

Custom CSS and scripts. LiveAgent allows extensive custom CSS and inline JavaScript. Desk365 strips <script> tags. Complex table layouts referencing portal-specific CSS classes will lose their styling. Identify these articles during audit and flag for manual reconstruction.

Multi-language articles. The lang_id field in LiveAgent v1 API responses carries the locale identifier. Extract each language variant as a separate record. Verify Desk365 localization API support on your tier before planning a multi-language automated load.

HTML compatibility. LiveAgent's and Desk365's WYSIWYG editors produce different markup. Custom CSS classes referencing portal-specific styles won't exist in Desk365. Test code blocks, tables, and nested list formatting after the first batch load.

Attachment upload validation. Desk365's public API exposes a has_attachments field on article records, but the dedicated bulk KB attachment upload endpoint is not fully documented as of this writing. Validate attachment upload behavior in a Desk365 sandbox environment on your actual plan tier before committing to a fully automated attachment migration.

Forums and feedback boards. Don't force forum content into KB articles wholesale — the format doesn't translate well and will clutter your Desk365 KB. Archive, selectively convert high-value threads, or migrate community content to a dedicated tool (Discourse, Canny, Productboard).

API Error Reference

HTTP Status Platform Meaning Action
429 Desk365 Rate limit exceeded Read Retry-After header; wait specified seconds before retry
422 Desk365 Validation error (missing required field, invalid visibility code, etc.) Log the response body; fix the payload; do not retry automatically
401 Desk365 Invalid or missing API key Verify Authorization header format (not Bearer, not Basic)
404 Desk365 Category or folder referenced in article POST does not exist Create parent objects first; check for typos in category_name/folder_name
429 LiveAgent 180 req/min exceeded Back off for 60 seconds; add time.sleep(0.35) between all extraction calls
500 Either Server error Log response body; retry with exponential backoff (max 5 attempts)

What You Lose in This Migration

Be explicit with stakeholders before committing:

  • Forums and feedback boards — no Desk365 equivalent; requires a separate tool or archival decision
  • Historical view/like/dislike counts — reset to zero; no API endpoint to seed historical engagement data
  • Custom portal CSS/themes — must be recreated in Desk365's portal designer from scratch
  • Per-article SEO metadata — LiveAgent's keywords and metadescription fields don't map to Desk365; must be re-entered manually or embedded in article body
  • Suggestion categories — no direct Desk365 equivalent
  • LiveAgent-specific widget embeds — must be replaced with Desk365's web widget
  • Article-level URL control — LiveAgent numerical IDs cannot be mapped to Desk365 URLs; only 301 redirects at the CDN/DNS layer bridge the gap

DIY vs. Managed Migration

DIY is viable when:

  • Fewer than 200 articles
  • No multi-KB portals
  • Minimal inline images or attachments
  • An engineer can dedicate 20–40 hours over 1–2 weeks
  • You're on Desk365 Plus or Premium (50 calls/min allows reasonable throughput)

A managed migration makes more sense when:

  • 500+ articles across multiple portals
  • Heavy attachment and inline image usage requiring significant local staging storage
  • Content restructuring needed during migration
  • Standard plan with 100 API calls/hour constraint makes timeline impractical
  • Zero-downtime requirement with delta sync capability
  • Your team lacks engineering bandwidth for a multi-week extraction, transform, and load project

Timeline Estimates

Scenario Article Count Estimated Time
Small, simple KB <100 articles, no attachments 3–5 days
Mid-size KB 100–500 articles, some attachments 1–2 weeks
Large multi-portal KB 500+ articles, multi-KB, heavy media 2–4 weeks

These assume a single engineer working part-time. A managed service running parallel workstreams can compress the large scenario to 1–2 weeks.

After the Migration

Once articles are published, complete these steps to restore full functionality:

  1. Configure the support portal. Set your custom domain, branding, and access controls in Desk365 Settings.
  2. Enable KB search in Teams. Desk365 lets agents search and insert KB articles directly from Microsoft Teams — activate this under Integrations if your team works in Teams.
  3. Confirm 301 redirects are active. If your LiveAgent KB was on a custom domain, verify redirect rules are live and returning HTTP 301 (not 302) for all mapped URLs.
  4. Update internal references. Any links to your KB from product docs, onboarding emails, or internal wikis need the new Desk365 URLs.
  5. Monitor article feedback. Desk365 includes built-in article rating (useful/not useful). Track these signals in the first 30 days to catch content gaps created by the structural flattening.
  6. Run a crawl. Use a tool like Screaming Frog or Sitebulb to crawl your new Desk365 KB and verify no internal links still point to your old LiveAgent domain.

Frequently Asked Questions

Can I export my LiveAgent knowledge base to a file?
No. LiveAgent has no built-in KB export or CSV download. You must use the LiveAgent API (v1 GET /knowledgebase/entries or v3 KB endpoints) to programmatically extract articles, categories, and content. The API rate limit is 180 requests per minute per API key.
Does Desk365 have an API for importing knowledge base articles?
Yes. Desk365 API v3 exposes endpoints for KB Categories, KB Folders, and KB Articles. You can create all three programmatically. Rate limits depend on your plan: 100 calls/hour on Standard, 50 calls/minute on Plus and Premium.
How do I migrate inline images from LiveAgent to Desk365?
Use a DOM parser to locate img tags in the article HTML, download the image files from LiveAgent's servers, upload them to Desk365 or a CDN you control (like Azure Blob Storage), and rewrite the HTML src URLs before importing. Skipping this step means every image breaks when you cancel LiveAgent.
What happens to LiveAgent forums and feedback boards during migration?
Desk365 has no forum or feedback board feature. These cannot be migrated directly. You can archive them, convert high-value threads into KB articles, or migrate community content to a dedicated tool like Discourse or Canny.
How long does a LiveAgent to Desk365 KB migration take?
A small KB (under 100 articles, no attachments) takes 3–5 days. Mid-size migrations (100–500 articles) take 1–2 weeks. Large multi-portal KBs with 500+ articles and heavy media take 2–4 weeks. These estimates assume a single engineer working part-time.

More from our Blog

Enchant to Desk365 Migration: A Technical Guide
Enchant/Migration Guide/Help Desk

Enchant to Desk365 Migration: A Technical Guide

Technical guide for migrating from Enchant to Desk365. Covers API constraints, object mapping, label-to-category conversion, rate limits, and dependency order.

Raaj Raaj · · 20 min read