Saltar al contenido principal
Casos de uso completos que puede ejecutar de verdad con una API key. Todas las llamadas usan el header Authorization: Bearer. Consulte Autenticación y la Guía de 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.
1

Descubra sus canales (inboxes)

Liste las inboxes conectadas a su empresa.
2

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).
cURL
3

Envíe un mensaje de texto

POST /v1/messages/send con el conversationId y el objeto message.
Use contentType: "TEXT" para mensajes de texto.
4

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.
cURL

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. Scopes: para registrar y consultar, webhooks:create y webhooks:read; para gestionar, webhooks:update y webhooks:delete (+ messages:create si responde automáticamente).
1

Registre un webhook

POST /v1/webhooks. Son 12 eventos válidos: MESSAGE_SENT, MESSAGE_RECEIVED, MESSAGE_DELIVERED, MESSAGE_READ, MESSAGE_FAILED, CONVERSATION_CREATED, CONVERSATION_UPDATED, CONVERSATION_STEP_CHANGED, CONTACT_CREATED, CONTACT_UPDATED, FOLLOWUP_SENT y FIELD_UPDATED. Consulte lo que cada uno entrega en la tabla de eventos.Su empresa tiene un webhook: si ya hay uno configurado, esta llamada devuelve 409. Actualice el existente en lugar de crear otro.
Campos opcionales: custom_headers (para que usted valide el origen) y status (ACTIVE/INACTIVE).
2

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:
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.
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.
3

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.
4

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".

Caso 3: Campañas y envío masivo

Scopes: campaigns:create, campaigns:read, campaigns:update, campaigns:delete y campaign-enrollments:create (+ messages:create para el atajo de plantilla en masa). La campaña llega a los contactos inscritos en ella. Cada inscripción vincula un contacto a una campaña y registra en qué punto de la cadencia está. Por la API, crear la campaña no inscribe a nadie, y agregar un contacto a una lista tampoco: la inscripción es siempre un paso explícito.
Las etapas de la campaña (los mensajes y los intervalos de la cadencia) se arman en el panel de Nuvia. No hay ruta de etapas para API key. Por la API se crea y configura la campaña, se inscriben los contactos, se activa y se hace el seguimiento.
1

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, sender_config y exclusion_lists. Las estructuras internas de estos objetos de configuración están en la Referencia de la API. Siga el schema de allí.La campaña nace como borrador. audience_config describe la audiencia, pero crear la campaña por la API no inscribe a nadie. Las inscripciones vienen en el paso siguiente.Las listas de exclusión (exclusion_lists) solo se pueden elegir mientras la campaña es borrador. Después de la activación, lo que cambia es su contenido (consulte el Caso 4).
2

Inscriba la audiencia

Elija la ruta según el origen de los contactos. Todas exigen el scope campaign-enrollments:create:Quien ya está inscrito en la campaña se omite, así que repetir la llamada no duplica inscripciones.
cURL
La inscripción por lista lee los contactos de la lista en el momento de la llamada. Quien se agregue a la lista después no entra solo en la campaña: inscríbalo de nuevo o use from-contact.
3

Revise 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.
4

Active y haga el seguimiento

Active con POST /v1/campaigns/:id/activate (pause con /pause). La campaña necesita al menos una etapa activa. La activación pone en cola a los contactos ya inscritos y devuelve cuántos en enrollments_enqueued.
cURL
Haga el seguimiento con GET /v1/campaigns/:id/analytics y GET /v1/campaigns/:id/step-analytics, y exporte los contactos con GET /v1/campaigns/:id/enrollments/export.
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.

Caso 4: Inscribir contactos desde su CRM

Para integraciones en las que su sistema decide quién entra en cuál cadencia: la campaña ya está activa, y cada contacto se inscribe en el momento en que el CRM lo pide. Nuvia hace los envíos, termina la cadencia cuando el lead responde y devuelve los eventos para actualizar el CRM. Scopes: campaign-enrollments:create, campaign-enrollments:read, campaigns:read y contacts:read (+ messages:read para leer las conversaciones y webhooks:create para recibir los eventos).
1

Elija la campaña

GET /v1/campaigns lista las campañas con estado y canal; GET /v1/campaigns/:id devuelve una. Guarde el id de la campaña de cada cadencia. La inscripción solo se acepta en una campaña con estado ACTIVE.El canal de la campaña define el identificador obligatorio del contacto: una campaña de LinkedIn exige linkedin_identifier; cualquier otra exige teléfono. Use una campaña por canal y deje que el CRM decida en cuál inscribir.
Una campaña cuyo disparador no es EXTERNAL_TRIGGER se completa automáticamente cuando se queda sin ninguna inscripción en curso. Basta un momento así, por ejemplo que el primer lead responda antes de que el CRM inscriba al segundo. A partir de ahí la inscripción devuelve 409, y una campaña MANUAL completada no se puede reactivar.Para cadencias alimentadas por el CRM, cree la campaña con trigger_type: EXTERNAL_TRIGGER y audience_config.type: EXTERNAL. Este tipo de campaña sigue activo para recibir nuevas inscripciones hasta que se pause.
2

Inscriba el contacto

POST /v1/campaigns/:id/enrollments/from-contact. La ruta localiza el contacto por el teléfono (o, sin teléfono, por el linkedin_identifier), crea el contacto si no existe y lo inscribe en la campaña.
La inscripción siempre empieza en la primera etapa de la cadencia; no hay forma de inscribir a partir de una etapa específica. El primer envío respeta la ventana de envío de la campaña.
3

Lea el resultado

La respuesta tiene status igual a enrolled o skipped:
Con enroll_again, una nueva inscripción viene con re_enrolled: true. Cuando la inscripción se omite, el motivo viene en reason, junto con el contactId cuando el contacto fue localizado:
La respuesta skipped no trae el enrollmentId. Para recuperarlo, consulte las inscripciones de la campaña (paso “Haga el seguimiento de las inscripciones”).
Errores: 404 cuando la campaña no existe o es de otra empresa, 409 cuando no está ACTIVE y 400 cuando el cuerpo es inválido (por ejemplo, sin phone ni linkedin_identifier).
4

Guarde los IDs en el CRM

Guarde el contactId, el enrollmentId y el id de la campaña junto al registro del CRM. Son los que vinculan los eventos y las consultas de Nuvia con su negocio u oportunidad.En Nuvia, una persona es un contacto, con un vínculo de CRM:
  • fields se graba en el contacto, no en la inscripción. La inscripción no tiene campo de negocio.
  • external_id es uno solo por contacto y vale el último enviado.
  • Las variables de los mensajes usan el valor actual del contacto.
Si una persona tiene más de un negocio en su CRM, guarde el vínculo inscripción → negocio de su lado. No envíe en fields datos específicos de un negocio: la inscripción del negocio B sobrescribe el valor del negocio A en el contacto.
5

Maneje reintentos y timeouts

La ruta no tiene clave de idempotencia. La protección es una regla de Nuvia: un contacto tiene como máximo una inscripción por campaña. Después de un timeout, reenvíe la misma llamada y trate skipped con already_enrolled (o already_in_progress, con enroll_again) como éxito.
Envíe las llamadas de un mismo contacto en secuencia, nunca en paralelo. Las llamadas simultáneas para el mismo teléfono pueden duplicar el contacto o fallar con 5xx. Ante un 5xx, espere unos segundos e intente de nuevo.
6

Haga el seguimiento de las inscripciones

Cada inscripción tiene un status:Una inscripción que recorrió todas las etapas, o que se detuvo por una falla de envío que no se resuelve con un reintento, termina sin motivo. Maneje un completion_reason ausente, nulo o con un valor nuevo sin romper la integración.Cuando el lead responde, Nuvia termina todas sus inscripciones activas que ya tuvieron actividad (envío, falla o invitación), en cualquier campaña, con completion_reason: REPLIED. La cadencia se detiene sola: su sistema no necesita interrumpirla, solo llevar al lead a la siguiente acción comercial.No existe webhook de inscripción creada, de cambio de estado ni de inscripción terminada. Para mantener el CRM al día, consulte periódicamente:El listado de inscripciones no filtra por contactId ni por enrollmentId. Por eso el enrollmentId guardado en el CRM es su referencia.
7

Reciba las respuestas por webhook

Los eventos de mensaje llegan por el webhook de la empresa. Para la integración con CRM, los principales:
  • Respuesta del lead: MESSAGE_RECEIVED con sender_type: CONTACT y message_type: INCOMING. Filtre por los dos campos: el evento también se dispara para mensajes que no son del lead, como los enviados desde la app de WhatsApp Business en coexistencia. Consulte el remitente del mensaje.
  • Falla de entrega: MESSAGE_FAILED. Las fallas anteriores al intento de envío no generan webhook y solo aparecen en las ejecuciones de la campaña.
  • Cambio de etapa del embudo: CONVERSATION_STEP_CHANGED no indica respuesta. Una etapa de campaña puede mover la conversación a una etapa del embudo en el propio envío, antes de que el lead responda.
Los eventos de mensaje no traen el ID de la campaña ni el external_id. Use el contactId para encontrar el registro en el CRM. El webhook hace un único intento de entrega, así que mantenga la consulta periódica del paso anterior para conciliar eventos perdidos.
No hay evento de opt-out. Nuvia no convierte palabras como “SALIR” o “BAJA” en un evento propio: si su proceso maneja bajas, identifique el mensaje del lead de su lado.
8

Evite cadencias simultáneas

Nuvia no impide que el mismo contacto esté en campañas diferentes al mismo tiempo. La respuesta del lead termina todas, pero hasta entonces puede recibir las dos cadencias. Para evitarlo:
  • En el CRM: antes de inscribir, verifique si el contacto ya tiene una inscripción en curso con los enrollmentId que guardó.
  • En Nuvia: use listas de exclusión. Se eligen al crear la campaña (solo mientras es borrador), pero el contenido de cada lista se consulta antes de cada envío. Agregar un contacto a una lista de exclusión después de la activación ya vale para los próximos envíos, y su inscripción termina con EXCLUSION_LIST.

Caso 5: Sincronizar contactos

Mantenga su CRM externo y Nuvia sincronizados. Scopes: contacts:read, contacts:create, contacts:update, contacts:delete.
1

Verifique duplicados por teléfono

Antes de crear, resuelva los teléfonos para ver cuáles ya existen: POST /v1/contacts/find-by-phones.
2

Cree los contactos que faltan

POST /v1/contacts. Obligatorios: name y al menos un identificador entre teléfono (phone_number, solo dígitos, código de área + número, sin el código de país, junto con country_code, ej.: 55), email y linkedin_identifier. Opcionales: campos de perfil como job_title y city, y additional_attributes ({ "slug": valor }) para campos personalizados.Si la empresa ya tiene un contacto con alguno de los identificadores, la ruta reutiliza ese contacto en lugar de duplicarlo. La búsqueda sigue el orden e-mail, LinkedIn y teléfono:
  • 201: contacto creado, con created: true.
  • 200: contacto existente reutilizado, con created: false y matched_by (email, linkedin o phone). Encontrado por teléfono, los campos enviados se actualizan. Encontrado por e-mail o LinkedIn, solo se completan los campos vacíos, e ignored_fields indica lo que no se guardó.
  • 409 CONTACT_IDENTITY_CONFLICT: los identificadores pertenecen a contactos diferentes. No se guarda nada, y conflicts devuelve el contacto de cada identificador.
El name de un contacto existente nunca cambia: para cambiarlo, use PUT /v1/contacts/:id. Para saber qué haría la ruta sin guardar nada, use POST /v1/contacts/identity-check.
3

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).

Caso 6: Asignar la conversación al owner de HubSpot

Para automatizaciones que reciben un evento de HubSpot con un owner (por ejemplo, el propietario de una reunión agendada) y necesitan asignar la conversación en Nuvia al usuario correspondiente. El mapeo entre owners de HubSpot y usuarios de Nuvia se configura en la pantalla de integración de HubSpot. La API solo lo lee. Scopes: hubspot:read y conversations:update (+ conversations:read para localizar la conversación). Una clave existente no obtiene el scope: genere una nueva con ese scope marcado (consulte la Guía de API key).
1

Lea el mapeo de owners

GET /v1/hubspot/owner-mappings devuelve los pares owner de HubSpot ↔ usuario de Nuvia de su empresa.
Respuesta:
El nuvia_user_id es el id del usuario de Nuvia que se usa para asignar la conversación. Si la empresa no tiene HubSpot conectado, la lista viene vacía.
2

Guarde el mapeo en caché y encuentre el usuario

El mapeo cambia poco. Consulte owner-mappings una vez, guárdelo por algunos minutos y busque el owner del evento por hubspot_owner_id. No use el correo electrónico: hubspot_owner_email es una copia de cuando se guardó el mapeo y no se actualiza si el correo cambia en HubSpot.
Trate el owner que no aparece en el mapeo, por ejemplo un vendedor nuevo que aún no se mapeó en la pantalla: registre el caso y no asigne la conversación a ciegas.
No llame a GET /v1/hubspot/owners, /properties o /pipelines en cada evento. Estas tres rutas consultan HubSpot en tiempo real y consumen la cuota de API del portal HubSpot de su empresa, la misma que usa la sincronización. owner-mappings se lee de Nuvia y no consume esa cuota. Sin HubSpot conectado, las tres responden 404: “Integração com HubSpot não encontrada. Conecte sua conta primeiro.” (Integración con HubSpot no encontrada. Conecte su cuenta primero.)
3

Asigne la conversación

PUT /v1/conversations/:id/assign-owner con el nuvia_user_id en userId. La ruta define el propietario de la conversación y no cambia quién está respondiendo: si la IA atiende, sigue atendiendo. Para pasar la atención a una persona, use PUT /v1/conversations/:id/assign-user.

Otras superficies públicas

Consumibles por API key y cubiertas en la Referencia: Agentes, Tablas y listas, Conversaciones, Base de conocimiento y HubSpot (solo lectura de la configuración de la integración). Vea el mapa en Secciones de la API.

Próximos pasos

Guía de API key

Scopes, creación y revocación de claves.

Referencia de la API

Todos los endpoints, parámetros y respuestas.