MÓDULO
Inicia aquí
Primeros pasos y conceptos relevantes para iniciar tu integración con la API de Upnify.
Bienvenida
Bienvenida
Te damos la bienvenida a la API de Upnify. Esta guía reúne los conceptos y recomendaciones que conviene conocer antes de comenzar una integración.
Aprende con una primera integración
Estos tutoriales breves incluyen pasos, código y un resultado que puedes comprobar. Recórrelos en orden o elige el tema que necesitas:
- Tu primera petición: obtén una sesión y consulta prospectos.
- Del formulario al CRM: crea un prospecto desde HTML y JavaScript.
- Busca antes de crear: compara el correo y evita altas innecesarias.
- Filtra y pagina prospectos: consulta grupos pequeños de información.
- Maneja los errores: renueva la sesión, corrige datos y limita los reintentos.
Conocimientos previos
Para desarrollar una integración con mayor seguridad y rapidez, te recomendamos contar con experiencia en:
- El protocolo HTTP y servicios REST. Si necesitas reforzar estos conceptos, consulta la sección REST.
- El funcionamiento del proceso y la cuenta de Upnify que integrarás.
- Un lenguaje de programación, por ejemplo Node.js, C#, Go, Python, PHP, Java, Perl o Ruby.
- Un cliente HTTP como Postman o Insomnia para explorar y probar solicitudes.
Cómo funciona la API de Upnify
La API usa un estilo REST y JSON para intercambiar información. Cada módulo documenta las rutas disponibles, los parámetros que debes enviar y el formato de sus respuestas.
Para realizar solicitudes autenticadas, la forma recomendada es obtener un token de integración e intercambiarlo por un token de sesión mediante POST /integraciones/sesion. Consulta Autenticación para realizar tu primera solicitud e Integraciones para conocer la vigencia y renovación de la sesión.
Trata los tokens y las credenciales como secretos: no los incluyas en código fuente, repositorios, registros de aplicación ni interfaces de usuario. Guárdalos en la configuración segura de tu aplicación y sustitúyelos si sospechas que fueron expuestos.
Consideraciones para tu integración
- Consulta los estándares del API antes de implementar. Te ayudarán a interpretar solicitudes, respuestas y códigos HTTP de forma consistente.
- Respeta el límite de 100 solicitudes por minuto. Si lo superas, la API puede responder con el código HTTP
429. Implementa espera y reintentos graduales; no repitas la solicitud de inmediato ni aumentes la frecuencia de llamadas. - Cuando estén disponibles para el evento que necesitas, utiliza webhooks en lugar de consultar periódicamente la información. Upnify puede notificar a tu sistema eventos como la creación de un prospecto, cliente o venta, evitando sincronizaciones innecesarias y acercando la integración al tiempo real.
- Prueba los flujos completos: solicitudes correctas, datos faltantes, errores de autenticación, límites de consumo y reintentos. Registra solo la información necesaria y nunca tokens, contraseñas ni datos personales completos.
Automatizaciones sin código
También puedes conectar Upnify con otras aplicaciones mediante herramientas como Integromat o Zapier. Estas plataformas pueden ayudarte a crear automatizaciones como:
- Agregar un cliente nuevo a una hoja de cálculo.
- Notificar un prospecto nuevo a un grupo de Telegram.
- Crear un cliente a partir de una venta de WooCommerce.
Antes de activar una automatización en producción, valida los campos que se comparten, los permisos del usuario o integración y el tratamiento de información sensible.
REST
REST y servicios RESTful
REST significa Representational State Transfer. Es un estilo de arquitectura para diseñar servicios web sencillos, mantenibles y escalables. Una API que sigue estos principios se conoce como API RESTful.
REST no es un protocolo ni una tecnología específica: aprovecha las convenciones de HTTP para que una aplicación cliente pueda solicitar o modificar información de un servicio web de forma predecible.
Recursos y URL
En REST, la información se organiza como recursos: por ejemplo, clientes, prospectos, ventas o productos. Cada recurso se identifica mediante una URL.
https://api.upnify.com/v4/clientes
Una URI identifica un recurso; una URL es un tipo de URI que además indica cómo localizarlo. En esta documentación usamos “URL” para referirnos a las direcciones que debes invocar.
Las rutas pueden incluir:
- Parámetros de ruta, que identifican un recurso concreto, como
/clientes/:tkCliente. - Parámetros de consulta, después de
?, para filtrar, ordenar o paginar resultados. - Un cuerpo JSON, normalmente al crear o actualizar información.
JSON: el formato de intercambio
La API intercambia datos mediante JSON (JavaScript Object Notation), un formato de texto legible por personas y fácil de procesar en la mayoría de los lenguajes.
{
"nombre": "Usuario de ejemplo",
"apellido": "Pérez",
"edad": 38,
"correo": "usuario@upnify.com"
}
Al enviar un cuerpo JSON, incluye el encabezado Content-Type: application/json. Revisa siempre la ficha del endpoint para conocer los campos requeridos, sus tipos y restricciones.
HTTP y sus métodos
HTTP define la comunicación entre tu aplicación y la API. Cada solicitud usa un método —también llamado verbo— que expresa la operación deseada sobre un recurso.
| Método | Uso habitual | Consideración |
|---|---|---|
GET |
Consultar recursos. | No debe modificar información y puede repetirse sin cambiar el resultado esperado. |
POST |
Crear un recurso o ejecutar una acción. | No suele ser idempotente: repetir una solicitud puede generar otra operación. |
PUT |
Actualizar un recurso existente. | Envía solo los campos que la ficha del endpoint permite modificar. |
DELETE |
Eliminar o desactivar un recurso. | Revisa la ficha: según el recurso, la eliminación puede ser lógica o permanente. |
Una solicitud HTTP incluye una URL, un método, encabezados y, cuando aplica, un cuerpo. La respuesta contiene un código de estado HTTP y, normalmente, datos JSON.
Códigos de respuesta
Como guía general, los códigos HTTP se agrupan así:
2xx: la solicitud se procesó correctamente.4xx: la solicitud requiere corrección, autenticación o permisos adicionales. Por ejemplo,401y403se relacionan con acceso, y429indica que superaste el límite de solicitudes.5xx: ocurrió un problema en el servidor. Conserva un identificador de seguimiento si la respuesta lo proporciona y reintenta solo cuando sea apropiado.
No supongas que todas las rutas devuelven la misma estructura. Consulta la sección Respuesta de cada endpoint antes de procesar los datos.
Recomendaciones prácticas
- Usa siempre HTTPS y conserva el token de sesión como un secreto. No lo incluyas en repositorios, registros ni URLs compartidas.
- Envía únicamente los encabezados y parámetros documentados para cada endpoint.
- Implementa tiempos de espera, manejo de errores y reintentos graduales. Ante un
429, espera antes de reintentar. - Pagina los listados y usa filtros para reducir el volumen de datos.
- Cuando un evento admita webhooks, prefírelos a consultar la API de forma repetitiva.
Continúa con Autenticación para obtener un token y con Integraciones para conocer opciones de conexión de larga duración.
Autenticación
La forma recomendada de acceder al API de Upnify de manera consistente y segura es utilizar un token de integración e intercambiarlo por un token de sesión. El acceso de estas sesiones está limitado para integraciones.
1. Obtén un token de integración
Da de alta una integración en Ajustes → API dentro de tu cuenta de Upnify CRM y selecciona el logotipo de Upnify. Esto agregará una nueva integración para sistemas externos y te asignará su token de integración el cuál deberás intercambiar por uno de sesión. Consulta Integraciones para conocer la diferencia entre ambos tokens y cómo administrar la vigencia de la sesión.
Los valores TOKEN-INTEGRACION-EJEMPLO y TOKEN-SESION-EJEMPLO de esta guía son ficticios. Sustitúyelos por los valores de tu integración y de la sesión obtenida, respectivamente.
2. Intercambia el token por una sesión
Envía el token de integración en el encabezado token de POST /integraciones/sesion. Esta solicitud no necesita cuerpo.
curl --request POST \
--url 'https://api.upnify.com/integraciones/sesion' \
--header 'token: TOKEN-INTEGRACION-EJEMPLO' \
--header 'Accept: application/json'
La respuesta es un arreglo JSON. Este ejemplo muestra una sesión obtenida el 22 de septiembre de 2026 a las 12:00, con dos días de vigencia:
[
{
"code": 0,
"token": "TOKEN-SESION-EJEMPLO",
"details": {
"expiracion": "2026-09-24T12:00:00",
"tkIntegracion": "TOKEN-INTEGRACION-EJEMPLO"
}
}
]
Comprueba que code sea 0 y guarda el valor de [0].token: ese es el token de sesión que usarás para consultar el API. details.tkIntegracion identifica el token de integración y details.expiracion informa el vencimiento vigente de la sesión, en hora local del servidor (CDMX), sin indicador de zona horaria.
3. Consulta el API con el token de sesión
Envía el token de sesión obtenido en el encabezado token de cada solicitud autenticada. Por ejemplo, para consultar prospectos con GET /prospectos:
curl --request GET \
--url 'https://api.upnify.com/prospectos' \
--header 'token: TOKEN-SESION-EJEMPLO' \
--header 'Accept: application/json'
Vigencia y renovación de la sesión
Una sesión nueva tiene dos días de vigencia desde su creación. Al repetir POST /integraciones/sesion con el token de integración, el API reutiliza la sesión existente:
- Si quedan cinco horas o más antes del vencimiento, conserva su fecha de expiración.
- Si quedan menos de cinco horas o la sesión ya venció, renueva su vigencia por dos días desde el momento del intercambio.
La renovación conserva el token de la sesión existente. Guarda siempre el token y la fecha devueltos por el intercambio de forma segura para usar los valores vigentes.
El campo details.expiracion informa el vencimiento vigente, incluida la renovación cuando ocurre. Está expresado en formato ISO 8601, en hora local del servidor (CDMX), sin indicador de zona horaria. Puede ser null en sesiones anteriores que no tengan una fecha de expiración registrada; no interpretes ese valor como una garantía de vigencia indefinida.
Realizar consultas al API no renueva la sesión. Programa el intercambio dentro de las últimas cinco horas de vigencia, antes del vencimiento. Si la sesión ya expiró, repite el intercambio con el token de integración antes de continuar con las solicitudes autenticadas.
Protección de los tokens
Guarda ambos tokens en la configuración segura de tu aplicación y utiliza HTTPS. No los incluyas en repositorios, registros ni interfaces de usuario.
Tu primera petición
Objetivo: intercambiar tu token de integración y consultar hasta cinco prospectos. Duración: 5 minutos.
Paso 1. Prepara tu token
En Upnify CRM, entra a Ajustes → API, selecciona el logotipo de Upnify y obtén el token de la integración para sistemas externos. Puedes consultar los detalles en Autenticación.
Para el ejemplo completo necesitas Node.js 22 o posterior. Crea una carpeta de práctica y, dentro de ella, un archivo .env:
UPNIFY_TOKEN_INTEGRACION=TOKEN-INTEGRACION-EJEMPLO
Sustituye el valor ficticio por tu token. Mantén .env fuera del control de versiones y no lo compartas.
Paso 2. Reconoce las dos solicitudes
Primero se envía el token de integración a POST /integraciones/sesion:
curl --request POST 'https://api.upnify.com/integraciones/sesion' \
--header 'token: TOKEN-INTEGRACION-EJEMPLO'
Si [0].code es 0, toma [0].token de la respuesta. Ese token de sesión se utiliza en GET /prospectos:
curl --get 'https://api.upnify.com/prospectos' \
--header 'token: TOKEN-SESION-EJEMPLO' \
--data-urlencode 'pagina=1' \
--data-urlencode 'cantidadRegistros=5'
Los valores de ambos comandos son ficticios. El segundo se sustituye por el token devuelto por el primero.
Paso 3. Une el flujo en un programa
Guarda este código como primera-peticion.cjs. El programa conserva la sesión en memoria y muestra únicamente cuántos prospectos recibió.
async function main() {
const tokenIntegracion = process.env.UPNIFY_TOKEN_INTEGRACION;
if (!tokenIntegracion) throw new Error("Configura UPNIFY_TOKEN_INTEGRACION.");
const intercambio = await fetch("https://api.upnify.com/integraciones/sesion", {
method: "POST",
headers: { token: tokenIntegracion },
});
if (!intercambio.ok) throw new Error(`Intercambio: HTTP ${intercambio.status}.`);
const [sesion] = await intercambio.json();
if (sesion?.code !== 0 || !sesion.token) {
throw new Error("No se recibió una sesión válida.");
}
const respuesta = await fetch(
"https://api.upnify.com/prospectos?pagina=1&cantidadRegistros=5",
{ headers: { token: sesion.token } },
);
if (!respuesta.ok) throw new Error(`Consulta: HTTP ${respuesta.status}.`);
const prospectos = await respuesta.json();
if (!Array.isArray(prospectos)) throw new Error("Se esperaba una lista.");
console.log(`Conexión correcta. Prospectos recibidos: ${prospectos.length}.`);
}
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});
Paso 4. Ejecuta y comprueba
node --env-file=.env primera-peticion.cjs
Resultado esperado: un mensaje de conexión correcta y un número entre 0 y 5. Una lista vacía también es una respuesta válida. Conserva la fecha details.expiracion al incorporar el ejemplo a tu aplicación: las sesiones nuevas duran dos días y se renuevan mediante el intercambio descrito en Autenticación.
Siguiente: crea un prospecto desde un formulario HTML.
Del formulario al CRM
Objetivo: crear un prospecto desde una página HTML con JavaScript, sin instalar un framework. Duración: 10 minutos.
Paso 1. Prepara una prueba local
Obtén un token de sesión siguiendo tu primera petición. Usa una cuenta destinada a pruebas: al enviar el formulario se creará un registro mediante POST /prospectos.
Este formulario es una herramienta local para quien desarrolla la integración. Introducirás tu token de sesión al probarlo; no quedará escrito en el archivo y el ejemplo no lo almacenará en cookies ni almacenamiento local. No uses este patrón para pedir credenciales a visitantes de un formulario público: el código del front-end y sus peticiones son visibles para quien utiliza la página.
Paso 2. Crea el formulario
Copia este documento completo en un archivo llamado formulario.html. Incluye nombre, apellidos, correo y teléfono como texto; tu cuenta puede exigir campos adicionales que deberás agregar según la respuesta de validación.
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mi primer prospecto</title>
</head>
<body>
<h1>Crear un prospecto de prueba</h1>
<form id="formulario">
<p><label>Token de sesión
<input name="token" type="password" required autocomplete="off">
</label></p>
<p><label>Nombre <input name="nombre" required maxlength="128"></label></p>
<p><label>Apellidos <input name="apellidos" required maxlength="128"></label></p>
<p><label>Correo <input name="correo" type="email" required maxlength="256"></label></p>
<p><label>Teléfono <input name="telefono" type="tel" required maxlength="128"></label></p>
<button type="submit">Crear prospecto</button>
</form>
<p id="estado" role="status" aria-live="polite"></p>
<script>
const formulario = document.querySelector("#formulario");
const estado = document.querySelector("#estado");
const boton = formulario.querySelector("button");
formulario.addEventListener("submit", async (evento) => {
evento.preventDefault();
if (boton.disabled) return;
boton.disabled = true;
estado.textContent = "Enviando…";
try {
const campos = new FormData(formulario);
const token = campos.get("token").trim();
const prospecto = {
nombre: campos.get("nombre").trim(),
apellidos: campos.get("apellidos").trim(),
correo: campos.get("correo").trim(),
telefono: campos.get("telefono").trim(),
};
if (!token || !prospecto.nombre || !prospecto.correo) {
throw new Error("Completa el token, el nombre y el correo.");
}
const respuesta = await fetch("https://api.upnify.com/prospectos", {
method: "POST",
headers: { token, "Content-Type": "application/json" },
body: JSON.stringify(prospecto),
});
const datos = await respuesta.json();
const resultado = datos[0];
if (!respuesta.ok || resultado?.code !== 0) {
const detalle = resultado?.fields ? ` Campos: ${resultado.fields}.` : "";
throw new Error((resultado?.msg || `HTTP ${respuesta.status}. Revisa la solicitud.`) + detalle);
}
estado.textContent = "Prospecto creado. Comprueba el registro en Upnify.";
formulario.reset();
} catch (error) {
estado.textContent = `${error.message} Si no se confirmó el envío, revisa Upnify antes de repetirlo.`;
} finally {
boton.disabled = false;
}
});
</script>
</body>
</html>
El navegador valida los campos antes de enviar. JavaScript evita que la página se recargue, envía el token en el encabezado y los datos del prospecto como JSON. El botón queda deshabilitado mientras espera la respuesta para evitar envíos repetidos.
Paso 3. Abre la página y envía un registro
Desde la carpeta donde guardaste el archivo, puedes servirlo con Python 3:
python3 -m http.server 8000 --bind 127.0.0.1
Abre http://127.0.0.1:8000/formulario.html en tu navegador. Introduce tu token de sesión y datos ficticios, por ejemplo nombre Persona, apellidos De prueba, correo persona@example.com y teléfono 0000000000. Pulsa Crear prospecto una sola vez.
Paso 4. Comprueba el resultado
Resultado esperado: aparece “Prospecto creado” y puedes localizar el registro en Upnify. Si la cuenta exige otros datos, completa los campos indicados por el API y vuelve a probar. Si recibes un error de sesión, obtén una sesión vigente; si el navegador muestra un error de red o CORS, revisa la pestaña Red de sus herramientas de desarrollo para confirmar si la solicitud salió y qué respondió el API.
Siguiente: busca un prospecto antes de crearlo.
Busca antes de crear
Objetivo: buscar candidatos por correo y comprobar si hay una coincidencia exacta antes de registrar otro prospecto. Duración: 8 minutos.
Paso 1. Prepara el correo y la sesión
Usaremos GET /sistema/buscar, con secciones=prospectos, y compararemos el campo correo de los resultados. La búsqueda recibe texto de al menos tres caracteres y puede devolver coincidencias parciales. Su respuesta contiene dos listas: [0] incluye los totales por sección y [1] contiene los registros encontrados.
Con Node.js 22 o posterior, crea un archivo .env privado con estos valores, sustituyendo el token ficticio por tu sesión vigente:
UPNIFY_TOKEN_SESION=TOKEN-SESION-EJEMPLO
CORREO_PRUEBA=persona@example.com
Paso 2. Consulta los candidatos
Esta solicitud muestra cómo codificar el correo sin concatenarlo directamente en la URL:
curl --get 'https://api.upnify.com/sistema/buscar' \
--header 'token: TOKEN-SESION-EJEMPLO' \
--data-urlencode 'secciones=prospectos' \
--data-urlencode 'buscar=persona@example.com' \
--data-urlencode 'pagina=1' \
--data-urlencode 'cantidadRegistros=20'
Paso 3. Comprueba el correo exacto
Guarda lo siguiente como buscar-prospecto.cjs. Revisa hasta cinco páginas de candidatos. Si alcanza ese límite sin completar la búsqueda, se detiene sin concluir que el contacto no existe.
async function buscarProspecto(correo, token) {
const normalizar = (valor) => String(valor || "").trim().toLowerCase();
const buscado = normalizar(correo);
for (let pagina = 1; pagina <= 5; pagina += 1) {
const url = new URL("https://api.upnify.com/sistema/buscar");
url.search = new URLSearchParams({
secciones: "prospectos", buscar: buscado,
pagina: String(pagina), cantidadRegistros: "20",
}).toString();
const respuesta = await fetch(url, { headers: { token } });
if (!respuesta.ok) throw new Error(`Búsqueda: HTTP ${respuesta.status}.`);
const datos = await respuesta.json();
const candidatos = datos[1];
if (!Array.isArray(candidatos)) throw new Error("Se esperaba una lista.");
const existente = candidatos.find((p) => normalizar(p.correo) === buscado);
if (existente) return existente;
if (candidatos.length < 20) return null;
}
throw new Error("Búsqueda incompleta: revisa más páginas antes de crear.");
}
async function main() {
const token = process.env.UPNIFY_TOKEN_SESION;
const correo = process.env.CORREO_PRUEBA?.trim();
if (!token || !correo || correo.length < 3) {
throw new Error("Configura una sesión y un correo de prueba válido.");
}
const existente = await buscarProspecto(correo, token);
if (existente) {
// Usa existente.tkProspecto en las operaciones siguientes.
console.log("Coincidencia encontrada: reutiliza el prospecto.");
} else {
console.log("Sin coincidencias exactas en los resultados consultados.");
}
}
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});
Paso 4. Decide la siguiente acción
node --env-file=.env buscar-prospecto.cjs
Resultado esperado: si usas el correo del registro creado en el tutorial anterior, el programa indica una coincidencia y evita una nueva alta. Si no encuentra coincidencias, revisa los resultados y utiliza el formulario cuando corresponda crear el registro.
Esta consulta sólo cubre los prospectos visibles que devuelve la búsqueda; no garantiza unicidad en toda la cuenta. Dos procesos pueden consultar antes de que cualquiera cree el registro. Conserva las validaciones de unicidad de la cuenta y atiende cualquier rechazo del API. Si la búsqueda falla o queda incompleta, no uses ese resultado para autorizar una creación.
Siguiente: consulta por filtros y páginas.
Filtra y pagina prospectos
Objetivo: consultar prospectos de un país y recorrer hasta dos páginas de diez registros. Duración: 5 minutos.
Paso 1. Elige el filtro y el tamaño de página
GET /prospectos acepta el filtro idPais y los parámetros de paginación pagina y cantidadRegistros. En este ejemplo usamos MX y comenzamos en la página 1.
curl --get 'https://api.upnify.com/prospectos' \
--header 'token: TOKEN-SESION-EJEMPLO' \
--data-urlencode 'idPais=MX' \
--data-urlencode 'pagina=1' \
--data-urlencode 'cantidadRegistros=10'
Sustituye el token ficticio por tu sesión vigente. Para pedir la siguiente página, conserva el filtro y el tamaño y cambia únicamente pagina=2.
Paso 2. Recorre dos páginas desde Node.js
Usa Node.js 22 o posterior y un archivo .env privado con UPNIFY_TOKEN_SESION=TOKEN-SESION-EJEMPLO, sustituyendo el valor de ejemplo. Guarda este código como paginar-prospectos.cjs:
async function main() {
const token = process.env.UPNIFY_TOKEN_SESION;
if (!token) throw new Error("Configura UPNIFY_TOKEN_SESION.");
const cantidadRegistros = 10;
let recibidos = 0;
for (let pagina = 1; pagina <= 2; pagina += 1) {
const url = new URL("https://api.upnify.com/prospectos");
url.search = new URLSearchParams({
idPais: "MX", pagina: String(pagina),
cantidadRegistros: String(cantidadRegistros),
}).toString();
const respuesta = await fetch(url, { headers: { token } });
if (!respuesta.ok) throw new Error(`Consulta: HTTP ${respuesta.status}.`);
const prospectos = await respuesta.json();
if (!Array.isArray(prospectos)) throw new Error("Se esperaba una lista.");
recibidos += prospectos.length;
console.log(`Página ${pagina}: ${prospectos.length} registros.`);
// Procesa los prospectos de esta página antes de consultar la siguiente.
if (prospectos.length < cantidadRegistros) break;
}
console.log(`Total recibido en esta práctica: ${recibidos}.`);
}
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});
Paso 3. Ejecuta y observa cuándo termina
node --env-file=.env paginar-prospectos.cjs
Resultado esperado: el programa recibe entre 0 y 20 registros. Si una página tiene menos de diez, termina; si ambas están completas, se detiene en la segunda por el límite de esta práctica. Ese total no representa necesariamente todos los prospectos de la cuenta.
Paso 4. Adapta el ejemplo
Cambia MX por el país que necesites y repite la consulta. Una lista vacía puede significar que no hay prospectos visibles con ese filtro. Para una sincronización mayor, procesa cada página antes de avanzar y contempla que los registros pueden cambiar entre solicitudes; la paginación no representa una fotografía inmutable de la cuenta.
Siguiente: aprende a manejar errores.
Maneja los errores
Objetivo: distinguir cuándo renovar la sesión, corregir datos o esperar antes de reintentar. Duración: 10 minutos.
Paso 1. Lee el estado HTTP y el código del API
Una petición puede fallar aunque fetch no lance una excepción: revisa respuesta.ok, el estado HTTP y el cuerpo JSON. Los errores del API se devuelven como un arreglo; el primer elemento puede incluir code, msg y fields.
| Situación | Cómo reconocerla | Qué hacer |
|---|---|---|
| Sesión vencida | HTTP 401, code: 40003 |
Repite el intercambio con el token de integración y usa la sesión devuelta. |
| Datos incorrectos | Por ejemplo, HTTP 409, code: 2 |
Revisa msg y fields, corrige la solicitud y vuelve a enviarla. |
| Límite de solicitudes | HTTP 429 |
Reduce la frecuencia y espera antes de reintentar. |
| Otro error de acceso | Otro HTTP 401 o HTTP 403 |
Revisa las credenciales o el acceso; no repitas indefinidamente. |
Ejemplo de una respuesta de sesión vencida:
[
{ "code": 40003, "msg": "Sesion expirada." }
]
Paso 2. Prepara ambos tokens
Con Node.js 22 o posterior, coloca en un archivo .env privado tu token de integración y una sesión obtenida mediante Autenticación. Sustituye estos valores ficticios:
UPNIFY_TOKEN_INTEGRACION=TOKEN-INTEGRACION-EJEMPLO
UPNIFY_TOKEN_SESION=TOKEN-SESION-EJEMPLO
Paso 3. Añade reintentos limitados a una consulta
Guarda este código como manejar-errores.cjs. Hace como máximo tres intentos de lectura, renueva una sola vez si la sesión venció y espera uno o dos minutos ante un 429.
const esperar = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function renovarSesion(tokenIntegracion) {
const respuesta = await fetch("https://api.upnify.com/integraciones/sesion", {
method: "POST", headers: { token: tokenIntegracion },
});
if (!respuesta.ok) throw new Error(`Intercambio: HTTP ${respuesta.status}.`);
const [sesion] = await respuesta.json();
if (sesion?.code !== 0 || !sesion.token) {
throw new Error("No se recibió una sesión válida.");
}
return sesion;
}
async function consultarProspectos(token, tokenIntegracion) {
let renovada = false;
for (let intento = 0; intento < 3; intento += 1) {
const respuesta = await fetch(
"https://api.upnify.com/prospectos?pagina=1&cantidadRegistros=5",
{ headers: { token } },
);
const datos = await respuesta.json().catch(() => null);
if (respuesta.ok) {
if (!Array.isArray(datos)) throw new Error("Se esperaba una lista JSON.");
return datos;
}
const errorApi = datos?.[0];
if (respuesta.status === 401 && errorApi?.code === 40003 && !renovada && intento < 2) {
const sesion = await renovarSesion(tokenIntegracion);
token = sesion.token;
renovada = true;
// En tu aplicación, conserva token y sesion.details.expiracion de forma segura.
continue;
}
if (respuesta.status === 429 && intento < 2) {
await esperar(60_000 * (intento + 1));
continue;
}
throw new Error(`HTTP ${respuesta.status}; código ${errorApi?.code ?? "no disponible"}.`);
}
}
async function main() {
const token = process.env.UPNIFY_TOKEN_SESION;
const tokenIntegracion = process.env.UPNIFY_TOKEN_INTEGRACION;
if (!token || !tokenIntegracion) throw new Error("Configura ambos tokens en .env.");
const prospectos = await consultarProspectos(token, tokenIntegracion);
console.log(`Consulta completada: ${prospectos.length} registros.`);
}
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});
Paso 4. Comprueba cada decisión
node --env-file=.env manejar-errores.cjs
Resultado esperado: con una sesión vigente, la consulta termina en el primer intento. Si vence, se intercambia el token y se repite la lectura. Si se agotan los intentos, se muestra el error y el programa termina.
Para practicar los fallos, sustituye fetch por respuestas simuladas: una secuencia 401/40003 → intercambio correcto → 200, otra 429 → 200 y otra 409/2. Comprueba que la última se detenga sin repetir la solicitud. No necesitas generar tráfico para provocar el límite del API.
Antes de aplicarlo a escrituras: un fallo de red no confirma si el servidor creó el registro. No traslades estos reintentos automáticamente a POST /prospectos; primero busca y comprueba el resultado para evitar altas repetidas. Las consultas normales no renuevan la sesión: programa su renovación según Autenticación.
Integraciones
Las integraciones conectan tu aplicación con Upnify para recibir contactos, consultar catálogos, configurar avisos y reservar citas. Cada ficha indica dónde enviar los parámetros, qué devuelve la operación y cómo llamarla desde cURL, JavaScript, Node.js, Python, Go y .NET.
Identificadores y autenticación
Conserva los nombres y valores devueltos por cada operación:
| Valor | Uso |
|---|---|
tkIntegracion |
Identifica una integración para consultarla, configurarla o eliminarla. |
| Token de integración | Autoriza la recepción de contactos y las operaciones que lo solicitan. Conserva el valor completo, incluido su prefijo. Puede aparecer como tkIntegracionSesion al crear una integración o tkSesionIntegracion al consultarla. |
| Token de sesión | Se obtiene intercambiando el token de integración mediante POST /integraciones/sesion. Se envía en el encabezado token de las operaciones que requieren una sesión. |
idFormulario |
Identificador del formulario asociado a una integración, devuelto al crearla o consultarla. |
La ubicación de token depende de la ruta: puede ser un encabezado, un segmento de la URL o un campo del cuerpo. Sigue la ficha de la operación. Guarda los tokens de forma segura y evita registrarlos o exponer las configuraciones que los contienen.
Recepción de contactos
- Consulta los catálogos para obtener los identificadores de fases, orígenes, etiquetas y campos personalizados que necesites.
- Envía el contacto a
POST /integraciones/:tokencon al menoscorreoomovil. Si configuras un mapeo, usa los nombres de entrada esperados por esa configuración. - Revisa
details[0].tkContactoydetails[0].actionpara saber qué contacto se procesó y qué acción se realizó. HTTP 200 por sí solo no confirma que se haya creado un contacto. - Utiliza un
triddistinto por solicitud y conserva ese valor al reintentarla. Si ya aparece en el historial, la respuesta indicaduplicated.
Para modificar un contacto existente, utiliza PUT /integraciones/:token con tkProspecto y los campos admitidos en su ficha. Esta operación puede reactivar el contacto y no admite todos los campos de la recepción inicial.
Calendarios y formularios
Para reservar una cita, consulta primero los horarios con POST /integraciones/calendario, registra o localiza al contacto con POST /integraciones/calendario/prospecto y utiliza los identificadores resultantes en POST /integraciones/calendario/cita. Ofrece únicamente horarios con ocupado: false y comprueba que la reserva devuelva tkCita.
Para cambiar la configuración de una integración, utiliza PUT /integraciones/:tkIntegracion/config.
Lectura de las respuestas
Las fichas distinguen entre respuestas que son arreglos y respuestas que son objetos. Revisa siempre el estado HTTP y el contenido recibido. Los listados paginados indican sus parámetros y, cuando corresponde, el total del encabezado Row-Count.
Algunas configuraciones se envían como texto JSON dentro del cuerpo; la tabla de parámetros lo indica expresamente. En las respuestas normalizadas, esas configuraciones pueden aparecer como objetos JSON. Los ejemplos utilizan datos ficticios que debes sustituir por los de tu integración.
/integraciones/webhooksRegistrar un webhook
DELETE
/integraciones/webhooks/:tkWebhookEliminar un webhook
GET
/integraciones/plantillasConsultar plantillas de integración
POST
/integraciones/plantillasCrear una plantilla de integración
PUT
/integraciones/plantillas/:tkIntegracionPlantillaActualizar una plantilla de integración
DELETE
/integraciones/plantillas/:tkIntegracionPlantillaEliminar una plantilla de integración
POST
/integracionesCrear una integración
POST
/integraciones/sesionObtener o renovar una sesión
POST
/integraciones/valida/:tokenVerificar un token de integración
GET
/integraciones/catalogos/:catalogo/:tokenConsultar un catálogo para integraciones
GET
/integraciones/formulariosConsultar integraciones para formularios
GET
/integracionesListar integraciones de la cuenta
GET
/integraciones/:tkIntegracionConsultar el detalle de una integración
GET
/integraciones/:tkIntegracion/historicoConsultar el historial de una integración
POST
/integraciones/calendarioConsultar horarios de un calendario
POST
/integraciones/calendario/prospectoRegistrar el contacto de una reserva
GET
/integraciones/widgets/:tkWidgetConsultar la configuración de un widget
POST
/integraciones/calendario/citaCrear una cita desde un calendario
POST
/integraciones/:tokenRecibir un contacto desde una integración
PUT
/integraciones/:tokenActualizar un contacto desde una integración
GET
/integraciones/conversiones-datos/:tkIntegracionConsultar conversiones de ventas
PUT
/integraciones/:tkIntegracion/configActualizar la configuración de una integración
DELETE
/integraciones/:tkIntegracionEliminar una integración