Quickstart — launch a lab
Quickstart: launch a lab with the Scenario API
This walkthrough drives the Scenario API end-to-end to launch a lab from a scenario, follow its execution, and retrieve remote access — in cURL and Python. It mirrors what the official mantis CLI does under the hood (mantis_api_client/mantis_api_client/scenario_api.py).
Before you start, get an access token and your workspace id — see the Authentication guide.
export BASE="https://app.mantis-platform.io/api/scenario/lab"
export TOKEN="<your access token>"
export WORKSPACE_ID="<your workspace id>"Step 1 — Browse the catalog
List the scenarios available to you and pick one by name.
cURL
curl "$BASE/scenario/" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Workspace-Id: $WORKSPACE_ID"Python
import requests
BASE = "https://app.mantis-platform.io/api/scenario/lab"
TOKEN = "<your access token>"
WORKSPACE_ID = "<your workspace id>"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "X-Workspace-Id": WORKSPACE_ID}
scenarios = requests.get(f"{BASE}/scenario/", headers=HEADERS)
scenarios.raise_for_status()
for s in scenarios.json()["scenario_list"]:
print(s["name"])Step 2 — Launch the lab
POST /scenario/run_lab creates and starts the lab in one call (use /scenario/create_lab if you want to start it later). The body wraps a lab_config; the response is the new lab id.
cURL
curl -X POST "$BASE/scenario/run_lab?workspace_id=$WORKSPACE_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Workspace-Id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"lab_config": {
"content_type": "KILLCHAIN",
"content_name": "<scenario-name-from-step-1>",
"scenario_profile": "default",
"max_duration": 3600
}
}'Python
lab_config = {
"content_type": "KILLCHAIN", # KILLCHAIN | ATTACK | TOPOLOGY | BASEBOX | BAS | DFIR
"content_name": "<scenario-name-from-step-1>",
"scenario_profile": "default",
"max_duration": 3600, # seconds; 0 = no timeout
}
resp = requests.post(
f"{BASE}/scenario/run_lab",
params={"workspace_id": WORKSPACE_ID},
json={"lab_config": lab_config},
headers=HEADERS,
)
resp.raise_for_status()
lab_id = resp.json()
print("Lab launched:", lab_id)Step 3 — Follow the execution
Poll GET /runner/{lab_id} until the lab reaches RUNNING (or a terminal state).
cURL
curl "$BASE/runner/$LAB_ID" -H "Authorization: Bearer $TOKEN"Python
import time
while True:
r = requests.get(f"{BASE}/runner/{lab_id}", headers=HEADERS)
r.raise_for_status()
status = r.json().get("status")
print("status:", status)
if status in ("RUNNING", "ERROR", "STOPPED"):
break
time.sleep(10)Step 4 — Get remote access
Once running, retrieve the connection info for the deployed machines.
cURL
curl "$BASE/runner/$LAB_ID/remote_access" -H "Authorization: Bearer $TOKEN"Python
access = requests.get(f"{BASE}/runner/{lab_id}/remote_access", headers=HEADERS)
access.raise_for_status()
print(access.json())Step 5 — Stop and clean up
# Stop execution
curl "$BASE/runner/$LAB_ID/stop" -H "Authorization: Bearer $TOKEN"
# Delete the lab
curl -X DELETE "$BASE/runner/$LAB_ID" -H "Authorization: Bearer $TOKEN"Full script
import time
import requests
BASE = "https://app.mantis-platform.io/api/scenario/lab"
TOKEN = "<your access token>"
WORKSPACE_ID = "<your workspace id>"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "X-Workspace-Id": WORKSPACE_ID}
def launch_scenario(name: str, profile: str = "default") -> str:
lab_config = {
"content_type": "KILLCHAIN",
"content_name": name,
"scenario_profile": profile,
"max_duration": 3600,
}
resp = requests.post(
f"{BASE}/scenario/run_lab",
params={"workspace_id": WORKSPACE_ID},
json={"lab_config": lab_config},
headers=HEADERS,
)
resp.raise_for_status()
return resp.json()
def wait_running(lab_id: str) -> str:
while True:
status = requests.get(f"{BASE}/runner/{lab_id}", headers=HEADERS).json()["status"]
if status in ("RUNNING", "ERROR", "STOPPED"):
return status
time.sleep(10)
if __name__ == "__main__":
scenarios = requests.get(f"{BASE}/scenario/", headers=HEADERS).json()["scenario_list"]
name = scenarios[0]["name"]
lab_id = launch_scenario(name)
print("Launched", lab_id, "->", wait_running(lab_id))
print(requests.get(f"{BASE}/runner/{lab_id}/remote_access", headers=HEADERS).json())Where to go next
- Full endpoint reference: the Scenario API reference (every endpoint has cURL + Python samples).
- Authentication guide for token handling.

