Export All Architect Flows as JSON Using the Genesys Cloud CX as Code CLI
What You Will Build
- One sentence: A Python script that authenticates with Genesys Cloud and leverages the
genesys-cloud-cx-as-codeCLI to export every Architect flow in your organization into a structured JSON directory. - One sentence: This uses the Genesys Cloud Platform API for authentication and the official
genesys-cloud-cx-as-codeCLI for the heavy lifting of flow serialization. - One sentence: The tutorial covers Python 3.9+ for orchestration and Bash for CLI execution.
Prerequisites
- OAuth Client Type: Confidential Client (Client Credentials Grant). You must have a Genesys Cloud OAuth client with the
adminscope or specificarchitect:flow:readscopes. - SDK/CLI Version:
genesys-cloud-cx-as-codeCLI v0.25.0 or later. - Language/Runtime: Python 3.9+ and Node.js 16+ (required by the CLI).
- External Dependencies:
genesys-cloud-cx-as-code(installed vianpm install -g @genesys/cloud-cx-as-code-cliornpx).httpxfor Python (optional, if you prefer a pure Python approach, but this tutorial focuses on the CLI as requested).osandsubprocess(standard library).
Authentication Setup
The CX as Code CLI relies on the Genesys Cloud SDK for JavaScript under the hood. It supports two primary authentication modes:
- Environment Variables: Setting
GENESYS_CLOUD_REGION,GENESYS_CLOUD_CLIENT_ID, andGENESYS_CLOUD_CLIENT_SECRET. - Config File: Using
genesys-cloud-cx-as-code config initto create a.genesysconfig file.
For programmatic automation, we will inject the credentials via environment variables to avoid exposing secrets in plaintext scripts.
Required Scopes:
architect:flow:read(Minimum)admin(Recommended for full visibility including private flows)
Implementation
Step 1: Install and Configure the CLI
Before writing Python code, ensure the CLI is available. The CLI is a Node.js application.
# Install the CLI globally
npm install -g @genesys/cloud-cx-as-code-cli
# Verify installation
genesys-cloud-cx-as-code --version
Step 2: Create the Python Orchestration Script
We will write a Python script that:
- Sets up the necessary environment variables for the CLI.
- Executes the
genesys-cloud-cx-as-code exportcommand. - Handles the output directory structure.
The genesys-cloud-cx-as-code export command is the core mechanism. By default, it exports all entities. To target only Architect flows, we use the --types flag.
import os
import sys
import subprocess
import shutil
from pathlib import Path
from typing import Optional
class GenesysFlowExporter:
def __init__(self, region: str, client_id: str, client_secret: str, output_dir: str = "./exports"):
self.region = region
self.client_id = client_id
self.client_secret = client_secret
self.output_dir = Path(output_dir)
def _setup_env(self) -> dict:
"""
Creates a modified environment dictionary with OAuth credentials.
This prevents polluting the parent process environment.
"""
env = os.environ.copy()
env["GENESYS_CLOUD_REGION"] = self.region
env["GENESYS_CLOUD_CLIENT_ID"] = self.client_id
env["GENESYS_CLOUD_CLIENT_SECRET"] = self.client_secret
return env
def _clean_output_dir(self) -> None:
"""
Removes existing export data to prevent merge conflicts
or stale data issues.
"""
if self.output_dir.exists():
shutil.rmtree(self.output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
print(f"Created clean output directory: {self.output_dir}")
def export_flows(self, include_private: bool = True) -> bool:
"""
Executes the CX as Code CLI to export Architect flows.
Args:
include_private: If True, exports private flows as well.
Requires admin scope.
Returns:
True if successful, False otherwise.
"""
# Construct the CLI command
# --types: Specifies we only want 'flows'
# --output-dir: Where to save the JSON files
# --include-private: Include private flows (if scope allows)
cmd = [
"genesys-cloud-cx-as-code",
"export",
"--types", "flows",
"--output-dir", str(self.output_dir),
]
if include_private:
cmd.append("--include-private")
# Setup environment with credentials
env_vars = self._setup_env()
# Clean the directory before export
self._clean_output_dir()
print("Starting Genesys Cloud Architect Flow Export...")
print(f"Command: {' '.join(cmd)}")
print("-" * 40)
try:
# Execute the CLI command
# capture_output=True ensures we can read stdout/stderr
# env=env_vars passes our OAuth credentials
result = subprocess.run(
cmd,
env=env_vars,
capture_output=True,
text=True,
check=False # We handle returncode manually
)
if result.returncode != 0:
print("ERROR: CLI execution failed.")
print(f"STDOUT: {result.stdout}")
print(f"STDERR: {result.stderr}")
return False
print("SUCCESS: Export completed.")
print(f"STDOUT: {result.stdout}")
# Validate that files were created
flow_files = list(self.output_dir.glob("**/flow.json"))
if not flow_files:
print("WARNING: No flow.json files found in output directory.")
return False
print(f"Exported {len(flow_files)} flow definitions.")
return True
except FileNotFoundError:
print("ERROR: 'genesys-cloud-cx-as-code' command not found. Is it installed globally?")
return False
except Exception as e:
print(f"UNEXPECTED ERROR: {e}")
return False
if __name__ == "__main__":
# In production, load these from a secure vault or .env file
REGION = "mypurecloud.com" # Example: us-east-1.mygenesys.com
CLIENT_ID = "your_client_id_here"
CLIENT_SECRET = "your_client_secret_here"
if CLIENT_ID == "your_client_id_here":
print("Please configure your CLIENT_ID and CLIENT_SECRET in the script.")
sys.exit(1)
exporter = GenesysFlowExporter(
region=REGION,
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
output_dir="./architect_exports"
)
success = exporter.export_flows(include_private=True)
sys.exit(0 if success else 1)
Step 3: Understanding the Output Structure
The CX as Code CLI does not output a single flat JSON file. It creates a directory structure that mirrors the Genesys Cloud entity hierarchy. This is crucial for version control (Git) and diffing.
For each flow, the CLI creates a directory named after the Flow ID. Inside, you will find:
flow.json: The main definition of the flow.flow-refs.json: References to other entities (like IVRs or WebChat).flow-entities/: A folder containing dependent entities (like Prompt, Queue, or User objects) if they were exported alongside the flow.
Example Directory Structure:
./architect_exports/
└── flows/
└── <flow-id>/
├── flow.json
├── flow-refs.json
└── flow-entities/
├── prompts/
│ └── <prompt-id>.json
└── queues/
└── <queue-id>.json
Step 4: Parsing the Exported JSON (Optional Validation)
If you need to programmatically verify the exports or extract specific metadata (e.g., “Which flows contain a ‘Transfer’ step?”), you can parse the generated JSON.
import json
from pathlib import Path
def analyze_flows(export_dir: Path) -> list[dict]:
"""
Reads all exported flow.json files and extracts basic metadata.
"""
flows_data = []
flows_dir = export_dir / "flows"
if not flows_dir.exists():
print(f"Flows directory not found at {flows_dir}")
return flows_data
for flow_folder in flows_dir.iterdir():
flow_json_path = flow_folder / "flow.json"
if flow_json_path.exists():
try:
with open(flow_json_path, 'r', encoding='utf-8') as f:
flow_data = json.load(f)
# Extract key metadata
metadata = {
"id": flow_data.get("id"),
"name": flow_data.get("name"),
"version": flow_data.get("version"),
"status": flow_data.get("status"),
"type": flow_data.get("type"), # e.g., 'voice', 'digital'
"has_draft": flow_data.get("draft", {}).get("id") is not None
}
flows_data.append(metadata)
except json.JSONDecodeError as e:
print(f"Error parsing {flow_json_path}: {e}")
except Exception as e:
print(f"Unexpected error reading {flow_json_path}: {e}")
return flows_data
# Usage
if __name__ == "__main__" and "analyze" in sys.argv:
export_path = Path("./architect_exports")
flows = analyze_flows(export_path)
for flow in flows:
print(f"Flow: {flow['name']} (ID: {flow['id']}) - Status: {flow['status']}")
Complete Working Example
Combine the classes above into a single file export_flows.py.
- Install Node.js and the CLI.
- Install Python dependencies (none required beyond standard library for the basic script, but
httpxis recommended for future API calls). - Run the script.
# 1. Install CLI
npm install -g @genesys/cloud-cx-as-code-cli
# 2. Create the Python script (save as export_flows.py)
# [Insert the GenesysFlowExporter class code from Step 2 here]
# 3. Run the script
python export_flows.py
Expected Console Output:
Created clean output directory: ./architect_exports
Starting Genesys Cloud Architect Flow Export...
Command: genesys-cloud-cx-as-code export --types flows --output-dir ./architect_exports --include-private
----------------------------------------
SUCCESS: Export completed.
STDOUT: Exported 15 flows.
Exported 15 flow definitions.
Common Errors & Debugging
Error: 401 Unauthorized / “Invalid Client Credentials”
Cause: The GENESYS_CLOUD_CLIENT_ID or GENESYS_CLOUD_CLIENT_SECRET environment variables are incorrect, or the OAuth client is disabled.
Fix:
- Verify the Client ID and Secret in the Genesys Cloud Admin Console (Admin > Security > OAuth).
- Ensure the OAuth client has the
adminorarchitect:flow:readscope. - Check that the
GENESYS_CLOUD_REGIONmatches your organization’s region (e.g.,mypurecloud.comfor US,de1.mypurecloud.comfor Germany).
Code Check:
Ensure the _setup_env method in the Python script is correctly passing the variables to the subprocess.
Error: 403 Forbidden / “Insufficient Permissions”
Cause: The OAuth client does not have permission to read private flows, or the user associated with the client (if using JWT) lacks Admin rights.
Fix:
- If exporting private flows (
--include-private), the OAuth client must have theadminscope. - If you only want public flows, remove the
--include-privateflag from the command list in Step 2.
Error: “genesys-cloud-cx-as-code: command not found”
Cause: The CLI is not installed globally or is not in the system PATH.
Fix:
- Run
npm install -g @genesys/cloud-cx-as-code-cli. - Verify installation with
which genesys-cloud-cx-as-code(Linux/Mac) orwhere genesys-cloud-cx-as-code(Windows). - If using a virtual environment, ensure Node.js is accessible.
Error: “EACCES: permission denied”
Cause: The CLI attempts to write to a directory where the user lacks write permissions.
Fix:
- Ensure the
output_dirspecified in the Python script is writable by the current user. - Avoid using root directories like
/. Use a subdirectory like./exports.
Error: Large Export Timeout
Cause: Organizations with hundreds of complex flows may hit API rate limits or timeout during the export process.
Fix:
- The CX as Code CLI has built-in retry logic for 429 errors.
- If the export fails repeatedly, break the export into smaller batches. However, the CLI does not currently support a “flow ID list” filter for exports.
- Monitor the Genesys Cloud API usage dashboard for rate limiting.
- Increase the Node.js memory limit if necessary:
NODE_OPTIONS="--max-old-space-size=4096" genesys-cloud-cx-as-code export ...