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.
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.
/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
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 | Sí | Identificador único del prospecto. |
empresa |
string | Sí | 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
[
{
"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ñano coincide con ninguna campaña existente del usuario, el prospecto se importa igualmente pero sin asignar campaña, y se añade un aviso aerrorDetails. Las campañas no se crean automáticamente. - Categorías nuevas: los valores de
sector,vertical,productosycargoque 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 enerrorDetails. - 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: trueyskipped: <N>, más un aviso enerrorDetails.
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)
{
"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.
/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
[
"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)
{
"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.