# SDK de JavaScript

> El SDK GTM más completo - 25+ módulos para seguimiento, inteligencia de visitantes, AI Copilot, webchat, reservas, enriquecimiento, secuencias, campañas, CRUD de CRM y más

Source: https://docs.graph8.com/es/developers/sdk/

El SDK `@graph8/sdk` le da acceso tipado a todas las funcionalidades de graph8 desde cualquier proyecto JavaScript o TypeScript. 25+ módulos, una sola llamada `g8.init()`.

> **Tip:**
> Pruebe el nivel de desarrollador gratis - 1.000 créditos, sin necesidad de tarjeta. [Comience aquí](https://auth.graph8.com/en/signup).
>
> Agentes de IA: obtenga el índice completo de documentación en [https://docs.graph8.com/llms.txt](https://docs.graph8.com/llms.txt).

## Instalación

```bash
npm install @graph8/sdk
```

## Modos de autenticación

El SDK ofrece dos modos de autenticación según lo que esté desarrollando:

| Modo | Clave | Caso de uso | ¿Seguro en el navegador? |
|------|-------|-------------|--------------------------|
| **Del lado del cliente** | `writeKey` | Seguimiento, identificación de visitantes, Copilot, chat, calendario, formularios | Sí |
| **Del lado del servidor** | `apiKey` | Enriquecimiento, secuencias, campañas, integraciones, voz, páginas | No |

```typescript
// Client-side (browser)
g8.init({ writeKey: 'YOUR_WRITE_KEY' });

// Server-side (Node.js)
g8.init({ apiKey: 'YOUR_API_KEY' });

// Both (full access)
g8.init({ writeKey: 'YOUR_WRITE_KEY', apiKey: 'YOUR_API_KEY' });
```

## Inicio rápido

> **Note: CDP integrado**
> Cada llamada `g8.track()` e `g8.identify()` se almacena automáticamente en el CDP integrado de graph8. Los contactos, el enriquecimiento, las secuencias y las campañas funcionan de inmediato. Opcionalmente, envíe una copia a su propio almacén de datos (BigQuery, Snowflake, etc.) a través de [Destinos](https://docs.graph8.com/developers/destinations/). Consulte [Pipeline de datos](https://docs.graph8.com/developers/data-pipeline/).

```typescript
import { g8 } from '@graph8/sdk';

g8.init({ writeKey: 'YOUR_WRITE_KEY' });

// Track events
g8.track('signup', { plan: 'pro', source: 'landing_page' });

// Identify users
g8.identify('user@acme.com', {
  name: 'Jane Smith',
  company: 'Acme Corp',
  job_title: 'VP Engineering',
});

// Know who's visiting
const visitor = await g8.visitors.identify();
// { company_name: 'Acme Corp', industry: 'SaaS', employee_count: '200-500' }

// Open AI copilot
g8.copilot.open({ greeting: 'How can I help?' });

// Show booking widget
g8.calendar.show({ username: 'thomas', eventType: 'demo-30min' });
```

## React / Next.js

```tsx
// app/layout.tsx
import { G8Provider } from '@graph8/sdk/react';

export default function RootLayout({ children }) {
  return (
    <G8Provider writeKey="YOUR_WRITE_KEY">
      {children}
    </G8Provider>
  );
}
```

```tsx
// Any component
import { useG8 } from '@graph8/sdk/react';

function PricingPage() {
  const { track, visitors, copilot, calendar } = useG8();

  useEffect(() => {
    visitors.identify().then(v => {
      if (v.company_name) setCompany(v.company_name);
    });
  }, []);

  return (
    <button onClick={() => {
      track('book_demo', { page: 'pricing' });
      calendar.show({ username: 'thomas', eventType: 'demo' });
    }}>
      Book a Demo
    </button>
  );
}
```

El hook devuelve: `track`, `identify`, `page`, `reset`, `visitors`, `copilot`, `chat`, `calendar`, `forms`, `signals` y `g8` (el cliente completo).

---

## Inteligencia de visitantes

Identifique a los visitantes anónimos por dirección IP: sepa qué empresa está en su sitio antes de que completen un formulario.

```typescript
// Resolve visitor's company
const visitor = await g8.visitors.identify();
// {
//   company_name: 'Acme Corp',
//   company_domain: 'acme.com',
//   industry: 'SaaS',
//   employee_count: '200-500',
//   city: 'San Francisco',
//   country: 'United States',
//   confidence: 0.92
// }

// Get engagement score
const score = await g8.visitors.score();
// { engagement: 82, intent: 'high', signals: ['pricing_page', 'case_study'] }

// React to high-intent visitors in real-time
const stop = g8.visitors.onIntent('high', (visitor) => {
  showBanner(`${visitor.company_name} is checking us out!`);
  g8.copilot.open(); // proactively open copilot
});

// Stop listening
stop();
```

---

## AI Copilot

Integre en su producto un asistente de IA que conoce la base de conocimiento de su organización.

```typescript
// Open as a floating widget
g8.copilot.open({
  greeting: 'Hi! How can I help you today?',
  position: 'bottom-right',  // or 'bottom-left'
  theme: 'dark',             // 'light', 'dark', or 'auto'
});

// Send a message programmatically
const answer = await g8.copilot.ask('What integrations do you support?');

// Register custom actions the AI can trigger
g8.copilot.registerAction('book_demo', async (params) => {
  router.push(`/book?date=${params.date}`);
});

// Listen for events
g8.copilot.on('tool_used', (data) => {
  analytics.track('copilot_action', data);
});

// Close
g8.copilot.close();
```

---

## Chat web

Chat en vivo y chat con IA integrados en su producto.

```typescript
// Open chat widget
g8.chat.open({
  position: 'bottom-right',
  theme: 'auto',
  greeting: 'Hi! Ask me anything.',
});

// Send a message
g8.chat.send('I need help with billing');

// Listen for events
g8.chat.on('message', (msg) => { /* new message from agent */ });
g8.chat.on('human_transfer', () => { /* transferred to human */ });

// Configure appearance
g8.chat.configure({
  position: 'bottom-left',
  avatar: '/logo.png',
});

// Close
g8.chat.close();
```

---

## Reserva de calendario

Integre la programación de citas directamente en su producto, sin redirigir a Calendly.

```typescript
// Show as a modal overlay
g8.calendar.show({
  username: 'thomas',
  eventType: 'demo-30min',
  prefill: { name: 'Jane', email: 'jane@acme.com' },
});

// Embed inline in a container
g8.calendar.embed('#booking-container', {
  username: 'thomas',
  eventType: 'discovery-call',
});

// Get available slots programmatically
const slots = await g8.calendar.slots('thomas', 'demo-30min', {
  start: '2026-04-07',
  end: '2026-04-11',
});

// Book programmatically
const booking = await g8.calendar.book({
  event_type_id: 123,
  slot: '2026-04-08T10:00:00Z',
  attendee: { name: 'Jane', email: 'jane@acme.com' },
});

// Listen for bookings
g8.calendar.on('booked', (booking) => {
  showConfirmation(booking);
});
```

---

## Formularios progresivos

Formularios inteligentes que omiten los campos que graph8 ya conoce: mayor conversión con los mismos datos.

```typescript
// Check what's already known
const result = await g8.forms.lookup('user@acme.com');

if (result.found) {
  console.log('Known:', result.known_fields);
  // { name: 'Jane Smith', company: 'Acme Corp' }

  console.log('Still need:', result.missing_fields);
  // ['phone', 'job_title']
}
```

---

## Enriquecimiento

> **Caution:**
> El enriquecimiento requiere una clave API (solo del lado del servidor). Nunca exponga su clave API en el código del navegador.

```typescript
// Initialize with API key
g8.init({ apiKey: 'YOUR_API_KEY' });

// Look up a person (2 credits, charged only when a match is found)
const person = await g8.enrich.person({ email: 'jane@acme.com' });
// { found: true, confidence: 0.95, data: { name, title, company, phone, linkedin, ... } }

// Look up a company (2 credits, charged only when a match is found)
const company = await g8.enrich.company({ domain: 'acme.com' });
// { found: true, data: { name, industry, revenue, headcount, tech_stack, ... } }

// Verify an email (1 credit)
const result = await g8.enrich.verifyEmail('jane@acme.com');
// { email: 'jane@acme.com', valid: true, deliverable: true, catch_all: false }

// Search 700M+ contacts with filters
const leads = await g8.enrich.search([
  { field: 'seniority_level', operator: 'any_of', value: ['VP', 'Director'] },
  { field: 'company_industry', operator: 'contains', value: ['SaaS'] },
  { field: 'company_employee_count', operator: 'between', value: [50, 500] },
], 1, 25);
```

---

## Señales de intención

Identifique cuándo las cuentas objetivo están activas en el mercado.

```typescript
// Get signals for a specific company
const signals = await g8.signals.company('acme.com');
// { domain: 'acme.com', score: 87, intent: 'high', signals: ['pricing_3x', 'case_study'] }

// Stream signals for multiple domains (polls every 30s)
const stop = g8.signals.stream(['acme.com', 'startup.io'], (signals) => {
  const hot = signals.filter(s => s.intent === 'high');
  if (hot.length > 0) notifySDR(hot);
});

// Stop streaming
stop();
```

> **Note:**
> Las señales funcionan tanto con la write key (pública, acceso limitado) como con la clave API (acceso completo).

---

## Secuencias

> **Caution:**
> Requiere clave API. Agregar contactos a una secuencia activa una prospección real.

```typescript
// List available sequences
const sequences = await g8.sequences.list();

// Add contacts to a sequence
await g8.sequences.add({
  sequenceId: sequences[0].id,
  contactIds: [5028106, 5028105],
  listId: 637,
});
```

---

## Campañas

> **Caution:**
> Requiere clave API. Iniciar una campaña envía mensajes reales.

```typescript
// List campaigns
const campaigns = await g8.campaigns.list();

// Create a campaign
const campaign = await g8.campaigns.create({
  name: 'Q2 Enterprise Push',
  category: 'Outbound',
  target_persona: 'VP Engineering at SaaS 200-1000',
});

// Launch
await g8.campaigns.launch(campaign.id);

// Get stats
const stats = await g8.campaigns.stats(campaign.id);
// { sent: 500, opened: 230, replied: 45, meetings: 12 }
```

---

## Contactos

> **Caution:**
> Requiere clave API. Opera sobre datos de CRM propios en su espacio de trabajo.

CRUD completo para los contactos de su espacio de trabajo de graph8: los mismos registros que alimentan las secuencias, las campañas y la sincronización con el CRM. Sin costo en créditos; estos endpoints solo leen y escriben datos que usted ya posee.

```typescript
import { g8 } from '@graph8/sdk';

g8.init({ apiKey: 'YOUR_API_KEY' });
```

### `list(params?)`

Lista contactos con filtros opcionales. Devuelve `{ data: Contact[]; total: number }`.

```typescript
const { data, total } = await g8.contacts.list({
  company_name: 'Acme Corp',
  seniority_level: 'VP',
  limit: 25,
  page: 1,
});
```

Campos filtrables: `email`, `name`, `job_title`, `seniority_level`, `company_name`, `country`, `list_id`, además de `page` y `limit`.

### `get(contactId)`

Obtiene un contacto individual por ID. Devuelve un `Contact`.

```typescript
const contact = await g8.contacts.get(5028106);
```

### `create(contact)`

Crea un contacto. `work_email` es obligatorio; todo lo demás es opcional. Pase `list_id` para agregar el contacto a una lista al mismo tiempo. Devuelve el `Contact` creado.

```typescript
const contact = await g8.contacts.create({
  work_email: 'jane@acme.com',
  first_name: 'Jane',
  last_name: 'Smith',
  job_title: 'VP Engineering',
  company_domain: 'acme.com',
  list_id: 637,
});
```

### `update(contactId, fields)`

Actualización parcial: envíe solo los campos que desea modificar. Devuelve `{ updated: number }`.

```typescript
await g8.contacts.update(5028106, {
  job_title: 'SVP Engineering',
  mobile_phone: '+14155551234',
});
```

### `delete(contactId)`

Eliminación lógica de un contacto. Devuelve `{ deleted: boolean }`.

```typescript
await g8.contacts.delete(5028106);
```

---

## Empresas

> **Caution:**
> Requiere clave API. Opera sobre datos de CRM propios en su espacio de trabajo.

Lea y actualice empresas en su espacio de trabajo. Las empresas se crean automáticamente cuando los contactos se guardan o se enriquecen, por lo que habitualmente solo necesitará `list`, `get` y `update` en lugar de crearlas. Para obtener los contactos de una empresa en una sola llamada, use `companies.contacts(id)`.

```typescript
import { g8 } from '@graph8/sdk';

g8.init({ apiKey: 'YOUR_API_KEY' });
```

### `list(params?)`

Lista empresas con filtros opcionales. Devuelve `{ data: Company[]; total: number }`.

```typescript
const { data } = await g8.companies.list({
  industry: 'SaaS',
  country: 'United States',
  limit: 50,
});
```

Campos filtrables: `domain`, `industry`, `name`, `country`, además de `page` y `limit`.

### `get(companyId)`

Obtiene una empresa individual por ID. Devuelve un `Company`.

```typescript
const company = await g8.companies.get(8821);
// { id: 8821, name: 'Acme Corp', domain: 'acme.com', industry: 'SaaS', employee_count: 320, ... }
```

### `contacts(companyId, limit?, offset?)`

Obtiene los contactos asociados a una empresa. El valor predeterminado es 50 por página. Devuelve `{ data: CompanyContact[]; total: number }`.

```typescript
const { data: people } = await g8.companies.contacts(8821, 25, 0);
// [{ id: 5028106, first_name: 'Jane', last_name: 'Smith', work_email: 'jane@acme.com', job_title: 'VP Engineering' }, ...]
```

### `update(companyId, fields)`

Actualización parcial. Devuelve `{ updated: number }`.

```typescript
await g8.companies.update(8821, {
  industry: 'B2B SaaS',
  description: 'Workflow automation for revenue teams.',
});
```

### `delete(companyId)`

Eliminación lógica de una empresa. Devuelve `{ deleted: boolean }`.

```typescript
await g8.companies.delete(8821);
```

---

## Listas

> **Caution:**
> Requiere clave API. Las listas alimentan secuencias, campañas y exportaciones.

Las listas organizan contactos (o empresas) en grupos para campañas, exportaciones y segmentación. Una lista creada aquí puede pasarse directamente a `g8.sequences.add()` o usarse como audiencia objetivo de una campaña.

```typescript
import { g8 } from '@graph8/sdk';

g8.init({ apiKey: 'YOUR_API_KEY' });
```

### `list(page?, limit?)`

Recorre todas las listas del espacio de trabajo. El valor predeterminado es página 1 / límite 50. Devuelve `{ data: ContactList[]; total: number }`.

```typescript
const { data: lists } = await g8.lists.list(1, 100);
// [{ id: 637, title: 'Q2 Outbound', type: 'contacts', contact_count: 1240, created_at: '2026-04-01T...' }, ...]
```

### `create(title, type?)`

Crea una nueva lista. `type` tiene como valor predeterminado `'contacts'`; use `'companies'` para una lista de cuentas. Devuelve el `ContactList` creado.

```typescript
const list = await g8.lists.create('Q2 Enterprise Push', 'contacts');
```

### `delete(listId)`

Eliminación lógica de una lista. Devuelve `{ deleted: boolean }`.

```typescript
await g8.lists.delete(637);
```

### `contacts(listId, page?, limit?)`

Recorre los contactos de una lista. Devuelve `{ data: ListContact[]; total: number }`.

```typescript
const { data } = await g8.lists.contacts(637, 1, 200);
```

### `addContacts(listId, contactIds)`

Agrega uno o más contactos existentes a una lista. Devuelve `{ added: number }`.

```typescript
await g8.lists.addContacts(637, [5028106, 5028105, 5028104]);
```

### `removeContacts(listId, contactIds)`

Elimina contactos de una lista (no elimina los contactos en sí). Devuelve `{ removed: number }`.

```typescript
await g8.lists.removeContacts(637, [5028104]);
```

---

## Integraciones con CRM

> **Caution:**
> Requiere clave API. Conectar y sincronizar mueve datos reales de clientes.

Conecte graph8 a su CRM (HubSpot, Salesforce, Pipedrive, etc.) y active sincronizaciones puntuales o bidireccionales.

```typescript
// List connected CRMs
const integrations = await g8.integrations.list();
// [{ id: 'int_123', provider: 'hubspot', status: 'connected', connected_at: '2026-03-15T...' }, ...]

// Connect a new CRM
await g8.integrations.connect('hubspot', { apiKey: 'pat-na1-...' });

// Trigger a sync ('inbound' | 'outbound' | 'bidirectional')
await g8.integrations.sync('hubspot', { direction: 'bidirectional' });
```

### Métodos

| Método | Descripción |
|--------|-------------|
| `g8.integrations.list()` | Lista los CRM conectados. Devuelve `Integration[]`. |
| `g8.integrations.connect(provider, config?)` | Conecta un CRM. Las credenciales específicas del proveedor van en `config`. |
| `g8.integrations.sync(provider, { direction? })` | Activa una sincronización. `direction` toma como valor predeterminado la configuración del proveedor. |

---

## Analítica

```typescript
const overview = await g8.analytics.overview({ period: '30d' });
// { visitors: 12500, contacts_created: 340, emails_sent: 2100, replies: 89, meetings_booked: 23 }
```

---

## Voz con IA

```typescript
// Start an AI voice call
const session = await g8.voice.start({
  agent: 'sales-discovery',
  contactId: 123,
});

// Get call analysis after completion
const analysis = await g8.voice.analysis(session.id);
// { sentiment: 'positive', summary: '...', next_steps: [...], objections: [...] }
```

---

## Páginas de destino

```typescript
// Clone from any URL
const page = await g8.pages.clone('https://competitor.com/pricing');

// Create from template
const page = await g8.pages.create({
  template: 'lead_magnet',
  title: 'The Future of Sales',
});

// Publish to CDN
const { url } = await g8.pages.publish(page.id);
// https://g8-lp-abc12345.pages.dev
```

---

## Webhooks

Escuche eventos de graph8 (del lado del servidor).

```typescript
g8.webhooks.on('reply_received', (event) => {
  slack.send(`${event.contact} replied to ${event.sequence}`);
});

g8.webhooks.on('meeting_booked', (event) => {
  crm.updateDeal(event.dealId, { stage: 'meeting' });
});

// Stop all listeners
g8.webhooks.stop();
```

**Eventos disponibles:** `reply_received`, `meeting_booked`, `contact_enriched`, `contact_created`, `sequence_completed`, `campaign_launched`, `form_submitted`, `visitor_identified`

---

## Privacidad

```typescript
g8.init({
  writeKey: 'YOUR_WRITE_KEY',
  privacy: {
    dontSend: true,           // Disable all cookies and event sending
    dontStoreUserIds: true,   // Don't store user identifiers
    ipPolicy: 'remove',       // 'keep' | 'stripLastOctet' | 'remove'
  },
});
```

## Compatibilidad con SSR

Todos los métodos son no operativos en el servidor y se ejecutan en el cliente tras la hidratación. Compatible con Next.js, Nuxt, Remix y cualquier framework con SSR.

## Opciones de configuración

| Opción | Tipo | Valor predeterminado | Descripción |
|--------|------|----------------------|-------------|
| `writeKey` | `string` | - | Write key para funcionalidades del lado del cliente |
| `apiKey` | `string` | - | Clave API para funcionalidades del lado del servidor |
| `host` | `string` | `https://t.graph8.com` | URL del host de seguimiento |
| `apiUrl` | `string` | `https://be.graph8.com` | URL de la API del backend |
| `debug` | `boolean` | `false` | Habilitar registro de depuración |
| `privacy.dontSend` | `boolean` | `false` | Deshabilitar cookies y envío de eventos |
| `privacy.dontStoreUserIds` | `boolean` | `false` | No almacenar identificadores de usuario |
| `privacy.ipPolicy` | `string` | `keep` | `keep`, `stripLastOctet` o `remove` |

## Obtenga sus claves

1. Vaya a [Configuración de graph8](https://app.graph8.com/profile) > MCP & API
2. La **write key** se encuentra en la sección del fragmento de seguimiento (lado del cliente)
3. La **clave API** se encuentra en la pestaña API (lado del servidor)
