What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
CLI - Public Beta
The Agility CLI lets you download an instance's content and structure to local files (pull), upload local files back up to an instance (push), and synchronize content and structure directly between two instances (sync).
Version: install the latest published version. See the npm versions page.
1. Important considerations
Chained multi-instance syncs (A → B → C)
After syncing instance A to B, the CDN publishing tasks triggered on B must finish before you use B as the source for a sync to C. Using B as a source too early can cause data loss. There is currently no way to confirm that publishing tasks have completed; a future release will block syncing from an instance with pending or errored tasks. For now, allow time between chained syncs.
Start with a blank target
The sync creates source→target mappings on its first run and cannot incorporate content that already exists independently on the target. For reliable environment parity, sync into a blank target instance.
Synced items get new Content IDs
Items created on the target during a sync receive new Content IDs; they do not carry the source's IDs across.
2. Install
The CLI is published on npm. Install it globally, replacing {version} with the version you want:
sudo npm install -g @agility/cli@{version}The latest published version is listed on the npm versions page.
3. Authentication
Authentication happens automatically the first time you run pull, push, or sync. You can also authenticate explicitly:
agility loginThis opens a browser window for secure authentication.
agility logoutYou must have an Org Admin, Instance Admin, or Manager role to perform CLI operations.
Non-interactive authentication (CI/CD)
Where a browser login isn't possible, authenticate with a Personal Access Token (PAT) instead of the OAuth browser flow. See the Personal Access Tokens documentation for how to create and manage one.
Provide the token via the --token flag or the AGILITY_TOKEN environment variable, and run with --headless=true:
agility pull --sourceGuid="abc123" --token="your-pat-here" --headless=true4. Environment configuration
You can set default values in an optional .env file (or as environment variables) so you don't have to pass them on every command. Command-line flags override environment values.
AGILITY_GUID=your-source-instance-guid
AGILITY_TARGET_GUID=your-target-instance-guid
AGILITY_LOCALES=en-us,fr-ca
AGILITY_TOKEN=your-personal-access-tokenEach documented flag has a matching environment variable:
| Environment variable | Flag |
|---|---|
| AGILITY_GUID | --sourceGuid |
| AGILITY_TARGET_GUID | --targetGuid |
| AGILITY_LOCALES | --locales |
| AGILITY_WEBSITE | --channel |
| AGILITY_ELEMENTS | --elements |
| AGILITY_MODELS | --models |
| AGILITY_ROOT_PATH | --rootPath |
| AGILITY_TOKEN | --token |
| AGILITY_OVERWRITE | --overwrite |
| AGILITY_VERBOSE | --verbose |
| AGILITY_HEADLESS | --headless |
5. Commands overview
The CLI has three main commands: pull, push, and sync.
pull: Downloads an instance's content and structure (models, containers, templates, content, pages, assets, galleries) to local files under agility-files/. Use it to take a local snapshot of an instance, for inspection, backup, or as the first half of a manual pull-then-push migration.
push: Uploads local files (created by a previous pull) up to a target instance, resolving dependencies in two passes so references point at the correct entities on the target. Use it when you already have a local copy and want to deliver it to a blank instance.
sync: Sets up a persistent relationship between two instances that are intended to be synced together in a unidirectional way. This migrates content and models directly from a source instance to a target instance in a single command, maintaining reference mappings so the two stay correlated across repeated runs. This is the command most migrations use, and the bulk of this guide covers it. pull and push share most of the same options; the conflict-resolution flag (--overwrite) and the publish-state flag (--autoPublish) apply specifically to sync.
Authentication runs automatically the first time you use any of them (see Section 3).
Each command works against an instance identified by its GUID. Find it in the Agility manager under Settings → API Keys, labelled GUID.
6. Pull command
Downloads content from an Agility instance to local files.
agility pull [options]| Option | Type | Default | Description |
|---|---|---|---|
| --sourceGuid | string | — | Instance GUID to pull from. Provide this flag or set AGILITY_GUID |
| --token | string | — | Personal Access Token for non-interactive auth; falls back to AGILITY_TOKEN |
| --locales | string | all (auto-detected) | Locale(s) to pull. Comma-separated for multiple |
| --channel | string | website | Channel to pull; falls back to AGILITY_WEBSITE |
| --elements | string | all | Comma-separated subset: Models,Galleries,Assets,Containers,Content,Templates,Pages,Sitemaps |
| --models | comma-separated list | none | Pull only the specified models and their direct content |
| --models-with-deps | comma-separated list | none | Pull the specified models with their full dependency tree: content, pages, assets, galleries, templates, containers |
| --preview | boolean | true | Use preview (staging) data rather than live |
| --rootPath | string | agility-files | Local directory for downloaded files |
| --baseUrl | string | default | Override the API base URL |
| --verbose=true | boolean | true | Detailed console output |
| --headless=true | boolean | false | No interactive UI; log to file only |
Examples
# Pull everything for a locale
agility pull --sourceGuid="abc123" --locales="en-us"
# Pull specific elements only
agility pull --sourceGuid="abc123" --locales="en-us" --elements="Models,Content"Downloaded files are written under the local agility-files/ directory (see Section 10).
7. Push command
Uploads content from your local files (created by a previous pull) up to an Agility instance, using a two-pass dependency system.
agility push --targetGuid=<targetGuid> [options]| Option | Type | Default | Description |
|---|---|---|---|
| --targetGuid | string | required | Target instance GUID to push to (or set AGILITY_TARGET_GUID) |
| --token | string | — | Personal Access Token for non-interactive auth; falls back to AGILITY_TOKEN |
| --locales | string | all (auto-detected) | Locale(s) to push. Comma-separated for multiple |
| --channel | string | website | Channel to push; falls back to AGILITY_WEBSITE |
| --elements | string | all | Comma-separated subset: Models,Galleries,Assets,Containers,Content,Templates,Pages,Sitemaps |
| --models | comma-separated list | none | Push only the specified models and their direct content |
| --models-with-deps | comma-separated list | none | Push the specified models with their full dependency tree: content, pages, assets, galleries, templates, containers |
| --preview | boolean | true | Use preview (staging) data rather than live |
| --rootPath | string | agility-files | Local directory to read files from |
| --baseUrl | string | default | Override the API base URL |
| --verbose=true | boolean | true | Detailed console output |
| --headless=true | boolean | false | No interactive UI; log to file only |
Push reads from the local agility-files/ directory (see Section 10).
8. Sync command
Synchronizes content and structure from a source instance to a target instance, with dependency resolution via reference mappings. This is the most fully-featured command.
agility sync --sourceGuid=<sourceGuid> --targetGuid=<targetGuid> [options]The sync is forward-only: it creates and updates entities on the target to match the source, but never deletes or unpublishes anything on the target.
Sync works from the local agility-files/ directory and maintains reference mappings under agility-files/mappings/ (see Sections 9 and 10).
8.1 Flags
| Option | Type | Default | Description |
|---|---|---|---|
| --sourceGuid | string | — | Source instance GUID (copy from). Provide this flag or set AGILITY_GUID |
| --targetGuid | string | required | Target instance GUID, copy to (or set AGILITY_TARGET_GUID) |
| --token | string | — | PAT for non-interactive auth; falls back to AGILITY_TOKEN |
| --locales | string | all (auto-detected) | Locale(s) to sync. Comma-separated for multiple |
| --channel | string | website | Channel to sync; falls back to AGILITY_WEBSITE |
| --elements | string | all | Comma-separated subset: Models,Galleries,Assets,Containers,Content,Templates,Pages,Sitemaps |
| --models | comma-separated list | none | Sync only the specified models and their direct content |
| --models-with-deps | comma-separated list | none | Sync the specified models with their full dependency tree: content, pages, assets, galleries, templates, containers |
| --overwrite=true | boolean | false | Resolve conflicts by overwriting the conflicted target items with the source versions. See 8.6 |
| --autoPublish | string | disabled | Mirror source publish state. Values: content, pages, both. See 8.5 |
| --preview | boolean | true | Use preview (staging) data rather than live |
| --rootPath | string | agility-files | Local directory for sync files |
| --baseUrl | string | default | Override the API base URL |
| --verbose=true | boolean | true | Detailed console output |
| --headless=true | boolean | false | No interactive UI; log to file only |
If the target does not support every locale present on the source, the sync stops cleanly before making any changes; there is no partial push.
8.2 What gets synced
| Entity | What's covered |
|---|---|
| Content Models | Reference name, display name, all field types (Text, HTML, Content, ImageAttachment, etc.), field labels, help text, validation, defaults, content definition type |
| Component / Module Models | Same coverage as content models, used for page modules |
| Containers (shared, top-level) | Reference name, view name, model assignment, default sort, listing settings, publish state |
| Containers (nested ContentView lists) | The internal containers Agility creates for linked-content fields on a model |
| Page Templates | Layout and module zone definitions |
| Pages | Name, title, menu text, hierarchy/parentage, SEO (meta description, keywords, robots), visibility flags (menu, sitemap), zone module assignments with content references, channel association |
| Content Items | All field values for every field type, content state (staging/published), item order, linked-content references, asset references, locale assignment |
| Galleries / Media Groupings | Name, description, parent grouping |
| Assets / Media files | Binary content (any file type), filename, container path, content type, size |
Linked content is copied across, and the mappings between related items are preserved.
8.3 Sync mechanics
| Operation | Behaviour |
|---|---|
| Initial sync (fresh target) | Every entity type is created and a mapping recorded for each |
| Re-sync, no changes | Safe to re-run: everything is skipped, nothing is written |
| Source-side update | Pushed to the target; the mapping is updated to the new version |
| Conflict (both sides changed) | Flagged and skipped, unless --overwrite=true is set (see 8.6) |
| Mapping integrity | One-to-one source↔target mapping is preserved across re-runs |
| Multi-locale | Each source locale syncs independently, provided the target has the same locale registered |
Content is matched by versionID on subsequent syncs: only newer versions are pushed, and duplicates are skipped.
8.4 Selective sync
For partial syncs, scope the run rather than syncing the whole instance:
--elements="Models,Content": limit to specific entity types.--models="Model1,Model2": sync only those content models and their direct content.--models-with-deps="Model1,Model2": sync those models with their full dependency tree: content, pages, assets, galleries, templates, and containers.
# Sync only models
agility sync --sourceGuid="abc123" --targetGuid="def456" --models="Model1,Model2"
# Sync models plus their dependencies
agility sync --sourceGuid="abc123" --targetGuid="def456" --models-with-deps="Model1,Model2"8.5 Publish state and --autoPublish
By default, synced content lands on the target in staging, regardless of its state on the source. The target site or app won't surface a new item until it has been published. Use --autoPublish to carry the source's publish state across.
Modes
| Value | Behaviour |
|---|---|
| --autoPublish or --autoPublish=both | Publish both content items and pages (default when no value is given) |
| --autoPublish=content | Publish only content items (skip pages) |
| --autoPublish=pages | Publish only pages (skip content items) |
How it works
- Tracks which items were successfully pushed to the target.
- Checks each item's publish state in the source; only items published in the source are eligible.
- Publishes the eligible items on the target via the batch workflow API, per locale.
- Updates reference mappings after publishing.
Only items published in the source are published on the target; staging-only items stay in staging. Auto-publish applies to sync only (not pull). Failed items aren't published, and any errors are listed in the final summary.
The sync never unpublishes anything. --autoPublish only ever adds a publish; it never removes one, in any mode.
Edge case: a published item with a newer staging version
In Agility, an item can be published and have a more recent unpublished (staging) version at the same time. This happens whenever someone publishes an item, then begins editing it again without re-publishing.
The sync always copies the latest version. When the latest version is the staging one, that's what's transferred, so --autoPublish finds it in a non-published state and leaves the target item in staging.
The result can be surprising: pages that look "published" on the source arrive in the target's Ready to Publish list even with --autoPublish set. This is expected; the source's latest version was a staging edit, and that's the version that synced.
To resolve: publish the staging version on the source first, so the source's latest version is the published one. Then re-sync with --autoPublish, and the target will publish that version.
8.6 Conflict resolution and --overwrite
A conflict occurs when the same entity has changed on both the source and the target since the last sync. By default the CLI skips conflicted entities and preserves the target's version, logging a Conflict detected, use --overwrite to force message.
--overwrite=true resolves conflicts in favour of the source: for each conflicted entity, it overwrites the target version with the source version.
What --overwrite does
- Resolves conflicts across all synced entity types: content items, pages, containers, models, templates, galleries, and assets. A conflict is when an item changed on both sides;
--overwritepushes the source version. - Overwrites only the target entities genuinely in conflict; unchanged entities are still skipped.
What --overwrite does not do
- It does not re-push entities that haven't changed; re-running with
--overwrite=trueon an already up-to-date sync still writes nothing. - It does not change publish state; that's governed separately by
--autoPublish. - It does not delete or unpublish anything on the target; the sync is always forward-only.
Overwrite doesn't destroy the live published version. Resolving a conflict writes the source's content into the target item's staging version; the currently-published version stays live and unchanged. The new version only replaces what's live if you also pass --autoPublish, and even then the previous content is retained as a prior entry in the target's version history, not deleted.
Use --overwrite=true after a sync has reported Conflict detected and you've decided the source should win.
8.7 What the CLI does NOT do
The sync only moves content forward. The following are out of scope and must be handled manually on the target (see Section 13).
| Not synced | Detail |
|---|---|
| Source-side deletions and unpublishes | If anything is deleted or unpublished on the source after a sync (a model, content item, page, container, template, asset, or gallery), the target's copy stays in place. The CLI does not detect the removal. Applies to published→staging unpublishes, soft deletes, and hard deletes. |
| Pre-existing target content | Content that already exists independently on the target cannot be remapped or replaced; sync into a blank target for parity. |
| Version history | Only the current version of an entity is applied on the target; prior versions are not recreated as target history. |
8.8 Current content sync gaps
The following items are not yet transferred by the sync and must be handled manually on the target after each run.
| Gap | Detail |
|---|---|
| Image focal points | The focal-point coordinate that tells templates where to crop an image does not transfer. |
| URL redirections | Page/URL redirect entries do not transfer. |
9. Reference mappings
Reference mappings record the relationship between each source entity and its corresponding target entity. They are what make sync dependency-aware and re-runnable.
How they work
- Discovery: the CLI catalogs entities on both instances.
- Mapping creation: establishes source↔target relationships using identification strategies.
- Dependency resolution: transforms entity references (model IDs, asset URLs, template references) during the push so target entities point at the right target dependencies.
Why they matter
- Dependency resolution: pages reference the correct target templates; field references are rewritten to target IDs.
- Conflict prevention: prevents duplicate creation and enables safe, incremental re-runs.
- Multi-instance support: each source→target pair has its own mapping set, supporting chained pipelines.
Lifecycle
- Automatic loading: existing mappings are loaded when a sync starts, then preserved and extended.
- Incremental updates: new entities are added as discovered; existing rows are updated when the target changes.
- Manual management: mapping files can be deleted to reset the relationship for a pair.
10. File structure
The CLI reads and writes everything under a local agility-files/ directory (override the location with --rootPath). This layout is shared by pull, push, and sync:
agility-files/
├── {instance-guid}/
│ ├── models/ # Content models
│ ├── containers/ # Content containers
│ ├── templates/ # Page templates
│ ├── galleries/ # Galleries
│ ├── assets/ # Media files
│ │ └── json/ # Asset metadata
│ ├── sitemaps/ # Sitemap definitions
│ └── {locale}/ # Per-locale content
│ ├── item/ # Content items
│ ├── list/ # Content lists
│ ├── page/ # Pages
│ ├── sitemap/ # Flat sitemap
│ ├── nestedsitemap/ # Nested sitemap structure
│ ├── urlredirections/ # URL redirections
│ └── state/ # Sync state and tokens
├── mappings/ # Reference mappings (sync only)
└── logs/ # Operation logsMappings (created during sync only)
Reference mappings are written only when you run sync; pull and push don't create them. They're stored per source→target pair:
agility-files/
└── mappings/
└── {sourceGuid}-{targetGuid}/
├── models/ # Content model mappings
├── containers/ # Container mappings
├── templates/ # Template mappings
├── galleries/ # Gallery mappings
├── assets/ # Asset mappings
└── {locale}/ # Per-locale mappings
├── item/ # Content item mappings
└── page/ # Page mappings11. Reading the sync log
Line markers
| Marker | Meaning |
|---|---|
| ● | Action performed (created, updated, downloaded) |
| ○ | Action skipped (already up to date, or no change needed) |
| ✗ | Action failed, or a conflict was detected |
| ⚠️ | Warning: non-fatal, informational |
| 📋 | Decision note (e.g. auto-publish reasoning) |
Phases (in order)
- Authentication and source pull
- Target pull (for comparison)
- Asset galleries and media groupings
- Media files and asset metadata
- Content models and field definitions
- Content containers and views
- Page templates and layouts
- Content items (per locale)
- Pages and page hierarchy (per locale)
Each push phase ends with a summary line:
Push <phase>: N successful, M skipped, K failedFor the authoritative per-phase outcome, rely on these per-phase summary lines.
Useful lines to look for
| To find out… | Look for |
|---|---|
| Total runtime | Total time: |
| Whether the sync succeeded | ✓ Sync completed successfully or ✗ Sync completed with errors |
| Conflicts | Conflict detected |
| Per-locale content decisions | [FilterContent] Decision summary: N create, M update, K skip, L conflict |
| Per-phase totals | Push <phase>: … successful, … skipped, … failed</phase> |
12. Typical workflows
Initial target population
Brand-new (blank) target, established source. First sync to populate the target.
agility sync --sourceGuid="abc123" --targetGuid="def456" --autoPublish--autoPublish ensures content published on the source arrives published on the target, rather than waiting in staging.
Expect: a longer runtime, many created lines, mapping files filling out, and ✓ Sync completed successfully at the end.
Verify: target entity counts line up with the source; key pages render correctly; mappings are one-to-one.
Ongoing sync
agility sync --sourceGuid="abc123" --targetGuid="def456"Add --autoPublish if the target should immediately reflect the source's publish state.
Expect: a short runtime, mostly up to date, skipping, and updated lines only where the source genuinely changed.
Verify: spot-check the items you know changed; confirm 0 failed in every phase.
Resolving conflicts
If a sync reports Conflict detected, both sides changed the same entities since the last sync:
- Source wins (the usual case): re-run with
--overwrite=true. - Target wins: do nothing; the target's version is already preserved.
agility sync --sourceGuid="abc123" --targetGuid="def456" --overwrite=true13. Manual post-sync procedures
Because the items in Section 8.7 aren't synced, handle them on the target as follows.
- Remove content deleted on the source: the CLI doesn't propagate deletions; delete the corresponding target entities in the Agility manager.
- Unpublish content unpublished on the source: manually unpublish the affected target items in the Agility manager.
14. Troubleshooting & FAQs
Sync stops immediately reporting missing locales
The source has a locale the target doesn't support. Add the locale on the target, or use --locales to restrict the sync to supported locales.
A locale's pages aren't pushed
The locale is registered on the source but has no published sitemap. If expected, ignore; otherwise publish the locale's sitemap on the source.
Conflict detected on a page, content item, or container
Both the source and target changed that entity since the last sync. The sync skips it and preserves the target version. To let the source win, re-run with --overwrite=true.
Sync halts with a model conflict error
If the CLI detects a structural incompatibility between a content model on the source and its counterpart on the target that it cannot auto-resolve, the sync stops and logs a model conflict error. This is different from the content conflicts that --overwrite=true handles; it requires manual resolution.
Pages published on the source land in Ready to Publish on the target, even with --autoPublish
Those pages were published, but each also had a more recent staging version. The sync copies the latest version (the staging one), so --autoPublish correctly leaves the target item in staging. This is expected. To fix it, publish the staging version on the source first, then re-sync. See Section 8.5.
FAQs
Can I pull/sync only selected content lists?
The first sync copies all content. Subsequent syncs bring across only newer versions via the established mappings; content is updated by versionID and duplicates are skipped.
Can I sync a specific subset of models and their content?
Yes. Use --models-with-deps to target one or more models and bring forward the staged or published content under them.
How are linked content and mappings handled?
Linked content is copied across, and the mappings between related items are preserved.
What state does synced content land in?
Staging, regardless of the source state. Use --autoPublish to publish items that were published in the source. Staging-only items stay staged; unpublished or deleted source items are not pulled across.
Which version is synced: staging or published?
The most recent version is synced regardless of its published status on the source, and it lands on the target in staging. Only that current version is applied; version history is not carried to the target.
If source content was published and then modified/staged, which version syncs?
The most recent version always syncs, regardless of staging or published state. See Section 8.5 for why this can leave a published page in staging on the target.
Does the CLI reconcile/replace existing target content, or append?
Neither; pre-existing target content cannot be remapped or replaced. The initial sync establishes a new mapping, so syncing into a blank instance is strongly recommended for environment parity.
Do synced items have the same Content ID as the source?
No. All synced content is created with new Content IDs on the target.