Skip to main content

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 pull downloads the workspace as a multidoc and splits it into individual .xs files on your filesystem.
  • xano workspace push reassembles your local .xs files into a multidoc and sends it to Xano.
  • The Metadata API exposes GET and POST endpoints at /workspace/{workspace_id}/multidoc for the same purpose — this is what the CLI calls under the hood.
This page is the complete reference for that format — written so an agent (or a human) working through the CLI or Metadata API knows exactly what a multidoc contains and how it’s applied, without needing any other context.
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)
The example above is trimmed for clarity. Below is a real, complete multidoc — the entire Loan Origination App workspace (3 tables, 2 API groups, and the full auth + loan flow) exported with 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 .xs files and run xano workspace push.
  • Apply it to an existing workspace (Metadata API) — send the multidoc to POST /workspace/{id}/multidoc.
Loan Origination App full workspace multidoc

Key rules

  • Each definition is separated by exactly --- on its own line
  • Every .xs file 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 --sync for a full push of every definition, and --sync --delete to 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:

Optional inclusions

A few additional data types can be included via flags: These are excluded by default since they contain runtime data rather than workspace definitions.

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 run xano workspace pull, the CLI:
  1. Calls GET /workspace/{workspace_id}/multidoc on the Metadata API
  2. Receives a single multidoc response
  3. Splits it on --- boundaries
  4. Writes each definition to its own .xs file, organized by type into the directory structure

Push: Files to multidoc

When you run xano workspace push, the CLI:
  1. Recursively collects all .xs files from the target directory
  2. Sorts them alphabetically by file path
  3. Joins them with --- separators into a single multidoc
  4. Sends it to POST /workspace/{workspace_id}/multidoc with content type text/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=true to 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.
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. Identity lives inside each document — there is no external mapping file, and the object’s file path is irrelevant to matching. Push the same definitions from a different folder layout and they still bind to the same objects.

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

Response: The selected branch as a text/x-xanoscript multidoc.

Push a multidoc

Request body: Content type 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.
Both endpoints require authentication via a Bearer token with appropriate workspace permissions. The same format powers several adjacent operations:

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 .xs files (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 .xs files 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.