Skip to main content

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.