Canonical twin runs
For new integrations, use client.twinRuns to create and manage standalone twin sessions on the current /twin-runs API:
const result = await client.twinRuns.create({
twins: ['stripe', 'slack'],
ttlMinutes: 60,
scenarioId: 'scenario-id', // optional
});
const runId = result.runId;
const status = await client.twinRuns.get(runId);
await client.twinRuns.extend(runId, { ttlMinutes: 30 });
await client.twinRuns.lock(runId);
await client.twinRuns.teardown(runId);
Legacy twin helpers
The TypeScript SDK also keeps the older client.twins namespace for the /validate/twins/... quickstart endpoints.
List available twins
const twins = await client.twins.list();
for (const twin of twins) {
console.log(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:
const { runId } = await client.twins.provision({
twins: ['stripe', 'slack'],
ttlMinutes: 60, // 1-480 minutes
scenarioId: 'scenario-uuid', // optional — pre-seed twin data
});
Check provisioning status
const status = await client.twins.getStatus(runId);
console.log(status.status); // "provisioning", "ready", or "failed"
if (status.status === 'ready') {
for (const [name, twin] of Object.entries(status.twins)) {
console.log(`${name}: ${twin.baseUrl}`);
console.log(` Admin: ${twin.adminUrl}`);
console.log(` Env vars:`, twin.envVars);
}
}
Extend TTL
await client.twins.extend(runId, { ttlMinutes: 30 });
Teardown
Immediately tear down a provisioned twin environment:
await client.twins.teardown(runId);
client.twins does not expose lock(). Use client.twinRuns.lock(runId) when you need to revoke public access without tearing the session down.