What is a Multidoc?
A multidoc is a single XanoScript document that captures one branch of a workspace — every table, API, function, task, agent, and other construct — separated by--- (triple-dash) delimiters. Think of it as a snapshot of a workspace branch in one file: like a database dump, but for your backend logic and schema.
You don’t hand-author a multidoc — Xano generates it — but it’s the format you or your AI agents work with for version control, backups, and migrating or cloning a workspace. The CLI and Metadata API read and write it:
xano workspace pulldownloads the workspace as a multidoc and splits it into individual.xsfiles on your filesystem.xano workspace pushreassembles your local.xsfiles into a multidoc and sends it to Xano.- The Metadata API exposes
GETandPOSTendpoints at/workspace/{workspace_id}/multidocfor the same purpose — this is what the CLI calls under the hood.
A multidoc captures a single branch. Pulling exports the live branch by default — pass a
branch to target another. There is no “all branches” export, so back up each branch separately. By default a multidoc is published definitions only: table records, environment variables, and draft (unpublished) function versions are excluded unless you opt in (see Optional inclusions).Structure
A multidoc is a sequence of XanoScript definitions separated by---. Each section between separators is a standalone definition — a table, function, API endpoint, etc. — exactly as it would appear in its own .xs file. Here’s a minimal multidoc with three definitions:
A minimal multidoc (three definitions)
xano workspace pull.
You can load a multidoc like this into Xano in a few ways:
- Create a new workspace from it (dashboard) — on the Workspaces page, open the ⋮ menu and choose Create Workspace (Multi-Doc), then paste the multidoc (or click Upload File) and click Create.
- Apply it to an existing workspace (CLI) — assemble your
.xsfiles and runxano workspace push. - Apply it to an existing workspace (Metadata API) — send the multidoc to
POST /workspace/{id}/multidoc.
Full example: the Loan Origination App workspace as a single multidoc
Full example: the Loan Origination App workspace as a single multidoc
Loan Origination App full workspace multidoc
Key rules
- Each definition is separated by exactly
---on its own line - Every
.xsfile contributes one definition to the multidoc - Definitions can appear in any order, though the CLI sorts them alphabetically by file path when assembling a push
- The CLI’s default push is partial — only changed definitions are sent. Use
--syncfor a full push of every definition, and--sync --deleteto also remove remote objects that are no longer present locally - Each definition must be a valid, standalone XanoScript primitive
What’s Included
A multidoc can contain every type of XanoScript construct in your workspace. Here’s the full list:| Construct | Keyword | Description |
|---|---|---|
| Workspace Settings | workspace | Environment variables, preferences, and configuration |
| Branch Config | branch | Branch color, description, middleware, history retention |
| Database Tables | table | Schema definitions with fields, indexes, and views |
| API Groups | api_group | API group settings (canonical URL, swagger, tags) |
| API Endpoints | query | HTTP endpoints with inputs, logic stacks, and responses |
| Custom Functions | function | Reusable logic blocks |
| Background Tasks | task | Scheduled and cron jobs |
| Triggers | table_trigger, realtime_trigger, workspace_trigger, agent_trigger, mcp_server_trigger | Event-driven handlers |
| Middleware | middleware | Request/response interceptors |
| Addons | addon | Reusable subqueries for fetching related data |
| AI Agents | agent | AI agent configuration |
| AI Tools | tool | Tools for agents and MCP servers |
| MCP Servers | mcp_server | MCP server definitions |
| Tests | test (embedded) | Unit tests, defined inline within their parent construct |
Optional inclusions
A few additional data types can be included via flags:| Data | CLI Flag | API Parameter | Description |
|---|---|---|---|
| Environment variables | --env | env=true | Custom $env.* values defined in workspace settings |
| Table records | --records | records=true | Actual data rows stored in each table |
| Draft function versions | --draft (pull only) | include_draft=true | Unpublished draft versions of functions |
How the CLI Uses Multidoc
The CLI is the primary interface for working with multidoc. Understanding how it transforms between multidoc and individual files helps when troubleshooting push/pull issues.Pull: Multidoc to files
When you runxano workspace pull, the CLI:
- Calls
GET /workspace/{workspace_id}/multidocon the Metadata API - Receives a single multidoc response
- Splits it on
---boundaries - Writes each definition to its own
.xsfile, organized by type into the directory structure
Push: Files to multidoc
When you runxano workspace push, the CLI:
- Recursively collects all
.xsfiles from the target directory - Sorts them alphabetically by file path
- Joins them with
---separators into a single multidoc - Sends it to
POST /workspace/{workspace_id}/multidocwith content typetext/x-xanoscript
The order of definitions within the multidoc doesn’t matter to Xano — the server resolves dependencies regardless of order. The CLI sorts alphabetically for consistency and readable diffs.
Importing and overwrite behavior
Multidocs are how you (or an agent) back up, restore, clone, and migrate a workspace — so it matters where you send one and what it overwrites:- Import as a new workspace (dashboard) — on the Workspaces page, the ⋮ menu → Create Workspace (Multi-Doc) builds a brand-new workspace from the multidoc. Nothing is overwritten — the safest path for restoring a backup elsewhere, cloning, or migrating between instances.
- Push into an existing workspace — Xano matches each definition to existing objects by its
guid: matches are updated in place (overwritten) and new definitions are created. Objects already in the workspace but absent from the multidoc are left untouched — unless you use--sync --delete(delete=true), which removes them so the workspace matches the multidoc exactly. That delete is destructive. - Records are only written with
--records/records=true. By default rows are added on top of existing data (which can duplicate); add--truncate/truncate=trueto empty each table first so the import replaces it. - Pushes run inside a database transaction by default (
transaction=true), so a failed import rolls back instead of leaving the workspace half-applied.
| Goal | How |
|---|---|
| Restore or clone to a fresh workspace | Dashboard → Create Workspace (Multi-Doc) |
| Update an existing workspace, keep anything not in the doc | xano workspace push (default partial) |
| Make a workspace exactly match the multidoc | xano workspace push --sync --delete |
| Replace table data too | add --records --truncate |
Every definition carries a
guid (visible in the example above). That GUID is how Xano decides whether a push updates an existing object or creates a new one — which is why importing the same multidoc twice updates in place instead of duplicating.Metadata API Endpoints
The Metadata API provides direct access to the multidoc format for programmatic workflows, CI/CD pipelines, or custom tooling.Retrieve a multidoc
| Parameter | Type | In | Required | Default | Description |
|---|---|---|---|---|---|
workspace_id | integer | path | Yes | — | Workspace ID |
branch | string | query | No | Live branch | Branch to retrieve |
env | boolean | query | No | false | Include environment variables |
records | boolean | query | No | false | Include table records |
include_draft | boolean | query | No | false | Include draft (unpublished) versions of functions |
text/x-xanoscript multidoc.
Push a multidoc
| Parameter | Type | In | Required | Default | Description |
|---|---|---|---|---|---|
workspace_id | integer | path | Yes | — | Workspace ID |
branch | string | query | No | Live branch | Branch to push to |
partial | boolean | query | No | false | Apply only the supplied definitions instead of a full replace (the CLI’s default push mode) |
delete | boolean | query | No | false | Remove remote objects not present in the multidoc (full sync) |
env | boolean | query | No | false | Include environment variables |
records | boolean | query | No | false | Include table records |
truncate | boolean | query | No | false | Truncate tables before importing records |
as_draft | boolean | query | No | false | Import functions as draft versions instead of publishing |
transaction | boolean | query | No | true | Wrap the import in a database transaction |
force | boolean | query | No | false | Skip server-side safety checks (for CI/CD) |
text/x-xanoscript — the full multidoc as a string.
To preview a push without applying it, send the same request to
POST /workspace/{workspace_id}/multidoc/dry-run. This is what backs the CLI’s --dry-run flag.Related multidoc endpoints
The same format powers several adjacent operations:| Endpoint | Purpose |
|---|---|
GET / POST /sandbox/multidoc | Export / import the sandbox tenant |
POST /workspace/{workspace_id}/release/multidoc | Create a release from a multidoc |
GET /workspace/{workspace_id}/release/{release_id}/multidoc | Export an existing release as a multidoc |
GET /workspace/{workspace_id}/tenant/{tenant_name}/multidoc | Export a specific tenant’s workspace |
When you’ll work with multidoc
Whether you’re an AI agent operating through the CLI/Metadata API or a human reviewing a diff, multidoc is the format under the hood:- Version control — A pulled workspace is a tree of
.xsfiles (one definition each) that reassemble into a multidoc on push, so changes diff and review like any other code. - Backup & restore — Export a branch to a multidoc, then re-import it as a new workspace or push it back to restore. See Importing and overwrite behavior.
- Migration & cloning — Move a workspace between branches or instances by exporting one multidoc and importing it elsewhere.
- CI/CD pipelines — Automated deployments send and receive multidoc payloads directly against the Metadata API.
- Debugging push failures — Knowing the CLI assembles your
.xsfiles into one multidoc helps you isolate which definition broke a push. - Custom tooling — If you’re building tools that interact with Xano programmatically, the multidoc endpoints are the transport layer for reading and writing workspace definitions.