Skip to content

Deployments API

The Deployments API lets your own systems run Rogue Arena labs end to end: deploy a scenario, wait for it to come up, run commands on its VMs, snapshot and revert, issue guest links, and tear it down. Use it to wire labs into an LMS, a hiring pipeline, a CI job, or an AI agent.

It uses the same API keys as the rest of the External API. Anyone with the API Key Use permission creates a personal key in Team Hub → External API and picks the deployment permissions below.

PermissionLabel in Team HubGrants
deployments:readView deploymentsDeployable scenarios, your deployments, their progress, VMs, and snapshots
deployments:lifecycleManage deploymentsDeploy, tear down, power on and off, revert to a snapshot
deployments:vmsControl VMsRun scripts, read files and folders, search files, list processes, take screenshots, send mouse and keyboard input, VM snapshots, copy files between VMs
deployments:guest-linksGuest linksCreate, list, and revoke guest links
deployments:vpnVPN configsCreate and download VPN configs

A key acts as the person who created it. It can only deploy scenarios that person can deploy, and it’s held to their permissions: deploying for a teammate needs the Lab Admin permission, and VPN configs need VPN access. Every download of a VPN config issues a fresh credential.

1. Find a scenario.

Terminal window
curl --fail-with-body \
--header "Authorization: Bearer $ROGUE_ARENA_TEAM_API_KEY" \
"https://arena.roguelabs.io/api/v1/deployable-scenarios"

Each scenario has a scenarioId, a name, and its published versions.

2. Deploy it. Send a new UUID v4 in Idempotency-Key. If the request is retried with the same key, you get the same deployment back, never a second one.

Terminal window
curl --fail-with-body \
--request POST \
--header "Authorization: Bearer $ROGUE_ARENA_TEAM_API_KEY" \
--header "Idempotency-Key: $(uuidgen | tr 'A-Z' 'a-z')" \
--header "Content-Type: application/json" \
--data '{"scenarioId": "<scenarioId>"}' \
"https://arena.roguelabs.io/api/v1/deployments"

A 202 returns the new deploymentId. Optional fields: versionNumber to pin a version (latest by default) and ownerUserId to deploy for a teammate.

Deployments go through the same capacity and billing checks as deploying in the browser. If your organization has no room, you get a 409 with an admission object explaining why.

3. Wait until it’s ready. Poll the progress endpoint until readiness is ready:

Terminal window
curl --fail-with-body \
--header "Authorization: Bearer $ROGUE_ARENA_TEAM_API_KEY" \
"https://arena.roguelabs.io/api/v1/deployments/<deploymentId>/progress"

readiness is one of deploying, ready, failed, stopped, or removing. pendingTasks lists what’s still running.

4. Work with the VMs. List them with GET /api/v1/deployments/<deploymentId>/vms, then run a script on one:

Terminal window
curl --fail-with-body \
--request POST \
--header "Authorization: Bearer $ROGUE_ARENA_TEAM_API_KEY" \
--header "Content-Type: application/json" \
--data '{"script": "whoami && hostname", "shell": "bash", "timeoutSeconds": 60}' \
"https://arena.roguelabs.io/api/v1/deployments/<deploymentId>/vms/<vmId>/scripts"

The response has output, exitCode, executionTimeMs, and truncated. Shells are bash, sh, powershell, and python3. Scripts can run up to 600 seconds.

5. Tear it down with DELETE /api/v1/deployments/<deploymentId>.

All paths start with https://arena.roguelabs.io/api/v1. {d} is /deployments/{deploymentId} and {v} is {d}/vms/{vmId}.

EndpointPurposePermission
GET /deployable-scenariosScenarios this key can deploydeployments:read
GET /deploymentsYour deployments; ?relationship=owned, shared, or teamdeployments:read
POST /deploymentsDeploy a scenariodeployments:lifecycle
GET {d}One deployment’s status and readinessdeployments:read
DELETE {d}Tear down a deploymentdeployments:lifecycle
GET {d}/progressReadiness and pending tasksdeployments:read
POST {d}/powerPower the whole deployment on or offdeployments:lifecycle
GET {d}/snapshotsDeployment-wide snapshotsdeployments:read
POST {d}/revertRevert the deployment to a snapshotdeployments:lifecycle
GET {d}/vmsVMs in the deploymentdeployments:read
GET {v}/accessA VM’s IP address and logindeployments:vms
POST {v}/powerPower one VM on or offdeployments:vms
POST {v}/scriptsRun a script and get its outputdeployments:vms
GET {v}/directory, GET {v}/fileList a folder or read a file (head, tail, or range)deployments:vms
POST {v}/file/grepSearch inside a filedeployments:vms
GET {v}/processesRunning processes, optionally filtered by namedeployments:vms
GET {v}/screenshotCapture the VM’s screendeployments:vms
POST {v}/inputSend clicks, mouse moves, and keystrokesdeployments:vms
POST {v}/snapshots, POST {v}/snapshots/{id}/revert, DELETE {v}/snapshots/{id}Take, revert, and delete VM snapshotsdeployments:vms
POST {d}/file-copies, GET {d}/file-copies/{transferId}Copy files between VMs and check progressdeployments:vms
GET {d}/guest-links, POST {d}/guest-links, DELETE {d}/guest-links/{linkId}, POST {d}/guest-links/revoke-allManage guest linksdeployments:guest-links
GET {d}/vpn-configs, POST {d}/vpn-configs, POST {d}/vpn-configs/{configId}/downloadManage and download VPN configsdeployments:vpn

The full request and response schemas are in a separate OpenAPI 3.1 document.

Errors use the same envelope, rate limits, and retry advice as the rest of the API; see Pagination, Rate Limits, and Errors. A 409 on deploy can carry an admission object instead of a plain error when capacity or billing stopped the deployment.

Treat a key with deployments:vms like a password to every lab it can reach: it can run any command on those VMs.