Introduction
Agility CMS is flexible by design. Your content is decoupled from your presentation layer, so you can manage authoring workflow and code deployment as two independent concerns. This guide explains how to set up CMS environments, website deployments, and content workflows that match the size and complexity of your team.
Two short framing sections before the workflow guidance. The first clarifies what an Agility instance actually is and clears up the most common multi-site confusion we hear from prospects. The second explains why content environments do not need to mirror DevOps environments, which is the most common source of overengineering we see in customer architectures.
An Agility instance is a fully isolated CMS environment with its own content, models, users, API keys, sitemaps, channels, and configuration. Each instance has a unique GUID. When you buy Agility, you buy capacity in instances.
Customers typically arrive with two questions tangled together:
These are different questions with different answers, and untangling them is the first job of this guide.
One instance can serve many web properties. A single Agility instance can power multiple websites, mobile apps, kiosks, in-product help, and other digital surfaces. Properties share content models and content where it makes sense, and use sitemaps and channels to give each property its own page structure, navigation, and routing. Most multi-site customers do this in one instance. See Using Agility CMS for Multiple Sites for the patterns.
There are real cases where separate instances per property are the right answer. Multi-tenant solutions where each customer needs a walled-off content surface. Distinct brands inside a holding company with no shared editorial team or governance. Recently-acquired properties being migrated separately. Brand-specific compliance requirements. These are exceptions and you will know if you are one of them.
The number of instances is a separate decision from the number of properties. That decision is about environments (sandbox, UAT, prod), not about how many sites or apps you are delivering. The rest of this guide answers that second question. Most customers need one instance.
Content is not a database that gets mirrored across environments. It is a publishing pipeline with editorial states. A single CMS instance with a strong workflow is the right answer for marketing, even when their developer counterparts run a multi-environment DevOps pipeline for the website that consumes that content.
Developers come from a world where DEV, UAT, and PROD are mirrored. Schema migrates upward. Fixture data lives in lower environments. They project that pattern onto content. The projection is wrong, because the editorial team is the user of the CMS, and editors do not want three of them. They want one source of truth with a workflow on top.
Editorial workflow already handles the gating that DevOps environments solve for code:
All of this lives in a single Agility instance. You do not need to add CMS environments to get these states. You already have them.
What does mirror your DevOps environments is your website code. Your local, dev-test, QA, UAT, and production website builds all point at the same Agility instance. Each deployment can serve content in two modes: preview (returning Staging/Draft, Awaiting Approval, Approved, and Published items) and live (returning Published items only). Local development typically runs preview-only because that is what developers need. Every other deployment registered in Web Studio supports both modes. Editors copy the preview URL for any registered deployment when they want to validate unpublished content, including on production itself. End users see the live URL of production by default. That is the integration point, and it is sufficient for almost every customer.
Agility CMS Instance
One workflow · all editors
All editorial states live here. Every deployment reads from this single instance.
Local
Developer laptop. Iterating on rendering code.
Developer choice. Not registered in Web Studio.
Dev-Test
Hosted build for engineers and integration tests.
Both modes available. Editors can preview here.
QA
Validation by QA against staged content.
Both modes available.
UAT
Editors & approvers review before publish.
Both modes available.
Production
End users see Live by default. Editors can preview here too.
Yes — Production previews unpublished content.
One Agility CMS instance serves every website deployment your team runs. Each registered deployment supports two modes — Preview (Staging/Draft, Awaiting Approval, Approved, Published) or Live (Published only). Production is fully previewable. The CMS doesn't change.
FIG. 01If you take one thing from this guide, take this: do not add CMS environments to mirror your DevOps environments. Add them only when your specific scenario requires it. The rest of this guide explains what those scenarios look like.
A related confusion worth calling out separately. A sitemap in Agility is the navigation and routing structure for one digital property. Channels group sitemaps under a single instance for multi-property setups. They exist so one instance can serve multiple websites or apps. They are not a substitute for DevOps environments, and they are not a workflow tool.
The pattern we see fail: a customer creates one sitemap for "production content," another for "staging content," another for "dev content," and another for "QA content." Editors are then asked to maintain four parallel copies of every page. Every content change has to be duplicated four times. Every release means manually reconciling four sitemaps. This is four times the editorial work and zero of the safety, because nothing prevents the wrong sitemap from going live, and there is no audit trail for which copy is canonical.
This usually arrives from teams whose previous platform forced them to model environments inside the content tree because it had no other way to do it. Agility does not work that way. The right tools for what those customers actually need are already in the box:
If you find yourself asking editors to duplicate pages across sitemaps, stop. The answer is one of the three options above, not a fifth sitemap.
When you change a content or component model, the code that reads that model usually has to change too. This relationship is the real pressure behind most requests for a sandbox or multi-environment setup. Worth understanding before you decide your topology, because most model changes are safer than they look.
Three cases, in order of risk.
Additive changes are the easy case. Add a new field to an existing model and your existing code keeps working, as long as it does not choke on fields it does not recognize. Roll out the model change first. Roll out the code that reads the new field whenever it is ready. The two are decoupled. No environment separation required.
Removals are a two-step deprecation, not a one-step delete. Hide the field in the model and set it to not required. The code can stop using it whenever. Once nothing references it anywhere in production code, then delete it from the model. The trap is reversing those steps. If you delete the field while old code is still reading it, you risk null reference errors at runtime. Defensive code that null-checks every field read is the cheapest defence against this. Build that habit from day one and most "deletions" never need a separate environment to validate.
Type changes are the dangerous case. Two things have to work:
For type changes, the cleanest pattern is usually a new field plus a migration, not editing the existing field in place. Add the new field, populate it from the old one, update the code to read the new field, hide the old one, eventually delete it. Slower but reversible at every step.
This is where a sandbox earns its keep. Type changes are exactly the case where running the change in an isolated instance first is genuinely useful. You can confirm what happens to existing values before touching production data. For purely additive changes and well-managed deprecations, a sandbox is nice to have, not necessary.
Where the CLI fits. Model changes can be synced between instances using the CLI when your topology calls for it. The sync is the mechanic. The additive-then-deprecate-then-delete discipline above is the strategy. The CLI does not relieve you of the discipline. A destructive type change synced from DEV to PROD loses the same data as one made directly in the production UI.
Most customers fit one of three topologies. Pick yours before you read the workflow sections.
Do you have multiple developers actively working on content models at the same time?
Do you need to test field-type changes or other destructive model changes in isolation before they reach production?
Does a regulator require demonstrably isolated environments — or does your consuming product need a non-production content surface with realistic test fixtures for QA?
Walk this tree top-to-bottom. The default answer at every step is No, which lands you on Single instance. Add complexity only when a specific scenario forces you off that path.
FIG. 02The three options:
The rest of this guide walks through each.
Coming from Contentful or Sanity? Their model nests environments inside a top-level workspace, and you spin up additional environments by cloning. Agility treats each instance as a fully isolated, production-grade environment. Tradeoff: you cannot clone an environment in three clicks, but every Agility instance can be configured with its own SLA, versioning depth, and workflow rules to match its specific role. Most customers have different requirements for sandbox versus production, and that is fine. Use the CLI's clone or sync operations for the equivalent of spinning up and refreshing a sandbox.
This is what most customers need. One production Agility instance. Editors and developers both work in it. The website code is deployed to multiple environments (local, dev, UAT, prod), all pointing at the same instance.
Staging / Draft
Editor working on content. Visible on Preview.
Awaiting Approval
Submitted for review. Approver can approve or decline.
Approved
Reviewed and ready. Not yet live.
Published
Live on every registered deployment’s Live URL.
The first three states (Staging/Draft, Awaiting Approval, Approved) are all returned by the Preview API. Only Published is returned by the Live API. The whole workflow lives in a single instance — adding more CMS environments adds nothing here.
FIG. 03This workflow handles the majority of customers. Resist adding complexity until you have a concrete reason that this workflow does not solve.
Add a sandbox instance when your team has multiple developers working on the content model simultaneously, or when you regularly need to test destructive model changes (field type changes especially) without risking production data. See "Model changes and the code that uses them" above for which changes warrant this and which do not.
Build v1 in production. Add the sandbox after.
This sounds backwards if you are coming from a code-first mental model, but it is the right sequencing for content. The sandbox exists to protect a working production instance from destructive experiments. Until you have a working production instance, there is nothing to protect, and the sandbox has nothing realistic to test against. Cloning an empty instance into another empty instance is theatre.
Once production is live and your editors are working in it, clone production to create the sandbox. From that point forward, model changes that warrant isolation start in sandbox and promote upward, and the sandbox gets refreshed from production whenever its content drifts too far from reality.
The principle that makes this work: architecture promotes upward, content does not.
Sandbox Instance
Developers only · model & architecture changes
Production Instance
Editors & developers · live editorial work
Two instances. Architecture (models, containers, templates) is promoted from Sandbox up to Production via the CLI — frequently, like code. Content flows the other way as a refresh, so developers test against realistic data. This is the opposite of what most people assume on day one.
FIG. 04The Agility CLI is a single npm package (@agility/cli) with the commands login, pull, push, clone, and sync. How you use it depends on where you are running it and whether the run needs to be repeatable. There is also an MCP server that exposes the same operations through an AI assistant. Three real paths:
agility login, which opens a browser to complete the OAuth flow. Then use pull, push, and clone for ad-hoc operations: cloning prod to a fresh sandbox, pulling models down to inspect them, pushing a one-off architecture change. This is the right starting point for any team adopting the sandbox topology.agility sync. Same CLI, run with the --headless flag and authenticated via a Personal Access Token instead of a browser. The sync command persists a mappings file alongside your project that records the relationship between source and target IDs. Commit the mappings to your repo and sync becomes idempotent: running it twice does not create duplicates. This is the right path once you have a stable promotion process worth automating.mcp.agilitycms.com from Claude or another MCP-aware client, point at your source and target instances, and describe what you want moved at the level of intent ("clone the Press Release model and its containers from sandbox to prod") instead of remembering CLI flags. The MCP server uses the same underlying APIs and produces the same result. Useful for complex one-off migrations where you would otherwise be flipping back and forth through CLI documentation. The MCP server authenticates per user via OAuth, so it is for interactive human-plus-AI use, not a replacement for agility sync in unattended CI pipelines.All three paths work against the same instances and can be used on the same project. Most teams start with the local CLI for exploration, graduate to agility sync in CI once the promotion shape stabilises, and reach for the MCP server for the operations that fall in between.
For installation, command syntax, flags, mappings details, and PAT setup, see the CLI references at the bottom of this guide.
The CLI can move models, galleries, assets, containers, content, templates, and pages. These can be moved together or scoped down to specific elements (for example, models only, or a specific model and its dependencies).
The CLI does not move: users, roles, permissions, webhooks, integration configurations, app installations, or API keys. These are instance-local by design. Configure them per instance.
This is the topology for genuine separation between non-production and production content surfaces. Most customers do not need this. Justified scenarios:
If your scenario is "we want to feel safer," you do not need this. The single-instance workflow with approvals is already audit-ready. If your scenario is "our developer team has DEV, UAT, and PROD for the website code," you do not need this either. Multiple website deployments pointed at one instance is the right answer.
agility sync
DEV
Developer-owned. No editors. Validates model & CI scripts before UAT.
No editorsUAT
Editors stage release content. QA validates against the UAT build.
Editors · release stagingPROD
Live editorial work. Published content goes live here.
Editors · primaryagility sync or clone
Each instance is fully production-grade in capability. The asymmetry is in role and content, not technical capability.
Three instances, each production-grade. Architecture (models, containers, templates) promotes upward via CI. Content refreshes downward on demand. Real content lives in PROD; lower environments seed from it. Use this topology only when compliance or external QA fixture needs justify it.
FIG. 05This is the opposite of the database mental model. People expect everything to flow upward like code. It does not. Real content lives in PROD. Lower environments get refreshed from PROD when fixtures are stale.
When the CLI runs in CI/CD, it persists a mappings file alongside your project. The mappings record the relationship between content IDs in the source instance and content IDs in the target instance. Commit the mappings to your code repository.
Why this matters:
If you treat mappings as throwaway, you will get duplicate content. Treat them as part of your codebase.
Browser-based login does not work in CI environments. Pipelines authenticate using a Personal Access Token (PAT) instead.
A typical pipeline for architecture promotion looks like this conceptually:
The same pattern repeats for each promotion stage. DEV to UAT runs on release branches. UAT to PROD runs on main or on a manual approval gate.
For full pipeline templates and platform-specific examples (GitHub Actions, GitLab, Azure DevOps), see the CLI - CI/CD Integration Guide.
The CLI also lets your pipeline drive editorial workflow operations on the synced content. After a sync, the same pipeline can publish, approve, decline, request approval, or unpublish the items it just moved.
Three patterns worth naming:
This is the piece that makes the multi-environment topology coherent. Without it, you would sync content into UAT and then manually walk it through approval. With it, the CI pipeline owns the end-to-end promotion. Most prospects evaluating Agility for multi-environment use do not realize this exists.
If your driver is regulatory, the pieces of the audit story are:
Multi-instance separation is one piece of this. It is not the whole picture. Strong workflow inside a single instance often satisfies more of the audit story than people assume. Confirm with your auditor before assuming you need multiple instances.
Things to avoid:
For the full command reference, see:
Known limits worth setting expectations around:
You can have as many website deployments as you want per CMS instance. A typical setup includes local development plus deployments for dev-test, QA, UAT, and production. The exact set varies by team. Some teams have only UAT and production. Larger teams may have additional environments for performance testing, regional rollout, or customer-specific staging.
Register every non-local deployment in Web Studio. Once registered, each deployment supports two modes:
Both modes are available on every registered deployment, including production. Editors can preview unpublished content on the actual production website, on UAT, or on any other registered deployment, by copying the appropriate URL from Web Studio. Local development is the only deployment that typically does not register with the CMS, because it is not a stable URL editors would point at.
Whether a single deployment actually serves both modes depends on the website framework and how it is implemented. Our recommended approach is Next.js using the example code we ship, which has preview and live mode switching built in. Sites built on other frameworks need this wired up explicitly. If dual-mode preview is important to your editorial workflow, confirm your chosen framework supports it before committing to a topology.
For multi-environment topologies, each CMS instance has its own corresponding set of registered deployments. The preview/live mode distinction applies to every registered deployment, in every environment. There is no environment that is "preview-only" or "live-only" by virtue of being non-production. The mode is chosen by the URL the user opens.