Agent & Headless Ready
    API · MCP · SDK · CLI

    Built for Agents

    Skip the browser — call our REST API directly, connect Claude or GPT via our MCP server, use our Python or TypeScript SDK, or script workflows from the CLI. We are the server; you are the client.

    Try it live

    Run real API calls right here — no account or API key required

    GET
    /api/health
    Health check

    Verify the API is up. Returns status, version, and uptime.

    GET
    /api/description
    API description

    Discover every capability, tool, and endpoint this platform exposes — no key needed.

    GET
    /api/chaos/scenarios
    Chaos scenarios

    List all built-in failure scenarios you can inject: AZ outage, DB crash, network partition, and more.

    POST
    /api/simulations
    Create & step a simulation

    Create a real AWS simulation with a t3.medium compute resource, then immediately run a step to see live metrics — cpu, latency, errorRate, and cost.

    POST
    /api/demo/rl/start
    RL training loop

    Bootstrap a Gym-compatible RL environment, run the first episode step, and see the reward signal. Hit 'Step again' to advance the episode — watch obs, reward, done, and sim_time_human update with each action.

    Headless API Access

    Call our REST API directly — no browser or UI required on your end

    Your base URL

    Every API endpoint is available at this URL. Authenticate with your API key and start making requests — no setup on your end beyond getting a key.

    Bash
    https://cloudworldmodel.ai
    Authentication

    Pass your API key as a Bearer token in every request. Here's a minimal working example — create a simulation then advance it one step:

    Bash
    # All authenticated requests use a Bearer token in the Authorization header
    curl -X POST https://cloudworldmodel.ai/api/simulations \
    -H "Authorization: Bearer your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{
    "name": "prod-replica",
    "resources": [
    { "id": "web", "type": "compute", "name": "Web Server", "provider": "aws" }
    ]
    }'
    # Then step the simulation (replace <id> with the id from the response above)
    curl -X POST https://cloudworldmodel.ai/api/simulations/<id>/step \
    -H "Authorization: Bearer your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{ "trafficRPS": 1500 }'
    Health & OpenAPI endpoints
    Bash
    # Health check — no auth required
    curl https://cloudworldmodel.ai/api/health
    # → { "status": "ok", "version": "1.0.0", "uptime": 42.3 }
    # Full OpenAPI spec as JSON
    curl https://cloudworldmodel.ai/api-docs/openapi.json
    # Interactive Swagger UI
    open https://cloudworldmodel.ai/api-docs
    RL tick rate — warm-up vs. training
    tick_seconds

    Every /rl/environments/:id/step call accepts an optional tick_seconds field (1–3600) that overrides the episode-level clock for that single step. Use this to run a fast warm-up phase before your agent starts making real decisions:

    • 300 sWarm-up. Each step jumps 5 simulated minutes. Twenty steps cover ~1.7 hours of simulated time in seconds of wall time — skipping past startup noise before the agent takes over.
    • 60 sTraining. One-minute ticks give the agent precise per-minute visibility — matching the granularity of real autoscaling cooldown windows (AWS default: 300 s).

    The actual value used is reflected back in observation.tick_seconds so your agent always knows how much simulated time each step represents.

    Python
    import requests
    BASE_URL = "https://your-domain.com/api"
    API_KEY = "your_api_key_here"
    ENV_ID = "env-aws-001"
    session = requests.Session()
    session.headers.update({"Authorization": f"Bearer {API_KEY}"})
    def step(action: dict, tick_seconds: int) -> dict:
    r = session.post(
    f"{BASE_URL}/rl/environments/{ENV_ID}/step",
    json={"action": action, "tick_seconds": tick_seconds},
    )
    r.raise_for_status()
    return r.json()
    NO_OP = {"type": "no_op", "parameters": {}}
    # Phase 1 — Warm-up: large ticks fast-forward through startup noise.
    # 20 steps × 300 s = 6,000 s ≈ 1.7 h of simulated time.
    for i in range(20):
    data = step(NO_OP, tick_seconds=300)
    print(f"warmup {i+1:2d} sim={data['sim_time_human']} cpu={data['obs']['cpu_util']:.1%}")
    if data["done"]:
    break
    # Phase 2 — Training: 1-minute ticks for precise autoscaling control.
    # The agent now reacts on a per-minute basis, matching real cooldown windows.
    done = False
    while not done:
    cpu = data["obs"]["cpu_util"]
    if cpu > 0.75:
    action = {"type": "scale_out", "parameters": {"instanceCount": 1}}
    elif cpu < 0.30 and data["obs"]["instances"] > 1:
    action = {"type": "scale_in", "parameters": {"instanceCount": 1}}
    else:
    action = NO_OP
    data = step(action, tick_seconds=60)
    done = data["done"]
    print(
    f"t={data['t']:4d} reward={data['reward']:+.3f} "
    f"cpu={data['obs']['cpu_util']:.1%} "
    f"p95={data['metrics']['latency_p95']} ms "
    f"cost=${data['metrics']['cost_usd_hr']:.2f}/hr"
    )
    Aurora Serverless v2 episode-loop quickstart
    RL Quickstart
    aurora-serverless · Python

    Aurora Serverless v2 (aurora-serverless) scales ACUs continuously between minCapacity and maxCapacity, so cost tracks actual load rather than peak provisioned size. The simulation engine models a 2–4 step ACU ramp delay after add_resource — during those steps cpu_util reads 0 and cost_usd_hr reflects only the minCapacity floor (~$0.06/hr at 0.5 ACUs). The full episode loop — including ramp-up handling, reward shaping, and idle scale-back — is covered in the Simulation Walkthrough.

    Model Context Protocol — lets Claude, GPT, and other AI assistants call our simulation directly via stdio

    Install the MCP server
    Bash
    npm install -g "github:canvascloudai/cwm-mcp"
    Register in Claude Desktop (claude_desktop_config.json)
    JSON
    {
    "mcpServers": {
    "cloud-world-model": {
    "command": "npx",
    "args": ["cwm-mcp"],
    "env": {
    "CWM_API_KEY": "your_api_key_here",
    "CWM_BASE_URL": "https://cloudworldmodel.ai"
    }
    }
    }
    }
    Available tools
    create_simulationCreate a new virtual cloud environment with resources and connections.
    simulate_stepAdvance the simulation by one tick and return metrics.
    get_simulation_metricsRead the latest CPU, latency, error rate, and cost metrics.
    list_simulationsList all simulations visible to the current API key.
    rl_create_environmentCreate a Gym-compatible RL training environment linked to a simulation.
    rl_stepExecute one RL action (scale_out, scale_in, etc.) and receive observation/reward.
    rl_resetReset an RL environment to start a new episode.
    list_chaos_scenariosList available chaos engineering scenarios (AZ outage, DB crash, etc.).
    chaos_runStart a chaos experiment and return a job ID.
    chaos_job_statusPoll a running chaos job for completion.
    chaos_job_resultsRetrieve the full resilience report once a chaos job is done.
    multicloud_exploreGenerate and score multi-cloud architecture strategies.
    multicloud_job_statusPoll a multi-cloud exploration job.
    multicloud_job_resultsRetrieve ranked strategy results.
    prediction_validateValidate infrastructure against a traffic forecast.
    prediction_job_statusPoll a running prediction/validation job.
    prediction_job_resultsRetrieve full validation results including bottlenecks and recommendations.
    optimization_runStart an autoscaling threshold optimization job.
    optimization_job_statusPoll a running optimization job.
    optimization_job_resultsRetrieve optimized threshold recommendations once the job is done.

    Monitor active RL environments — episodes, rewards, and status — in the RL Environment Status viewer.

    Official Python client — zero dependencies, uses stdlib urllib

    Install
    Bash
    pip install "git+https://github.com/canvascloudai/cwm-sdk.git"
    Create simulation → simulate step → read metrics
    Python
    from cwm import CloudWorldModel
    client = CloudWorldModel(
    base_url="https://cloudworldmodel.ai",
    api_key="your_api_key_here",
    )
    # 1. Create a simulation
    sim = client.create_simulation({
    "name": "prod-replica",
    "resources": [
    {
    "id": "web",
    "type": "compute",
    "name": "Web Server",
    "provider": "aws",
    "characteristics": {"size": "t3.medium"},
    }
    ],
    })
    # 2. Run a simulation step
    result = client.simulate_step(sim["id"], traffic=1500)
    m = result["metrics"]
    print(m["cpuUsage"]) # e.g. 0.72
    print(m["latencyP95"]) # e.g. 143.2
    print(m["costPerHour"]) # e.g. 0.0464
    Aurora Serverless RL episode loop
    aurora-serverless

    Full episode loop using the SDK's higher-level interface — mirrors the Aurora Serverless quickstart without raw HTTP calls.

    Python
    from cwm import CloudWorldModel
    client = CloudWorldModel(
    base_url="https://www.cloudworldmodel.ai/api",
    api_key="your_api_key_here",
    )
    # 1. Create an RL environment linked to a simulation that already contains
    # at least one AWS database resource (the engine clones it for the episode).
    env_result = client.create_rl_environment(
    simulation_id="<sim-id>",
    episode_config={"maxSteps": 40},
    )
    env_id = env_result["environment"]["id"]
    # 2. add_resource action — adds an Aurora Serverless v2 database to the sim.
    # The engine models a 2-4 step ACU scale-out delay for aurora-serverless targets.
    step1 = client.rl_step(env_id, action={
    "type": "add_resource",
    "parameters": {"resourceType": "database", "provider": "aws"},
    })
    # Response keys: observation, reward {total, components, metrics}, done, info
    obs = step1["observation"] # {cpu_util, rps, instances, traffic, currentTime}
    reward = step1["reward"] # {total, components: {performance, cost, stability, sla}, metrics}
    # 3. Ramp window (steps 1-4): ACU warming up — cpu_util == 0, cost at minCapacity floor.
    # Only count cost + stability reward components to avoid false latency penalties.
    result = step1
    for _ in range(4):
    result = client.rl_step(env_id, action={
    "type": "adjust_threshold",
    "parameters": {"cpuThreshold": 70},
    })
    obs = result["observation"]
    rc = result["reward"]["components"]
    adj_reward = rc["cost"] + rc["stability"]
    print(f"Ramp cpu_util={obs['cpu_util']:.3f} adj_reward={adj_reward:.3f}")
    # 4. Steady-state training loop — all four reward components now meaningful.
    done = result["done"]
    while not done:
    result = client.rl_step(env_id, action={
    "type": "adjust_threshold",
    "parameters": {"cpuThreshold": 70},
    })
    done = result["done"]
    obs = result["observation"]
    rw = result["reward"]
    print(f"Train cpu_util={obs['cpu_util']:.3f} "
    f"cost_usd_hr={rw['metrics']['costPerHour']:.4f} "
    f"reward={rw['total']:.3f}")
    # 5. Reset for the next episode.
    client.rl_reset(env_id)

    TypeScript / JS SDK

    canvascloudai/cwm-ts-sdk

    Typed Node.js client with full IDE autocomplete, uses native fetch

    Install
    Bash
    npm install "github:canvascloudai/cwm-ts-sdk"
    Create simulation → simulate step → read metrics
    JavaScript
    import { CwmClient } from "@cwm/sdk";
    const client = new CwmClient({
    baseUrl: "https://cloudworldmodel.ai",
    apiKey: "your_api_key_here",
    });
    // 1. Create a simulation
    const sim = await client.createSimulation({
    name: "prod-replica",
    resources: [
    {
    id: "web",
    type: "compute",
    name: "Web Server",
    provider: "aws",
    characteristics: { size: "t3.medium" },
    },
    ],
    });
    // 2. Run a simulation step and read metrics
    const result = await client.simulateStep(sim.id, { traffic: 1500 });
    console.log(result.metrics.cpuUsage); // e.g. 0.72
    console.log(result.metrics.latencyP95); // e.g. 143.2
    console.log(result.metrics.costPerHour); // e.g. 0.0464
    Aurora Serverless RL episode loop
    aurora-serverless

    Full episode loop using the SDK's higher-level interface — mirrors the Aurora Serverless quickstart without raw HTTP calls.

    JavaScript
    import { CwmClient } from "@cwm/sdk";
    const client = new CwmClient({
    baseUrl: "https://www.cloudworldmodel.ai/api",
    apiKey: "your_api_key_here",
    });
    // 1. Create an RL environment linked to a simulation that already contains
    // at least one AWS database resource (the engine clones it for the episode).
    const { environment } = await client.createRlEnvironment("<sim-id>", {
    episodeConfig: { maxSteps: 40 },
    });
    const envId = environment.id;
    // 2. add_resource action — adds an Aurora Serverless v2 database to the sim.
    // The engine models a 2-4 step ACU scale-out delay for aurora-serverless targets.
    let step1 = await client.rlStep(envId, {
    action: { type: "add_resource", parameters: { resourceType: "database", provider: "aws" } },
    tick_seconds: 60,
    });
    // Response keys: t, obs, metrics, reward, reward_components, done
    let { t, obs, metrics } = step1; // t=1 after first action
    // obs: {cpu_util, rps, instances, traffic, currentTime}
    // metrics: {cost_usd_hr, latency_p95, error_rate, uptime, sla_violations}
    // 3. Ramp window (t = 1-4): obs.cpu_util === 0, metrics.cost_usd_hr at minCapacity floor (~$0.06/hr).
    // Only count cost + stability reward components — skip performance and sla during ACU ramp-up.
    const RAMP_STEPS = 4;
    let result = step1;
    for (let i = 0; i < RAMP_STEPS; i++) {
    result = await client.rlStep(envId, {
    action: { type: "adjust_threshold", parameters: { cpuThreshold: 70 } },
    tick_seconds: 60,
    });
    ({ t, obs, metrics } = result);
    const rc = result.reward_components;
    const adjustedReward = rc.cost + rc.stability;
    console.log(`Ramp t=${String(t).padStart(2)} cpu_util=${obs.cpu_util.toFixed(3)} ` +
    `cost_usd_hr=${metrics.cost_usd_hr.toFixed(4)} adj_reward=${adjustedReward.toFixed(3)}`);
    }
    // 4. Steady-state training loop — all four reward components are now meaningful.
    // metrics.cost_usd_hr climbs over 3-6 steps toward the ACU-proportional steady-state rate.
    let done = result.done;
    while (!done) {
    result = await client.rlStep(envId, {
    action: { type: "adjust_threshold", parameters: { cpuThreshold: 70 } },
    tick_seconds: 60,
    });
    ({ t, obs, metrics } = result);
    const reward = result.reward;
    done = result.done;
    console.log(`Train t=${String(t).padStart(2)} cpu_util=${obs.cpu_util.toFixed(3)} ` +
    `latency_p95=${metrics.latency_p95.toFixed(0)}ms ` +
    `cost_usd_hr=${metrics.cost_usd_hr.toFixed(4)} reward=${reward.toFixed(3)}`);
    }
    // 5. Reset for the next episode.
    await client.rlReset(envId);

    Script any workflow from the terminal — no code required

    Install
    Bash
    # Install globally from GitHub
    npm install -g "github:canvascloudai/cwm-cli"
    # Verify
    cwm --help
    cwm --help output
    Bash
    Usage: cwm <command> [options]
    Commands:
    config Manage CLI configuration (set, show)
    simulate Simulation management (create, get, list, step)
    rl RL environment interactions (create, step, reset)
    chaos Chaos engineering (scenarios, run, status, results)
    multicloud Strategy exploration (explore, status, results)
    keys API key management (create, list, revoke)
    Options:
    --base-url <url> CWM server URL (overrides config)
    --api-key <key> API key (overrides config)
    --output <format> Output format: text | json
    -h, --help Display help for a command
    Key workflows
    Bash
    # Point the CLI at our server and set your key (saved to ~/.cwm/config.json)
    cwm config set --base-url https://cloudworldmodel.ai
    cwm config set --api-key your_api_key_here
    # Create a simulation from a JSON spec file
    cwm simulate create --file sim-spec.json
    # Run a simulation step (optionally inject traffic)
    cwm simulate step <sim-id> --traffic 1500
    # List all simulations
    cwm simulate list
    # Run a chaos scenario
    cwm chaos run <sim-id> --scenario zone_failure --duration 300
    # Advance an RL environment
    cwm rl step <env-id> scale_up
    # Explore multi-cloud strategies (pass a workload JSON file)
    cwm multicloud explore --file workload.json

    After creating an RL environment with cwm rl, you can inspect live episode progress, cumulative rewards, and environment health in the RL Environment Status viewer.

    Aurora Serverless RL episode loop
    aurora-serverless

    Full episode loop using shell commands — mirrors the Aurora Serverless quickstart without writing any code.

    Bash
    # 0. Save your key once; the CLI reads it automatically from ~/.cwm/config.json.
    cwm config set --api-key your_api_key_here
    # 1. Create an RL environment linked to a simulation that already contains
    # at least one AWS database resource (the engine clones it for the episode).
    ENV_ID=$(cwm rl create <sim-id> --max-steps 40 --output json | jq -r '.environment.id')
    # 2. add_resource action — adds an Aurora Serverless v2 database to the sim.
    # cwm rl step passes no action parameters, so use curl for this parameterized step.
    # The engine models a 2-4 step ACU scale-out delay for aurora-serverless targets.
    curl -s -X POST https://www.cloudworldmodel.ai/api/rl/environments/$ENV_ID/step \
    -H "Authorization: Bearer your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{"action":{"type":"add_resource","parameters":{"resourceType":"database","provider":"aws"}}}' \
    | jq '{obs: .obs, reward: .reward, done: .done}'
    # Response keys: obs {cpu_util, rps, instances, traffic, currentTime},
    # reward (total scalar), reward_components {performance,cost,stability,sla},
    # metrics {cost_usd_hr, latency_p95, error_rate}, done
    # 3. Ramp window (steps 1-4): ACU warming up — obs.cpu_util == 0, cost at minCapacity floor.
    # Only cost + stability reward components are meaningful during ACU ramp-up.
    for i in 1 2 3 4; do
    cwm rl step $ENV_ID adjust_threshold --output json \
    | jq '{cpu_util: .obs.cpu_util, adj_reward: (.reward_components.cost + .reward_components.stability)}'
    done
    # 4. Steady-state training loop — all four reward components are now meaningful.
    # Loop until the episode is done (done == true in the JSON response).
    while true; do
    RESULT=$(cwm rl step $ENV_ID adjust_threshold --output json)
    echo "$RESULT" | jq '{cpu_util: .obs.cpu_util, cost_usd_hr: .metrics.cost_usd_hr, reward: .reward}'
    DONE=$(echo "$RESULT" | jq -r '.done')
    [ "$DONE" = "true" ] && break
    done
    # 5. Reset for the next episode.
    cwm rl reset $ENV_ID

    Ready to get started?

    Get your API key in under two minutes — no waitlist, no credit card. If you have a Canvas Cloud AI account, you already have access.