> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getsupervisor.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Integra la Public API usando @getsupervisor/agents-studio-sdk, con ejemplos prácticos y convenciones recomendadas.

> Todo lo que necesitas para consumir la Public API desde Node.js o el navegador usando nuestro SDK oficial.

## Instalación

<CodeGroup>
  ```bash npm theme={null}
  npm install @getsupervisor/agents-studio-sdk
  ```

  ```bash yarn theme={null}
  yarn add @getsupervisor/agents-studio-sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @getsupervisor/agents-studio-sdk
  ```
</CodeGroup>

## Configura el cliente

Define tus variables de entorno (usa el nuevo dominio productivo).

```bash theme={null}
export API_BASE_URL="https://api-prod.studio.getsupervisor.ai/v1"
export WORKSPACE_ID="00000000-1111-2222-3333-444455556666"
export API_KEY="sk_live_..."
```

Crea un helper `client.ts` para reutilizar en tu aplicación:

```ts theme={null}
import { createClient } from '@getsupervisor/agents-studio-sdk';

export const client = createClient({
  baseUrl: process.env.API_BASE_URL!,
  workspaceId: process.env.WORKSPACE_ID!,
  apiKey: process.env.API_KEY!,
  retry: { maxRetries: 2, baseDelayMs: 300 },
});

// Cambia de workspace en caliente: client.workspace.set('ws-otro');
// Usa API Keys si prefieres: client.auth.setApiKey('sk_live_...');
```

<Note>
  Define `apiKey` en la configuración inicial o usa
  `client.auth.setApiKey('sk_...')` para rotarla en caliente. El SDK enviará el
  header `X-API-Key` automáticamente.
</Note>

## Operaciones frecuentes

### Listar agentes

```ts theme={null}
import { client } from './client';

const agents = await client.agents.list({
  limit: 10,
  filter: { status: 'active' },
});

agents.data.forEach((item) => {
  console.log(`${item.agentId}: ${item.name} (${item.agentType})`);
});

if (agents.meta.hasNext) {
  const nextPage = await agents.next();
  console.log(`Total acumulado: ${nextPage.meta.total}`);
}
```

### Crear y actualizar agentes

```ts theme={null}
import { client } from './client';

const draft = await client.agents.create({
  name: 'Onboarding Bot',
  agentType: 'chat',
  description: 'Acompaña a nuevos usuarios durante su primera semana.',
});

await client.agents.update(draft.agentId, {
  status: 'active',
  metadata: { onboardingFlow: 'welcome-series' },
});
```

### Versiones, instrucciones y horarios

```ts theme={null}
import { client } from './client';

const agentId = '11111111-2222-3333-4444-555555555555';

const version = await client.agentVersions.create(agentId);
await client.agentVersions.createInstruction(agentId, version.id, {
  order: 0,
  content: 'Saluda con empatía y confirma el objetivo de la conversación.',
});
await client.agentVersions.publish(agentId, version.id, {
  notes: 'Versión inicial productiva',
});

await client.agentSchedule.create(agentId, {
  timezone: 'America/Mexico_City',
  isEnabled: true,
  monday: { enabled: true, start: '09:00', end: '18:00' },
  tuesday: { enabled: true, start: '09:00', end: '18:00' },
  wednesday: { enabled: true, start: '09:00', end: '18:00' },
  thursday: { enabled: true, start: '09:00', end: '18:00' },
  friday: { enabled: true, start: '09:00', end: '18:00' },
  saturday: { enabled: false },
  sunday: { enabled: false },
  outOfHoursBehavior: 'offline',
  outOfHoursMessage: 'Fuera de horario, te contactaremos en cuanto volvamos.',
});
```

### Stages y triggers del blueprint

```ts theme={null}
const stages = client.agents.stages(agentId);
const { data } = await client.agents.blueprints(agentId).list();
const blueprintId = data[0].blueprint.blueprintId;

const listing = await stages.list(blueprintId, { limit: 10 });
console.log(listing.meta.total);

const blueprintStages = stages(blueprintId);

const created = await blueprintStages.create({
  name: 'proposal',
  goalPrompt: 'Explica la solución recomendada y ofrece agendar una demo.',
  order: 2,
});

await stages.triggers(blueprintId, created.id).create({
  condition: { type: 'intent', value: 'schedule_call' },
  nextStageName: 'handoff',
});

await stages.reorder(blueprintId, {
  stageIds: listing.data.map((stage) => stage.id),
  startingStageName: 'greeting',
});
```

Los helpers devuelven los métodos `list`, `get`, `create`, `update`, `delete`, `reorder` y `triggers(stageId)` (con `list`, `get`, `create`, `update`, `delete` para cada trigger).

### Conectar la tool `voice.calls`

```ts theme={null}
import { client } from './client';

const connection = await client.tools.connect('voice.calls', {
  workspaceId: client.workspace.get()!,
  agentId: '11111111-2222-3333-4444-555555555555',
  metadata: {
    reason: 'demo-outbound',
    expectedOutcome: 'confirmar cita',
  },
});

console.log(connection.status); // connected o pending
console.log(connection.descriptionUsage);
console.log(connection.usageExample);
```

### Ejecutar `voice.calls.startCall`

```ts theme={null}
import { client } from './client';

await client.tools.execute('voice.calls', {
  workspaceId: client.workspace.get()!,
  agentId: '11111111-2222-3333-4444-555555555555',
  action: 'startCall',
  args: {
    to: '+525500000000',
    metadata: { reason: 'confirmar cita', customerId: 'cust-789' },
  },
});
```

### API Keys y autenticación

```ts theme={null}
import { client } from './client';

const created = await client.apiKeys.create({
  name: 'Backend Integration',
  environment: 'production',
  scopes: ['agents:read', 'tools:execute'],
});

const revealed = await client.apiKeys.show(created.id);
console.log(revealed.key); // se muestra una sola vez

await client.apiKeys.revoke(created.id);
```

### Webhooks y suscripciones

```ts theme={null}
import { client } from './client';

const webhook = await client.webhooks.create({
  name: 'Voice events',
  url: 'https://example.com/webhooks/voice',
  description: 'Eventos de llamadas de voz',
});

await client.webhooks.subscriptions.create(webhook.id, {
  eventType: 'tools.voice.calls.execute',
});
```

## Manejo de errores e idempotencia

```ts theme={null}
import { client } from './client';
import {
  HttpError,
  NetworkError,
  TimeoutError,
} from '@getsupervisor/agents-studio-sdk';

try {
  await client.tools.execute(
    'voice.calls',
    {
      workspaceId: client.workspace.get()!,
      agentId: '11111111-2222-3333-4444-555555555555',
      action: 'startCall',
      args: { to: '+525500000000' },
    },
    { idempotencyKey: `voice-${Date.now()}` },
  );
} catch (error) {
  if (error instanceof HttpError) {
    console.error('HTTP error', error.status, error.body);
  } else if (error instanceof TimeoutError) {
    console.error('Timeout: reintenta o amplía el timeout');
  } else if (error instanceof NetworkError) {
    console.error('Problema de red, el SDK reintentará según tu política');
  } else {
    throw error;
  }
}
```

## Ejemplo completo: CRUD de agentes

```ts theme={null}
import { createClient } from '@getsupervisor/agents-studio-sdk';

async function main() {
  const client = createClient({
    baseUrl: process.env.API_BASE_URL!,
    workspaceId: process.env.WORKSPACE_ID!,
    apiKey: process.env.API_KEY!,
  });

  // Crear un agente temporal
  const agent = await client.agents.create({
    name: 'Demo Onboarding',
    agentType: 'chat',
    description: 'Integra nuevos usuarios durante su primera semana.',
  });

  // Actualizar metadatos clave
  await client.agents.update(agent.agentId, {
    status: 'active',
    metadata: { campaign: 'onboarding-q4' },
  });

  // Obtener listado paginado
  const list = await client.agents.list({ limit: 5 });
  list.data.forEach((item) => console.log(item.agentId, item.name));

  if (list.meta.hasNext) {
    const next = await list.next();
    console.log('Página 2:', next.data.length);
  }

  // Eliminar cuando termine la prueba
  await client.agents.delete(agent.agentId);
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
```

## Ejemplo completo: agente de voz productivo

```ts theme={null}
import { createClient } from '@getsupervisor/agents-studio-sdk';

async function bootstrapVoiceAgent() {
  const client = createClient({
    baseUrl:
      process.env.API_BASE_URL ?? 'https://api-prod.studio.getsupervisor.ai/v1',
    workspaceId: process.env.WORKSPACE_ID!,
    apiKey: process.env.API_KEY!,
    retry: { maxRetries: 2 },
  });

  const voiceTool = await client.tools
    .list({ agentType: 'voice', limit: 10 })
    .then((page) =>
      page.data.find((tool) => tool.identifier === 'voice.calls'),
    );

  if (!voiceTool) {
    throw new Error('La tool voice.calls no está disponible en tu workspace.');
  }

  const agent = await client.agents.create({
    name: `Voice demo ${new Date().toISOString()}`,
    agentType: 'voice',
    status: 'inactive',
  });

  const version = await client.agentVersions.create(agent.agentId);

  const [language, messageStyle, toneStyle] = await Promise.all([
    client.catalogs.list({ limit: 10, filter: { type: 'language' } }),
    client.catalogs.list({ limit: 10, filter: { type: 'message_style' } }),
    client.catalogs.list({ limit: 10, filter: { type: 'tone_style' } }),
  ]);

  const pickActive = (page: typeof language) =>
    page.data.find((item) => item.isActive)?.id;

  await client.agents
    .blueprints(agent.agentId)
    .version(version.id)
    .create({
      languageId: pickActive(language)!,
      personalityName: 'Ava',
      personalityRole: 'Voice concierge',
      targetAudience: 'Clientes con dudas rápidas',
      mainGoal: 'Resolver preguntas comunes y escalar cuando sea necesario',
      personalityInitialGreeting:
        'Hola, soy Ava del equipo de soporte. ¿En qué puedo ayudarte?',
      personalityMessageStyleId: pickActive(messageStyle)!,
      personalityToneStyleId: pickActive(toneStyle)!,
      criticalRules: ['Nunca compartas información sensible.'],
      topicsForbidden: ['Negociaciones legales', 'Recomendaciones médicas'],
    });

  await client.agentVersions.createInstruction(agent.agentId, version.id, {
    order: 0,
    content:
      'Saluda con empatía, confirma el motivo de la llamada y ofrece opciones breves antes de escalar.',
  });

  await client.tools.connect(voiceTool.identifier, {
    workspaceId: client.workspace.get()!,
    agentId: agent.agentId,
    metadata: { escenario: 'demo-voice' },
    auth: { type: 'none' },
  });

  await client.agentVersions.publish(agent.agentId, version.id, {
    notes: 'Primera versión con tool voice.calls configurada automáticamente.',
  });
}

bootstrapVoiceAgent().catch((error) => {
  console.error(error);
  process.exit(1);
});
```

## Scopes disponibles (octubre 2025)

| Scope                      | Permiso principal                                                         |
| -------------------------- | ------------------------------------------------------------------------- |
| `agents:read`              | Listar y consultar agentes del workspace.                                 |
| `agents:write`             | Crear/actualizar/eliminar agentes y gestionar su configuración operativa. |
| `agent-versions:read`      | Listar y consultar versiones de un agente.                                |
| `agent-versions:write`     | Crear, clonar, restaurar y publicar versiones de un agente.               |
| `agent-instructions:read`  | Leer instrucciones (a nivel agente y por versión).                        |
| `agent-instructions:write` | Crear, actualizar o borrar instrucciones personalizadas.                  |
| `agent-blueprints:read`    | Consultar el blueprint (personalidad) de una versión de agente.           |
| `agent-blueprints:write`   | Editar blueprint: personalidad, reglas, audiencia, objetivos, etc.        |
| `blueprint-stages:read`    | Listar y consultar stages del blueprint.                                  |
| `blueprint-stages:write`   | Crear, actualizar o reordenar stages del blueprint.                       |
| `stage-triggers:read`      | Consultar triggers que conectan stages y sus condiciones.                 |
| `stage-triggers:write`     | Crear, actualizar o eliminar triggers entre stages.                       |
| `agent-schedules:read`     | Consultar horario semanal y excepciones vigentes.                         |
| `agent-schedules:write`    | Crear o modificar horarios y excepciones.                                 |
| `campaigns:read`           | Consultar campañas y sus ejecuciones.                                     |
| `campaigns:write`          | Crear y disparar campañas batch.                                          |
| `calls:read`               | Consultar llamadas (Speech Analytics) del workspace.                      |
| `catalogs:read`            | Navegar catálogos globales y por workspace (idiomas, tonos, voces, etc.). |
| `catalogs:write`           | Registrar o ajustar ítems de catálogo.                                    |
| `tools:read`               | Descubrir tools disponibles, recursos y capacidades declaradas.           |
| `tools:connections:read`   | Listar conexiones configuradas entre agentes y tools.                     |
| `tools:connections:write`  | Crear o actualizar conexiones entre agentes y tools.                      |
| `tools:execute`            | Ejecutar acciones de una tool.                                            |
| `webhooks:read`            | Listar webhooks y sus suscripciones activas.                              |
| `webhooks:write`           | Crear, actualizar o eliminar webhooks y suscripciones.                    |
| `api-keys:read`            | Listar credenciales existentes y revelar su valor.                        |
| `api-keys:write`           | Emitir o revocar API Keys.                                                |
| `workspaces:read`          | Consultar workspaces disponibles y sus metadatos.                         |

Consulta el archivo OpenAPI local (`openapi/public-api.yaml`) para validar scopes adicionales y revisa la guía de API Keys en [`./keys`](./keys) para recomendaciones de seguridad.

## Recursos adicionales

* Revisa la guía MCP en [`./mcp`](./mcp) para combinar tools con agentes desde el Protocolo de Contexto de Modelo.
* Usa la referencia OpenAPI (`/openapi/public-api.yaml`) para navegar los modelos y respuestas HTTP.
* En la carpeta `snippets/` de esta documentación encontrarás fragmentos reutilizables listos para copiar en tus integraciones.
