Convert Spaces
The space convert commands export an entire Confluence space — all its pages — to a directory of Markdown files. The page hierarchy is automatically preserved as nested subdirectories.
This is the main operational workflow for acs2md and the core reason most teams license the product.
If you are planning a real customer run, see Workflows & Recipes for continuity, archive, migration, governance, and AI-corpus patterns built around space convert.
Convert by key
acs2md space convert by-key SPACE_KEY [flags]The space key is the short identifier visible in the Confluence URL: .../wiki/spaces/MYSPACE/. It is also shown in the output of acs2md space list.
Examples
# Convert to the default output directory
acs2md space convert by-key MYSPACE
# Convert to a specific directory
acs2md space convert by-key MYSPACE --output-dir ./docs
# Build a RAG knowledge base — plain text, no images
acs2md space convert by-key MYSPACE \
--exclude-marks=true \
--embed-images=false \
--output-dir ./rag-knowledge-base
# Include only currently published pages
acs2md space convert by-key MYSPACE --status current --output-dir ./docs
# Disable internal link rewriting
acs2md space convert by-key MYSPACE --rewrite-links=false --output-dir ./site
# Incremental sync — only re-convert changed pages, keep deleted files
acs2md space convert by-key MYSPACE --incremental --output-dir ./docs
# Full sync — re-convert changed pages, delete files for removed pages
acs2md space convert by-key MYSPACE --sync --output-dir ./docsFlags
| Flag | Short | Default | Description |
|---|---|---|---|
--output-dir | -o | ./output/<SPACE_KEY>/ | Directory to write Markdown files into |
--status | -s | current | Filter pages by status: current, archived, trashed, deleted, draft |
--conflict-resolution | overwrite | How to handle filename conflicts: overwrite, suffix, skip, versioned | |
--rewrite-links | true | Rewrite internal Confluence URLs to local relative paths | |
--sync | false | Track .convert-sync-state.json and only re-convert changed pages. Deletes local files for pages removed from Confluence. Mutually exclusive with --incremental. | |
--incremental | true | Like --sync, but keeps local files for removed pages. Mutually exclusive with --sync. |
Convert by ID
acs2md space convert by-id SPACE_ID [flags]Converts a space identified by its numeric ID instead of its key. Same flags as by-key.
acs2md space convert by-id 65539 --output-dir ./docsConversion flags
These flags are available on both by-key and by-id and control how each page is rendered.
Content & metadata
| Flag | Short | Default | Description |
|---|---|---|---|
--include-metadata | -m | true | Add a YAML front matter block to each file (title, author, created/modified dates) |
--exclude-marks | -x | true | Strip all inline formatting: bold, italic, underline, colours. Set --exclude-marks=false if you want to preserve rich inline formatting. |
Images & media
| Flag | Short | Default | Description |
|---|---|---|---|
--embed-images | -e | true | Embed images as base64 data URIs |
--ext-embed-drawio | -D | true | Embed draw.io diagrams as base64 images |
--ext-embed-roadmap | true | Embed Roadmap Planner diagrams as base64 images | |
--embed-media-images | true | Embed Confluence media files (images, avatars) as base64 data URIs |
Pass --embed-images=false to keep image references as external URLs. This
produces smaller output files but requires network access to view them.
Extension flags
| Flag | Default | Description |
|---|---|---|
--ext-render-toc | true | Generate a Markdown table of contents from document headings |
--ext-render-recently-updated | true | Render the recently-updated macro as a Markdown list |
--ext-render-listlabels | true | Render label badges |
--ext-render-pagetree | true | Render the pagetree macro as a nested Markdown list |
--ext-render-children | true | Render the children macro as a flat Markdown list |
--ext-render-contributors | true | Render the contributors macro as a Markdown list |
--ext-render-page-signatures | true | Render Document Control signature tables |
--ext-render-qc-properties | true | Render QC property and revision macros with their actual values |
--ext-render-task-report | true | Render tasks-report-macro as a Markdown table |
--ext-render-content-report | true | Render content-report-table macro as a Markdown table |
--ext-resolve-inline-card-titles | true | Resolve inline card links to their actual page titles |
Progress reporting
Long-running conversions display a real-time progress bar on stderr showing the current page title, completion percentage, and estimated time remaining. This does not interfere with stdout output that may be piped to a file.
That separation matters for automation because it keeps progress visibility for humans without corrupting redirected output.
If you need a clean transcript for CI logs, demos, or docs capture, use the global --no-progress flag.
Observed conversion run (sanitized)
The following output was captured from a live macOS run against a small current space, with the space name and key anonymized:
📚 Converting space: Team Documentation (TEAMDOCS)
📂 Output directory: /tmp/acs2md-doc-sample
🔄 Mode: incremental — state file: /tmp/acs2md-doc-sample/.convert-sync-state.json
🔍 Fetching page metadata for sync...
📥 Fetched metadata for 6 pages ✅
📋 Found 6 page(s) to convert (0 up-to-date)
✅ Sync complete!
✅ Converted: 6
❌ Failed: 0
✅ Up-to-date (skipped): 0
🗑️ Removed from tracking: 0
🔗 Links rewritten: 1 files
📂 Output: /tmp/acs2md-doc-sampleRunning the same command again against the existing output directory produced:
📚 Converting space: Team Documentation (TEAMDOCS)
📂 Output directory: /tmp/acs2md-doc-sample
🔄 Mode: incremental — state file: /tmp/acs2md-doc-sample/.convert-sync-state.json
🔍 Fetching page metadata for sync...
📥 Fetched metadata for 6 pages ✅
✅ All pages are up-to-date.
✅ Sync complete!
✅ Up-to-date (skipped): 6
🗑️ Removed from tracking: 0
📂 Output: /tmp/acs2md-doc-sampleSpace plus page workflows
acs2md also includes page-level commands so teams can combine bulk export with targeted inspection from the same binary.
acs2md page convert by-id,by-title,by-urlacs2md page get by-id,by-title,by-urlacs2md page count nodes,page count marks, andpage properties
Output structure
acs2md creates subdirectories that mirror the Confluence page tree. Each page becomes a Markdown file, and child pages are placed inside a folder named after their parent.
./output/TEAMDOCS/
├── .convert-sync-state.json
├── Team_Documentation.md
└── Team_Documentation/
├── Architecture_decisions.md
├── Change_log.md
├── Meeting_notes.md
├── Product_requirements.md
└── Retrospectives.mdFile names are derived from page titles, with conflicts resolved using the --conflict-resolution strategy.
The root Markdown file and the child folder sharing the same page title are not theoretical; that layout came directly from a live export.
Output conflict resolution
When two pages in the space produce the same file name, --conflict-resolution controls the behaviour:
| Value | Behaviour |
|---|---|
overwrite | Overwrite any existing file (default) |
suffix | Append the page ID to disambiguate duplicate file names |
skip | Leave the existing file and skip the duplicate |
versioned | Create a timestamped output directory for each run |
Sync and incremental mode
On the current live release tested for this documentation, acs2md space convert by-key defaults to incremental mode when neither --incremental nor --sync is passed. The tool creates a .convert-sync-state.json file inside the output directory and only re-converts pages that have changed since the last run.
| Flag | Behaviour |
|---|---|
--sync | Re-convert changed pages. Deletes local files for pages that were removed from Confluence. |
--incremental | Re-convert changed pages. Keeps local files for pages that were removed from Confluence. This is the observed default behaviour on v1.0.0. |
The two flags are mutually exclusive.
Sync and incremental modes are ideal for CI/CD pipelines and scheduled exports. On subsequent runs, only pages with new versions are fetched and converted, significantly reducing API calls and processing time.
Sample state file
The state file created by the live export looked like this after anonymization:
{
"last_sync_at": "2026-03-29T10:55:33.744109+02:00",
"pages": {
"100101": {
"converted_at": "2026-03-29T10:55:31.313290+02:00",
"version_created_at": "2024-01-15T09:00:00.000Z",
"page_id": "100101",
"title": "Team Documentation",
"file_path": "/tmp/acs2md-doc-sample/Team_Documentation.md",
"version_number": 3
}
},
"space_id": "100001",
"version": 1
}Recommended usage patterns
- Use
--syncwhen the output directory should remain an exact live mirror of the source space. - Use
--incrementalwhen you want a continuity or archive-style copy that keeps deleted content locally. - Use
--rewrite-links=falseonly when local portability is not required. - Run
space pages --treebefore the first large export if you need to verify scope with stakeholders.
Practical examples
Full space migration for a static site
acs2md space convert by-key DOCS \
--include-metadata \
--output-dir ./site/docsAI knowledge base (plain text, no images)
acs2md space convert by-key KB \
--exclude-marks \
--embed-images=false \
--ext-render-toc=false \
--output-dir ./ragNightly backup via CI/CD
#!/bin/bash
export ACS2MD_CONFLUENCE_DOMAIN=mycompany.atlassian.net
export ACS2MD_CONFLUENCE_USERNAME=$CONFLUENCE_USER
export ACS2MD_CONFLUENCE_API_TOKEN=$CONFLUENCE_TOKEN
acs2md space convert by-key DOCS \
--output-dir "./backup/$(date +%Y-%m-%d)" \
--log-file acs2md.logIncremental sync in CI/CD
# Only re-convert changed pages, keep files for removed pages
acs2md space convert by-key DOCS \
--incremental \
--output-dir ./docs
# Only re-convert changed pages, delete files for removed pages
acs2md space convert by-key DOCS \
--sync \
--output-dir ./docsArchive-oriented export that keeps removed pages
acs2md space convert by-key DOCS \
--incremental \
--output-dir ./archive/docsExport without link rewriting
# Keep original Confluence URLs instead of rewriting to local paths
acs2md space convert by-key MYSPACE \
--rewrite-links=false \
--output-dir ./exportFor scenario-driven guidance instead of single commands, continue with Workflows & Recipes.