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

# Ejemplos de integración

> Escenarios de principio a fin con la API de Nuvia: mensajes, webhooks, campañas y contactos

Casos de uso completos que puede ejecutar de verdad con una API key. Todas las llamadas usan el
header `Authorization: Bearer`. Consulte [Autenticación](/es/autenticacao) y la
[Guía de API key](/es/guia-api-key) para obtener y configurar la clave. Base: `https://api.nuvia.ai`,
prefijo `/v1`.

Cada caso indica los **scopes** de API key necesarios. Otorgue solo esos al crear la clave.

## Caso 1: Enviar su primer mensaje

**Scopes:** `inboxes:read`, `conversations:read`, `messages:read`, `messages:create`.

<Steps>
  <Step title="Descubra sus canales (inboxes)">
    Liste las inboxes conectadas a su empresa.

    <CodeGroup>
      ```bash cURL theme={null}
      curl https://api.nuvia.ai/v1/inboxes \
        -H "Authorization: Bearer $NUVIA_API_KEY"
      ```

      ```javascript JavaScript theme={null}
      const res = await fetch("https://api.nuvia.ai/v1/inboxes", {
        headers: { Authorization: `Bearer ${process.env.NUVIA_API_KEY}` },
      });
      const { data } = await res.json();
      ```

      ```python Python theme={null}
      import os, requests
      res = requests.get(
          "https://api.nuvia.ai/v1/inboxes",
          headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
      )
      data = res.json()["data"]
      ```
    </CodeGroup>
  </Step>

  <Step title="Obtenga una conversación">
    El envío de un mensaje se hace dentro de una conversación. Liste conversaciones para obtener un
    `conversationId` (o cree una con `POST /v1/conversations`).

    ```bash cURL theme={null}
    curl "https://api.nuvia.ai/v1/conversations" \
      -H "Authorization: Bearer $NUVIA_API_KEY"
    ```
  </Step>

  <Step title="Envíe un mensaje de texto">
    `POST /v1/messages/send` con el `conversationId` y el objeto `message`.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.nuvia.ai/v1/messages/send \
        -H "Authorization: Bearer $NUVIA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "conversationId": "ID_DE_LA_CONVERSACION",
          "message": { "content": "¡Hola! Enviado vía API.", "contentType": "TEXT" }
        }'
      ```

      ```javascript JavaScript theme={null}
      await fetch("https://api.nuvia.ai/v1/messages/send", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.NUVIA_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          conversationId: "ID_DE_LA_CONVERSACION",
          message: { content: "¡Hola! Enviado vía API.", contentType: "TEXT" },
        }),
      });
      ```

      ```python Python theme={null}
      import os, requests
      requests.post(
          "https://api.nuvia.ai/v1/messages/send",
          headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
          json={
              "conversationId": "ID_DE_LA_CONVERSACION",
              "message": {"content": "¡Hola! Enviado vía API.", "contentType": "TEXT"},
          },
      )
      ```
    </CodeGroup>

    Use `contentType: "TEXT"` para mensajes de texto.
  </Step>

  <Step title="Lea el historial de la conversación">
    `GET /v1/messages/conversation/:id` devuelve los mensajes; los adjuntos están en
    `GET /v1/messages/conversation/:id/attachments`.

    ```bash cURL theme={null}
    curl "https://api.nuvia.ai/v1/messages/conversation/ID_DE_LA_CONVERSACION" \
      -H "Authorization: Bearer $NUVIA_API_KEY"
    ```
  </Step>
</Steps>

## Caso 2: Recibir eventos vía webhooks

Registre una URL propia para que Nuvia le notifique en tiempo real (mensajes, conversaciones,
contactos). Este caso muestra el flujo de principio a fin; el formato del payload, la lista completa
de eventos y las garantías de entrega están en la [guía de Webhooks](/es/guias/webhooks).

**Scopes:** para registrar y consultar, `webhooks:create` y `webhooks:read`; para gestionar,
`webhooks:update` y `webhooks:delete` (+ `messages:create` si responde automáticamente).

<Steps>
  <Step title="Registre un webhook">
    `POST /v1/webhooks`. Son 10 eventos válidos: `MESSAGE_SENT`, `MESSAGE_RECEIVED`,
    `MESSAGE_DELIVERED`, `MESSAGE_READ`, `CONVERSATION_CREATED`, `CONVERSATION_UPDATED`,
    `CONTACT_CREATED`, `CONTACT_UPDATED`, `FOLLOWUP_SENT` y `FIELD_UPDATED`. Consulte lo que cada uno
    entrega en la [tabla de eventos](/es/guias/webhooks).

    Su empresa tiene **un** webhook: si ya hay uno configurado, esta llamada devuelve `409`.
    Actualice el existente en lugar de crear otro.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.nuvia.ai/v1/webhooks \
        -H "Authorization: Bearer $NUVIA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "url": "https://tu-servidor.com/nuvia/webhook",
          "events": ["MESSAGE_RECEIVED", "CONVERSATION_CREATED"],
          "status": "ACTIVE"
        }'
      ```

      ```javascript JavaScript theme={null}
      await fetch("https://api.nuvia.ai/v1/webhooks", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.NUVIA_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          url: "https://tu-servidor.com/nuvia/webhook",
          events: ["MESSAGE_RECEIVED", "CONVERSATION_CREATED"],
          status: "ACTIVE",
        }),
      });
      ```

      ```python Python theme={null}
      import os, requests
      requests.post(
          "https://api.nuvia.ai/v1/webhooks",
          headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
          json={
              "url": "https://tu-servidor.com/nuvia/webhook",
              "events": ["MESSAGE_RECEIVED", "CONVERSATION_CREATED"],
              "status": "ACTIVE",
          },
      )
      ```
    </CodeGroup>

    Campos opcionales: `custom_headers` (para que usted valide el origen) y `status`
    (`ACTIVE`/`INACTIVE`).
  </Step>

  <Step title="Reciba los callbacks">
    Cuando ocurre un evento, Nuvia hace un `POST` a su `url`, con el header `X-Webhook-Event` y un
    cuerpo de tres campos:

    ```json theme={null}
    {
      "event": "MESSAGE_RECEIVED",
      "timestamp": "2026-08-13T14:03:00.000Z",
      "data": {}
    }
    ```

    `data` trae el recurso del evento: el mensaje, la conversación o el contacto, en el mismo
    formato de los `GET` correspondientes. `FIELD_UPDATED` es la excepción y tiene estructura
    propia.

    <Warning>
      Responda `2xx` en hasta **10 segundos** y procese en background. No hay retry: si su
      respuesta falla o excede el tiempo, el evento se pierde. Detalles en
      [Garantías de entrega](/es/guias/webhooks#garantias-de-entrega).
    </Warning>
  </Step>

  <Step title="Reaccione al evento">
    A partir del callback, puede actuar vía API: responda con
    `POST /v1/messages/send` (Caso 1) o descargue adjuntos con
    `GET /v1/messages/conversation/:id/attachments`.
  </Step>

  <Step title="Gestione la configuración">
    `GET /v1/webhooks` devuelve **un objeto** con la configuración de la empresa (o `null`). No es
    una lista. Use el `id` de ese objeto para actualizar con `PUT /v1/webhooks/:id` o eliminar con
    `DELETE /v1/webhooks/:id`. Para pausar sin perder la configuración, prefiera `PUT` con
    `status: "INACTIVE"`.
  </Step>
</Steps>

## Caso 3: Campañas y envío masivo

**Scopes:** `campaigns:create`, `campaigns:read`, `campaigns:update`, `campaigns:delete`
(+ `messages:create` para el atajo de plantilla en masa).

<Steps>
  <Step title="Cree la campaña">
    `POST /v1/campaigns`. Campos obligatorios: `name`, `channel_type`, `trigger_type` y
    `audience_config`; los opcionales incluyen `description`, `trigger_config`, `behavior_config` y
    `sender_config`. Las estructuras internas de estos objetos de configuración están en la
    [Referencia de la API](/es/api-reference/campaigns). Siga el esquema de allí.

    La **audiencia se define en la propia creación**, dentro de `audience_config` (por
    `contact_ids`, `lists` o `filters`). No hay un paso de inscripción (enrollment) separado que
    hacer vía API. La campaña ya nace con la audiencia que se indique aquí.
  </Step>

  <Step title="Verifique antes de enviar">
    Use las vistas previas (no crean nada): `POST /v1/campaigns/audience-preview` cuenta los
    contactos de la audiencia y `POST /v1/campaigns/preview-message` resuelve las variables del
    mensaje.
  </Step>

  <Step title="Active y monitoree">
    Active con `POST /v1/campaigns/:id/activate` (pause con `/pause`). Monitoree con
    `GET /v1/campaigns/:id/analytics` y `GET /v1/campaigns/:id/step-analytics`, y exporte los
    contactos con `GET /v1/campaigns/:id/enrollments/export`.

    ```bash cURL theme={null}
    curl -X POST https://api.nuvia.ai/v1/campaigns/ID_DE_LA_CAMPANA/activate \
      -H "Authorization: Bearer $NUVIA_API_KEY"
    ```
  </Step>
</Steps>

<Note>
  **Atajo:** para enviar una plantilla de WhatsApp a varios contactos sin armar una campaña, use
  `POST /v1/messages/send-bulk-template` (scope `messages:create`). El paso a paso, con los
  parámetros de plantilla y los límites de Meta, está en la guía
  [Envío masivo de plantillas en WhatsApp](/es/guias/whatsapp-template-massa).
</Note>

## Caso 4: Sincronizar contactos

Mantenga su CRM externo y Nuvia sincronizados.

**Scopes:** `contacts:read`, `contacts:create`, `contacts:update`, `contacts:delete`.

<Steps>
  <Step title="Verifique duplicados por teléfono">
    Antes de crear, resuelva los teléfonos para ver cuáles ya existen:
    `POST /v1/contacts/find-by-phones`.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.nuvia.ai/v1/contacts/find-by-phones \
        -H "Authorization: Bearer $NUVIA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{ "phones": ["+5511999999999", "+5511888888888"] }'
      ```

      ```javascript JavaScript theme={null}
      const res = await fetch("https://api.nuvia.ai/v1/contacts/find-by-phones", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.NUVIA_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ phones: ["+5511999999999", "+5511888888888"] }),
      });
      ```

      ```python Python theme={null}
      import os, requests
      res = requests.post(
          "https://api.nuvia.ai/v1/contacts/find-by-phones",
          headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
          json={"phones": ["+5511999999999", "+5511888888888"]},
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Cree los contactos que faltan">
    `POST /v1/contacts`. Campos: `firstname`, `lastname`, `phone`, `email`, `company` y
    `properties`.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.nuvia.ai/v1/contacts \
        -H "Authorization: Bearer $NUVIA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "firstname": "María",
          "lastname": "Silva",
          "phone": "+5511999999999",
          "email": "maria@empresa.com"
        }'
      ```

      ```javascript JavaScript theme={null}
      await fetch("https://api.nuvia.ai/v1/contacts", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.NUVIA_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          firstname: "María",
          lastname: "Silva",
          phone: "+5511999999999",
          email: "maria@empresa.com",
        }),
      });
      ```

      ```python Python theme={null}
      import os, requests
      requests.post(
          "https://api.nuvia.ai/v1/contacts",
          headers={"Authorization": f"Bearer {os.environ['NUVIA_API_KEY']}"},
          json={
              "firstname": "María",
              "lastname": "Silva",
              "phone": "+5511999999999",
              "email": "maria@empresa.com",
          },
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Actualice y liste">
    Actualice un contacto con `PUT /v1/contacts/:id` (o solo el nombre con
    `PUT /v1/contacts/:id/name`) y liste/pagine con `GET /v1/contacts`. Para **quitar el vínculo**
    de un contacto con un CRM externo, use `DELETE /v1/contacts/:id/crm-link`: esto **solo deshace
    la vinculación; el contacto sigue existiendo** en Nuvia (no es una eliminación de contacto).
  </Step>
</Steps>

## Otras superficies públicas

Consumibles por API key y cubiertas en la Referencia: **Agentes**, **Tablas y listas**,
**Conversaciones** y **Base de conocimiento**. Vea el mapa en
[Secciones de la API](/es/secoes-da-api).

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Guía de API key" icon="key" href="/es/guia-api-key">
    Scopes, creación y revocación de claves.
  </Card>

  <Card title="Referencia de la API" icon="code" href="/es/api-reference">
    Todos los endpoints, parámetros y respuestas.
  </Card>
</CardGroup>
