API REST

Documentación de la API

Integra Affino con tu CRM, ERP, formulario web o herramienta de enriquecimiento. Importa prospectos en bloque y gestiona la lista de bajas desde cualquier sistema externo.

Versión 1.0 JSON · UTF-8 Desarrolladores e integradores

Introducción

La API REST de Affino permite integrar la plataforma de captación comercial con sistemas externos: CRMs, ERPs, formularios web, herramientas de scraping o servicios de enriquecimiento de datos. A través de la API puedes:

  • Importar y actualizar prospectos en bloque, con fusión inteligente de datos cuando el contacto ya existe.
  • Añadir emails o dominios completos a la lista de bajas (lista negra) para evitar futuros envíos.

Todas las peticiones y respuestas utilizan formato JSON y codificación UTF-8.

Autenticación y contexto

Todas las rutas de la API requieren autenticación mediante una clave de API (Bearer Token) y la especificación del usuario destino. Ambos valores se envían como cabeceras HTTP en cada petición.

Cabecera Valor Descripción
Authorization Bearer <TU_API_KEY> Clave de API que te proporciona el equipo de Affino.
X-User-ID <UID_DEL_USUARIO> Identificador único del usuario al que pertenecen los datos.

El valor de X-User-ID se valida contra el sistema de autenticación de Affino. Si el usuario no existe, la petición se rechaza con código 403 Forbidden.

POST /api/prospects

1. Importación de prospectos

Añade o actualiza prospectos en bloque. Si el email ya existe, los datos se fusionan inteligentemente.

Cabeceras

HTTP
Authorization: Bearer <TU_API_KEY>
X-User-ID: <UID_DEL_USUARIO>
Content-Type: application/json

Cuerpo de la petición

El cuerpo debe ser un array de objetos JSON. Las claves deben estar en minúsculas exactas y sin acentos (salvo campaña, que lleva la ñ).

Campo Tipo Obligatorio Descripción
email string Identificador único del prospecto.
empresa string Nombre de la empresa.
nombre string No Nombre del contacto.
web string No Sitio web de la empresa.
telefono string No Teléfono de contacto.
cargo string No Cargo del contacto.
linkedin string No Perfil de LinkedIn.
sector string No Sector de actividad.
vertical string No Vertical de negocio.
productos string No Productos, separados por comas.
campaña string No Debe coincidir con una campaña existente del usuario (ver «Comportamiento»).
etapa string No Etapa del pipeline: prospectos, con_respuesta, etc.
notas string No Notas libres sobre el prospecto.

Cualquier clave adicional no listada arriba se guardará automáticamente dentro del campo notas como JSON.

Ejemplo de petición

JSON
[
  {
    "nombre": "Ana García",
    "email": "ana.garcia@tecnosol.com",
    "empresa": "TecnoSoluciones",
    "cargo": "directora de marketing",
    "productos": "servicio cloud, soporte premium"
  }
]

Comportamiento

  • Crear vs. actualizar: si el email ya existe, el prospecto se actualiza (fusión de datos; los productos se combinan sin duplicar). Si no existe, se crea.
  • Campaña inexistente — no bloquea la fila: si el valor de campaña no coincide con ninguna campaña existente del usuario, el prospecto se importa igualmente pero sin asignar campaña, y se añade un aviso a errorDetails. Las campañas no se crean automáticamente.
  • Categorías nuevas: los valores de sector, vertical, productos y cargo que no existían se añaden automáticamente a la configuración del usuario.
  • Emails inválidos: las filas con un email mal formado (sin @ o sin punto en el dominio) se omiten, con un aviso en errorDetails.
  • Tope de contactos según tu plan: al alcanzar el límite del plan, los prospectos nuevos excedentes se omiten (no se crean); las actualizaciones de existentes no cuentan para el tope. La respuesta incluye entonces limitReached: true y skipped: <N>, más un aviso en errorDetails.

Respuestas

Código Significado
200 OK Importación procesada. Ver ejemplo de respuesta a continuación.
400 Bad Request El cuerpo no es un array JSON válido, falta X-User-ID, o la importación falló entera por validación.
401 Unauthorized Clave de API faltante o incorrecta.
403 Forbidden El X-User-ID no corresponde a un usuario existente.
500 Internal Server Error Error inesperado en el servidor.

Ejemplo de respuesta (200 OK)

JSON
{
  "message": "Importación procesada correctamente.",
  "created": 12,
  "updated": 3,
  "errors": 1,
  "errorDetails": [
    "Email x@y.com: La campaña 'Z' no existe y no se asignará."
  ]
}

errors es el número de avisos; created y updated pueden ser mayores que 0 aunque haya avisos. Si se alcanzó el tope de contactos del plan, se añaden los campos limitReached y skipped.

POST /api/blacklist

2. Añadir a la lista de bajas

Añade emails (o dominios completos) a la lista negra para evitar futuros envíos.

Cuerpo de la petición

El cuerpo debe ser un array de strings. Cada string puede ser:

  • Un email concreto: "email.a.bloquear@dominio.com".
  • Un dominio completo, anteponiendo @: "@dominio.com" bloquea todos los emails de ese dominio (se almacena sin la @).

Ejemplo de petición

JSON
[
  "email.a.bloquear@dominio.com",
  "@competencia.com"
]

Cada valor se normaliza a minúsculas. Se descartan (con aviso) los valores sin un . o con espacios.

Respuestas

Código Significado
200 OK Lista procesada. Ver ejemplo de respuesta a continuación.
400 Bad Request El cuerpo no es un array de strings, falta X-User-ID, o ningún valor era válido.
401 Unauthorized Clave de API faltante o incorrecta.
403 Forbidden El X-User-ID no corresponde a un usuario existente.

Ejemplo de respuesta (200 OK)

JSON
{
  "message": "Lista de bajas procesada correctamente.",
  "imported": 2,
  "errors": 0,
  "errorDetails": []
}

Códigos de error generales

Código Descripción
400 Bad Request Formato JSON inválido, falta X-User-ID o error de validación.
401 Unauthorized Clave de API faltante o incorrecta.
403 Forbidden El usuario indicado en X-User-ID no existe.
500 Internal Server Error Error inesperado en el servidor.

Soporte

Si tienes dudas durante la integración o necesitas una clave de API, contacta con el equipo de Affino y te la haremos llegar junto con tu X-User-ID.