Canonical twin runs
For new integrations, use client.twin_runs to create and manage standalone twin sessions on the current /twin-runs API:
result = client.twin_runs.create(
["stripe", "slack"],
ttl_minutes=60,
scenario_id="scenario-id", # optional
)
run_id = result["run_id"]
status = client.twin_runs.get(run_id)
client.twin_runs.extend(run_id, ttl_minutes=30)
client.twin_runs.lock(run_id)
client.twin_runs.teardown(run_id)
Legacy twin helpers
The Python SDK also keeps the older client.twins namespace for the /validate/twins/... quickstart endpoints.
List available twins
twins = client.twins.list()
for twin in twins:
print(twin.name, twin.label, twin.kind)
# e.g. "stripe", "Stripe", "frontend"
Provision a twin environment
Spin up standalone twins for agent testing or local development:
result = client.twins.provision(
twins=["stripe", "slack"],
ttl_minutes=60, # 1-480 minutes
scenario_id="scenario-uuid", # optional — pre-seed twin data from a saved scenario
)
run_id = result["run_id"]
Check provisioning status
status = client.twins.get_status(run_id)
print(status.status) # "provisioning", "ready", or "failed"
if status.status == "ready":
for name, twin in status.twins.items():
print(f"{name}: {twin.base_url}")
print(f" Admin: {twin.admin_url}")
print(f" Env vars: {twin.env_vars}")
Extend TTL
client.twins.extend(run_id, ttl_minutes=30)
Teardown
Immediately tear down a provisioned twin environment:
client.twins.teardown(run_id)
client.twins does not expose lock(). Use client.twin_runs.lock(run_id) when you need to revoke public access without tearing the session down.