---
title: "Confluence to GitBook Migration: The CTO's Technical Guide"
slug: confluence-to-gitbook-migration-the-ctos-technical-guide
date: 2026-05-19
author: Raaj
categories: [Confluence, Migration Guide, GitBook]
excerpt: "A CTO-level technical guide covering Confluence to GitBook migration: XML storage format conversion, API limits, macro mapping, and the three viable approaches."
tldr: "GitBook's native importer caps at 20 pages. Real Confluence migrations need XML-to-Markdown conversion, Git Sync, link rewriting, and staged QA — or a managed service."
canonical: https://clonepartner.com/blog/confluence-to-gitbook-migration-the-ctos-technical-guide/
---

# Confluence to GitBook Migration: The CTO's Technical Guide


**There is no one-click migration path from Confluence to GitBook that preserves macros, attachments, and internal links at scale.** GitBook's built-in import panel accepts Confluence content, but it caps at 20 pages and 20 files per import — and it cannot parse Confluence's proprietary XML storage format into clean Markdown without significant data loss on anything beyond basic text. For any workspace with more than a handful of pages, you need a custom pipeline or a managed service. ([gitbook.com](https://gitbook.com/docs/getting-started/import))

This guide covers the real technical constraints on both sides, the viable migration approaches and the failure modes of each, the exact API limits you will hit, and the data mapping decisions that determine whether your docs survive the move intact.

If you are evaluating whether GitBook is the right target for your Confluence content, see our [Confluence alternatives comparison](https://clonepartner.com/blog/blog/confluence-alternatives-2026-platforms-limits-migration/). If you have already made the decision and need to get your data out of Confluence cleanly, start with our [Confluence export guide](https://clonepartner.com/blog/blog/how-to-export-all-data-from-confluence-methods-limits-tools/).

## Why Engineering Teams Move from Confluence to GitBook

The migration driver is almost never "Confluence is broken." It is that Confluence stopped fitting how your team works. The triggers we see most often:

- **Docs-as-code adoption.** Engineering teams want documentation to live in Git, flow through pull requests, and ship alongside code. GitBook's native Git Sync makes this the default workflow. Confluence's storage format makes round-trips between Confluence and Git essentially impossible without serious engineering pain.
- **Simpler public-facing docs.** Confluence was built as an internal wiki. Publishing external developer docs from Confluence requires fighting the platform's defaults. GitBook is purpose-built for published technical documentation with custom domains, branded sites, and clean URL structures.
- **Cost at scale.** Confluence Cloud pricing compounds with user count. GitBook's per-site + per-user model can be cheaper for small, focused documentation teams — though it scales in two dimensions, so model the math for your team size.
- **Atlassian Data Center EOL pressure.** Teams on Confluence Data Center are facing the [2029 end-of-life timeline](https://clonepartner.com/blog/blog/atlassian-data-center-end-of-life-2029-guide/), which forces a platform decision regardless.

> [!NOTE]
> **GitBook's sweet spot:** External-facing developer docs, API references, and product guides. If your primary use case is broad internal knowledge management with deep Jira integration, GitBook may not be the right target. See our [Notion vs. Confluence comparison](https://clonepartner.com/blog/blog/notion-vs-confluence-2026/) for alternative paths.

## The Core Technical Challenge: XML Storage Format vs. Markdown

This is the single most important thing to understand before planning your migration. **Confluence does not store content as HTML or Markdown. It stores content in a proprietary XHTML-based format that Atlassian calls "Storage Format."**

The storage format is technically XML, not XHTML, because it includes custom elements for macros and other Confluence-specific features. Standard elements like `<p>` and `<table>` are interspersed with Confluence-specific elements like `<ac:structured-macro>`, `<ac:parameter>`, and `<ac:rich-text-body>`. ([confluence.atlassian.com](https://confluence.atlassian.com/doc/confluence-storage-format-790796544.html))

Here is what a simple code block looks like in Confluence storage format:

```xml
<ac:structured-macro ac:name="code" ac:schema-version="1">
  <ac:parameter ac:name="language">python</ac:parameter>
  <ac:plain-text-body>
    <![CDATA[print("hello world")]]>
  </ac:plain-text-body>
</ac:structured-macro>
```

In GitBook, the equivalent is a standard Markdown fenced code block:

````markdown
```python
print("hello world")
```
````

This translation is straightforward for a code block. It is not straightforward for:

- **Layout macros** (`ac:layout-section`, `ac:layout-cell`) — GitBook has no multi-column layout equivalent
- **Expand/collapse macros** — must map to GitBook's expandable blocks
- **Jira issue macros** — no GitBook equivalent; these become dead references or plain text links to the issue URL
- **Table of contents macros** — GitBook generates TOCs automatically; the macro must be stripped
- **Draw.io / Gliffy diagrams** — embedded as macro attachments; must be exported as images and re-embedded
- **User mentions** (`<ac:link><ri:user>`) — no equivalent; become plain text
- **Page includes** — GitBook has reusable content blocks, but the mapping is not 1:1

> [!WARNING]
> **The macro problem is the migration.** If your Confluence instance uses only basic text, headings, lists, tables, and images, the conversion is manageable. If your pages are macro-heavy — and most enterprise Confluence instances are — every macro type requires a custom conversion rule or a conscious decision to drop the content.

GitBook's built-in import tool uses AI by default to clean up mismatched content. That can produce nicer pages for simple content, but it makes before-and-after QA less deterministic. If fidelity matters more than convenience, turn AI cleanup off and own the conversion rules yourself. GitBook warns that imported content can differ from the original because the products do not share the same feature set. ([gitbook.com](https://gitbook.com/docs/getting-started/import))

Bidirectional sync between Confluence and GitBook is not practical. The format mismatch between Confluence's XML storage format and Markdown makes clean round-trips impossible. Plan for a one-way cutover, not an ongoing sync. ([community.atlassian.com](https://community.atlassian.com/forums/Confluence-questions/What-options-to-store-confluence-pages-in-Github/qaq-p/2442970))

## Migration Approaches: Native Import, Git Sync Pipeline, and Managed Services

### Approach 1: GitBook's Built-In Import Panel

**How it works:** GitBook's import tool accepts content from Confluence by URL or by uploading HTML/Markdown files. You paste your published Confluence page URL, and GitBook's scraper pulls the rendered content and converts it into GitBook blocks. ([gitbook.com](https://gitbook.com/docs/getting-started/import))

**When to use it:** Small spaces with fewer than 20 pages of simple content. Proof-of-concept migrations. Quick one-off page imports.

**Hard limits:**

- Maximum 20 pages per import
- Maximum 20 files (images, attachments) per import
- URL-based import scrapes the *rendered* page, not the storage format — macro output is captured, but macro structure is lost
- No attachment migration beyond inline images
- No preservation of page hierarchy or internal cross-links between pages

**Verdict:** Good for kicking the tires. Not a real migration path for any workspace with depth.

### Approach 2: Confluence Export → Markdown Conversion → Git Sync

This is the most viable DIY approach for medium-to-large migrations. It works in three stages.

**Stage 1: Export from Confluence**

You have two extraction options:

- **Space HTML export** — Confluence generates a ZIP of rendered HTML files. Comments are excluded from HTML exports. Blog posts are excluded from PDF/HTML space-level exports in Confluence Cloud. ([support.atlassian.com](https://support.atlassian.com/confluence-cloud/docs/export-content-to-word-pdf-html-and-xml/))
- **REST API extraction** — Fetch page content via the Confluence REST API, which returns the raw storage format XML. This gives you more control but requires handling pagination.

For the API path, the Confluence REST API v2 uses cursor-based pagination with `limit` and `cursor` parameters. The v1 API uses offset-based pagination with `start` and `limit`. Do not mix pagination strategies across API versions — using offset parameters against v2 endpoints will silently produce incomplete result sets. ([developer.atlassian.com](https://developer.atlassian.com/cloud/confluence/rest/v2/intro/))

```python
import requests

BASE_URL = "https://your-domain.atlassian.net/wiki/api/v2"
HEADERS = {"Authorization": "Basic <base64_email:api_token>"}

def fetch_all_pages(space_id):
    pages = []
    url = f"{BASE_URL}/spaces/{space_id}/pages?limit=50&body-format=storage"
    while url:
        resp = requests.get(url, headers=HEADERS)
        resp.raise_for_status()
        data = resp.json()
        pages.extend(data.get("results", []))
        next_link = data.get("_links", {}).get("next")
        url = f"https://your-domain.atlassian.net{next_link}" if next_link else None
    return pages
```

**Stage 2: Convert Storage Format to Markdown**

This is the hard part. You need a custom parser that:

1. Strips Confluence-specific XML elements (`ac:structured-macro`, `ac:parameter`, etc.)
2. Maps standard XHTML elements to Markdown equivalents
3. Converts supported macros to GitBook-compatible blocks
4. Downloads and re-links attachments and images
5. Rewrites internal page links to relative Markdown paths
6. Generates a `SUMMARY.md` file that mirrors your page hierarchy (GitBook uses this to build its table of contents)

Open-source tools like Pandoc can handle basic HTML-to-Markdown conversion, but they choke on Confluence's custom XML elements. You will need to pre-process the storage format before feeding it to any converter. Community tools like `confluence-markdown-exporter` can export single pages, descendants, or entire spaces to Markdown via the Atlassian API, but macro coverage and attachment handling still need testing. ([github.com](https://github.com/Spenhouet/confluence-markdown-exporter))

**Stage 3: Push to Git → Sync to GitBook**

Once your Markdown files are in a Git repository with the correct folder structure and a `SUMMARY.md`, configure GitBook's Git Sync integration:

1. Install the GitBook app on your GitHub or GitLab account
2. Create a space in GitBook
3. Set up Git Sync with the direction **GitHub → GitBook**
4. GitBook ingests the Markdown and builds the space

Git Sync is bi-directional after initial setup — changes in GitBook push back to the repo, and commits to the repo sync to GitBook.

**Pros:**
- Full control over conversion logic
- Handles large volumes (no 20-page cap)
- Results in a Git-backed docs workflow from day one
- Repeatable — you can iterate on conversion quality before going live

**Cons:**
- Requires significant engineering effort to build the converter
- Every macro type needs a custom rule
- Attachment handling adds complexity (download, re-host, re-link)
- Internal link rewriting is error-prone at scale

### Approach 3: Managed Migration Service

**How it works:** A migration service like ClonePartner handles the full pipeline — extraction from Confluence (API or export), custom conversion logic, attachment migration, link rewriting, hierarchy mapping, and validation — delivering clean Markdown into your Git repo or directly into GitBook.

**When to use it:** Enterprise Confluence instances with hundreds or thousands of pages, heavy macro usage, complex page hierarchies, or tight timelines where tying up engineering bandwidth on a one-time migration is not justifiable.

**Pros:**
- No engineering time spent building throwaway conversion scripts
- Macro-specific conversion rules already built from prior migrations
- Attachment and image re-hosting handled
- Validation and QA included
- Zero-downtime cutover possible with staged sync

**Cons:**
- External cost
- Requires sharing access credentials (mitigated by scoped API tokens)

### Approach Comparison Table

| Factor | GitBook Import Panel | Export → Git Sync Pipeline | Managed Service |
|---|---|---|---|
| **Max pages** | 20 per import | Unlimited | Unlimited |
| **Macro handling** | Scrapes rendered output | Custom rules required | Pre-built rules |
| **Attachments** | Inline images only | Manual download/re-link | Handled |
| **Internal links** | Broken | Manual rewrite | Handled |
| **Page hierarchy** | Flat | SUMMARY.md generation | Preserved |
| **Engineering effort** | None | 40–120+ hours | None |
| **Complexity** | Low | High | Low |
| **Best for** | < 20 pages, simple content | Mid-size, eng-heavy teams | Enterprise, macro-heavy |

For a **small team** moving a lightweight knowledge base, start with the native GitBook importer and fall back to an exporter plus Git Sync if the 20-page cap gets in the way. For an **enterprise** docs program, go straight to API extraction or a managed service with Git Sync and a redirect plan.

## Navigating Confluence and GitBook API Limits

If you build a custom migration pipeline, you must architect around the constraints of both platforms.

### Confluence API Constraints

The Confluence Cloud REST API v2 uses cursor-based pagination. Each response returns a `_links.next` URL with an opaque cursor. The maximum `limit` parameter is typically 250, but Atlassian can throttle lower under load.

Key pitfalls:

- **CQL result truncation.** When using CQL for search-based extraction with `expand=body.storage.value`, Confluence may return fewer results than requested — and the response does not clearly indicate the truncation. Always verify your result counts against the known page total.
- **v1 expansion caps.** The v1 API has lower limits when expanding heavy fields like `body.export_view` or `body.styled_view`. These endpoints were designed for rendering, not bulk extraction.
- **Attachment downloads.** Binary attachment downloads still go through v1 endpoints, even if you use v2 for page content.
- **Rate limiting.** Treat `429` responses as normal, not exceptional. Your extractor should implement backoff from the start.

### GitBook API Constraints

GitBook enforces rate limits per method type. When exceeded, the API returns HTTP 429 with the following headers:

- `X-RateLimit-Limit` — maximum requests in the current window
- `X-RateLimit-Remaining` — requests remaining
- `X-RateLimit-Reset` — UTC epoch seconds when the window resets

GitBook API authentication uses personal access tokens with Bearer auth. Paginated responses use a `page` token. ([gitbook.com](https://gitbook.com/docs/developers/gitbook-api/authentication))

Your migration script must implement exponential backoff:

```python
import time
import requests

def gitbook_request(url, headers, payload, max_retries=5):
    for attempt in range(max_retries):
        resp = requests.post(url, headers=headers, json=payload)
        if resp.status_code == 429:
            reset_time = int(resp.headers.get("X-RateLimit-Reset", time.time() + 60))
            wait = max(reset_time - int(time.time()), 1) + (2 ** attempt)
            time.sleep(wait)
            continue
        resp.raise_for_status()
        return resp.json()
    raise Exception("Rate limit exceeded after max retries")
```

> [!CAUTION]
> **Do not ignore 429s.** Sustained abuse of any API will eventually get your token revoked. Build the backoff into your scripts from the start. Pushing data blindly into GitBook will result in dropped pages and a corrupted documentation hierarchy.

## Data Mapping: Translating Spaces, Pages, and Macros

### Structural Mapping

| Confluence Concept | GitBook Equivalent | Notes |
|---|---|---|
| Space | Space | 1:1 mapping. Each Confluence space becomes a GitBook space. |
| Space home page | First page in the space TOC | GitBook treats the first page as the landing page. |
| Page tree (nested pages) | Pages with hierarchy | Defined by folder structure + `SUMMARY.md`. |
| Blog posts | Pages (flat) | GitBook has no blog concept. Blog posts become regular pages. |
| Page labels | — | No equivalent. Use folder organization instead. |
| Comments | — | Not migrated. GitBook has comment threads, but no import path. |
| Attachments | Files in Git repo | Must be downloaded, placed in repo, and re-linked. |
| Space permissions | Space member roles | Coarser model. Map carefully. |
| Page restrictions | — | GitBook permissions are at space level, not page level. |
| Collections (space groups) | Collections | Conceptual equivalent exists. |

> [!WARNING]
> **Deep nesting limits:** Confluence allows virtually infinite page nesting. GitBook supports nesting, but overly deep hierarchies create a poor user experience in GitBook's sidebar. Plan to flatten your architecture during the transformation phase — keep nesting to three levels or fewer where possible. ([gitbook.com](https://gitbook.com/docs/creating-content/content-structure/page))

### Macro Mapping Reference

| Confluence Macro | GitBook Block | Migration Strategy |
|---|---|---|
| `code` | Fenced code block | Direct conversion. Preserve language attribute. |
| `info` / `note` / `warning` / `tip` | Hint block | Map `ac:name` to hint type. |
| `toc` | (Auto-generated) | Strip entirely. GitBook generates TOC. |
| `expand` | Expandable block | Convert body content. |
| `panel` | Hint block | Approximate. Panel styling lost. |
| `jira` | Plain text link | No live Jira integration. Link to issue URL. |
| `excerpt` | — | Strip macro wrapper, keep inner content. |
| `children` / `pagetree` | (Auto-generated) | GitBook shows child pages automatically. |
| `drawio` | Embedded image | Export diagram as PNG/SVG, embed as image. |
| `gliffy` | Embedded image | Same as drawio. |
| `include` (page include) | Reusable content | Requires manual setup of reusable blocks. |
| `gallery` | Image blocks | Flatten to sequential images. |
| `status` | Inline text with emoji | Approximate mapping. |

### Handling Attachments and Internal Links

**Attachments** require a three-step process:

1. **Extract:** Download the attachment via the Confluence API (v1 endpoints for binary downloads).
2. **Host:** Upload the attachment to your Git repository or a dedicated S3 bucket. Git Sync goes through GitHub/GitLab, which has its own file size limits — 100 MB per file on GitHub. Large PDFs or binaries need external hosting. ([gitbook.com](https://gitbook.com/docs/help-center/integrations/integrations-troubleshooting/git-sync/git-sync-file-size-limitations))
3. **Rewrite:** Parse the Confluence page content, locate `<ri:attachment>` tags, and replace them with standard Markdown image links `! [alt](new-url)`.

**Internal links** require a state map. Build a lookup table mapping every Confluence Page ID to its new GitBook URL path *before* starting conversion. During the transformation phase, the script scans page content for Confluence link tags (`<ri:page ri:content-title="Page Name" />`), looks up the target page in the state map, and injects the correct relative URL.

**Redirects** from old Confluence URLs to new GitBook paths require separate handling. GitBook supports site redirects, but manual redirects are a Premium or Ultimate feature, and CSV redirect imports are capped at 500 rows per batch. GitBook creates automatic redirects when pages are moved or renamed inside GitBook, but that does not replace a deliberate Confluence-to-GitBook redirect map. ([gitbook.com](https://gitbook.com/docs/publishing-documentation/site-redirects))

## Step-by-Step Migration Process

### 1. Audit Your Confluence Instance

Before writing any code:

- **Count pages per space.** Use the API: `GET /wiki/api/v2/spaces/{id}/pages?limit=1` and check the total.
- **Inventory macros.** Query using CQL or the API to identify which macros are used and how frequently. This determines your conversion scope.
- **Identify orphan pages.** Pages not linked from the page tree that may be missed in a hierarchical crawl.
- **Catalog attachments.** Total size determines whether inline download or bulk export is more practical. Flag files over 100 MB for external hosting.
- **Build the link map.** Create a lookup table of `pageId → new Markdown path` before starting conversion.
- **Identify obsolete content.** Do not migrate legacy documentation that has not been viewed in two years.

### 2. Extract Content

Use the Confluence REST API v2 to fetch all pages with storage format bodies. Paginate using cursor-based links. For each page, also fetch:

- Child pages (to rebuild hierarchy)
- Attachments (via v1 API)
- Labels (for any manual categorization you want to preserve)

### 3. Convert Storage Format to Markdown

For each page:

1. Parse the storage format XML
2. Walk the DOM tree, converting standard HTML elements to Markdown
3. Handle each `ac:structured-macro` by name, applying the macro mapping table above
4. Download attachments and images to a local directory
5. Rewrite image `src` attributes to relative paths
6. Rewrite internal page links using your `pageId → path` lookup
7. Write the resulting Markdown to the correct file path

### 4. Generate SUMMARY.md and Organize Files

GitBook uses `SUMMARY.md` to define the table of contents. If this file is missing, GitBook infers structure from the folder hierarchy — but explicit definition is more reliable. Files not listed in `SUMMARY.md` will not show up in the imported table of contents. ([gitbook.com](https://gitbook.com/docs/getting-started/git-sync/troubleshooting))

```markdown
# Summary

* [Getting Started](getting-started/README.md)
  * [Installation](getting-started/installation.md)
  * [Configuration](getting-started/configuration.md)
* [API Reference](api/README.md)
  * [Authentication](api/authentication.md)
  * [Endpoints](api/endpoints.md)
```

Organize Markdown files into folders matching the target navigation structure.

### 5. Push to Git and Configure GitBook Sync

Commit all Markdown files, `SUMMARY.md`, and assets to your GitHub or GitLab repository. In GitBook, set up Git Sync with the **GitHub → GitBook** direction. GitBook ingests everything on the first sync.

> [!NOTE]
> **Git Sync gotcha:** If Git Sync is enabled, manage `README.md` in the repository, not in the GitBook UI, or you can create duplicate readmes and rendering conflicts. ([gitbook.com](https://gitbook.com/docs/getting-started/git-sync/troubleshooting))

### 6. Validate

- **Page count:** Compare the number of pages in Confluence vs. pages in GitBook.
- **Spot-check macros:** Review 10–15 pages that were macro-heavy in Confluence. Verify the conversion rendered correctly.
- **Internal links:** Click through cross-references. Broken links show up in GitBook's sidebar as warnings.
- **Images and attachments:** Verify all images render. Missing images appear as broken Markdown image references.
- **Table integrity:** Complex merged-cell tables from Confluence may not convert cleanly to Markdown tables.
- **Redirect map:** Verify the top-traffic URLs against the redirect map before launch.
- **Run UAT with content owners.** The people who wrote the docs should verify accuracy.

## Edge Cases That Will Break Your Migration

**Nested tables.** Markdown does not support nested tables. Confluence pages with tables inside tables need to be restructured manually or flattened.

**Multi-column layouts.** Confluence's `ac:layout-section` elements have no Markdown equivalent. Content from columns must be linearized (stacked vertically), which changes the reading experience.

**Inline comments.** Confluence inline comments are not part of the storage format body — they are stored separately. They will not appear in any export and cannot be migrated to GitBook.

**Page-level permissions.** Confluence supports per-page view restrictions. GitBook permissions are space-level only. If you have restricted pages in a shared space, you need to restructure into separate GitBook spaces.

**Large attachments.** GitBook's Git Sync goes through GitHub/GitLab, which enforces a 100 MB per file limit. Large PDFs or binaries need external hosting and a manual link.

**Drafts and unpublished pages.** Confluence exports only published content by default. Draft pages are not included in space exports and are not accessible via the standard REST API without specific status filters.

**Slug churn.** GitBook changes page slugs when titles change unless you set slugs manually. Old links can drift during QA if authors keep renaming pages during the migration window. Freeze title changes near cutover. ([gitbook.com](https://gitbook.com/docs/creating-content/content-structure/page))

**Hidden content.** Standard Confluence exports only include content visible to the exporting user. Ensure you extract with an account that has visibility into all spaces and pages. ([support.atlassian.com](https://support.atlassian.com/confluence-cloud/docs/export-content-to-word-pdf-html-and-xml/))

**Comments and calendars.** HTML export omits page comments, and space exports do not include Team Calendars data.

## Constraints to Accept Before You Start

- **GitBook has no equivalent of Confluence's macro ecosystem.** Any migration from a macro-heavy Confluence instance involves permanent information loss unless you redesign those pages for GitBook's block model.
- **Bidirectional sync is not practical.** Plan for a one-way cutover, not an ongoing sync.
- **Page version history does not migrate.** GitBook tracks versions through Git commits, but you will not carry over Confluence's page version history. Your first commit is your starting point.
- **Blog posts become regular pages.** GitBook has no blog or news feed concept. Structure accordingly.
- **API rate limits slow large migrations.** With GitBook's rate limiting and Confluence's own throttling, a 5,000-page migration takes hours of API time even with efficient batching.

## Pre-Migration and Post-Migration Checklist

### Before You Start

- [ ] Full Confluence space export (XML) as backup — keep it immutable
- [ ] Macro audit — list every macro type and frequency
- [ ] Internal link inventory — build `pageId → target path` map
- [ ] Attachment size audit — flag files over 100 MB
- [ ] Define which spaces migrate and which stay or are archived
- [ ] Define fallback strategy for macros GitBook does not support
- [ ] Determine if you are migrating page history (revisions) or just the current published state (we recommend current state; archive Confluence for history)
- [ ] Set up a GitBook sandbox space for test imports
- [ ] Run a test migration on one small, complex space end-to-end
- [ ] Review converted pages with content owners for accuracy

### After Cutover

- [ ] Verify all pages are present and accessible
- [ ] Validate internal links (sample 10% minimum)
- [ ] Confirm images and diagrams render correctly
- [ ] Set up redirects from old Confluence URLs if pages were publicly indexed
- [ ] Connect GitBook to your GitHub/GitLab repositories to enable the docs-as-code workflow
- [ ] Rebuild user groups and access controls in GitBook
- [ ] Remove or archive the Confluence space to prevent stale content drift
- [ ] Brief the team on GitBook's editor, Git Sync workflow, and change requests
- [ ] Monitor search analytics in GitBook for 404s and missing content signals
- [ ] Keep Confluence available as the rollback source until sign-off

For a deeper go-live checklist, use our [knowledge base migration checklist](https://clonepartner.com/blog/blog/the-ultimate-knowledge-base-migration-checklist-a-zero-downtime-plan/).

## When to Use a Managed Service

The temptation is to build a quick Python script and "just do it." Here is when that math does not work:

- **Your instance has 500+ pages across multiple spaces.** The long tail of macro conversion rules alone will consume weeks of engineering time.
- **You have tight timelines.** A managed service has already solved the conversion edge cases. Your team has not.
- **Your engineering team's time is better spent on product.** A migration script is throwaway code. Every hour your engineers spend on it is an hour not spent on features your customers pay for.
- **You need zero downtime.** A staged migration with incremental sync while your team continues writing in Confluence requires orchestration that is hard to get right on the first attempt.
- **Your docs are public-facing.** Broken links, missing images, and formatting errors are visible to your users and damage credibility.

At **ClonePartner**, we have run 1,500+ data migrations — including Confluence moves that involved thousands of pages, complex macro conversion, and full attachment preservation. We handle the pagination, rate limits, macro translation, link rewriting, and validation so your engineering team does not write code they will throw away the week after go-live.

Do not pull your core engineers off product development to write single-use XML parsers.

> Planning a Confluence to GitBook migration? Let our engineers handle the storage format conversion, attachment re-hosting, and internal link rewriting — while your team stays focused on shipping product.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### Can I import Confluence pages directly into GitBook?

Yes, but with hard limits. GitBook's built-in import panel supports Confluence by URL or file upload, but it caps at 20 pages and 20 files per import. It scrapes the rendered page, not the storage format, so macro structure is lost. For larger migrations, GitBook recommends using Git Sync with a repository of pre-converted Markdown files.

### What happens to Confluence macros when migrating to GitBook?

Confluence macros use a proprietary XML format (ac:structured-macro) that has no direct Markdown equivalent. Simple macros like code blocks and info panels map to GitBook blocks. Complex macros like Jira issue embeds, Draw.io diagrams, and multi-column layouts either require manual conversion, approximation as images or plain text, or are lost entirely. Each macro type needs a custom conversion rule.

### What are the GitBook API rate limits for migration scripts?

GitBook's API returns HTTP 429 when rate limits are exceeded, with X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. Migration scripts must implement exponential backoff. Sustained rate limit violations risk token revocation.

### Can I keep Confluence and GitBook in sync during migration?

Bidirectional sync between Confluence and GitBook is not practical. Confluence's XML storage format and GitBook's Markdown are fundamentally incompatible for clean round-trips. The reliable approach is a one-way cutover: extract from Confluence, convert, import into GitBook, run a final delta sync, then decommission the Confluence space.

### How long does a Confluence to GitBook migration take?

A small space (under 50 pages, minimal macros) can be migrated in a day using the Git Sync pipeline. Enterprise instances with 500+ pages, heavy macro usage, and complex hierarchies typically take 1–2 weeks including conversion script development, testing, and validation — or 2–5 days with a managed migration service.
