LinkedFlow Docs Abrir la app

API e integraciones

LinkedFlow habla con el resto de tus herramientas por tres caminos: una API REST con token, un webhook que dispara workflows desde fuera y nodos que llaman a lo tuyo desde dentro de un recorrido. Esta página es el contrato exacto, con ejemplos listos para n8n, Make o un curl.

La API que usa la propia app es la API pública: mismos endpoints, misma autenticación. Para una integración no uses el token del navegador: crea un token de API en Ajustes → Tokens de API, con la caducidad que tú elijas y atado a este workspace.

Los tres caminos

CaminoQuién llama a quiénPara qué sirve
API RESTTu herramienta → LinkedFlowCrear prospectos y listas, lanzar workflows, leer ejecuciones, resolver aprobaciones, consultar el funnel.
Webhook entranteTu herramienta → un workflow concretoArrancar un recorrido para un prospecto que ya existe en el CRM, con el token del workflow como credencial.
Nodos de salidaLinkedFlow → tu herramientaAvisar a tu CRM o a n8n a mitad del recorrido (Webhook saliente) o pedirle un dato y seguir con la respuesta (Petición HTTP).

Autenticación

Toda la API vive bajo https://app.linkedflow.pro/api/v1 y se autentica con un token en la cabecera Authorization. Hay dos maneras de conseguirlo, y para integraciones solo sirve la primera.

Token de API (el que quieres para n8n)

En la app, Ajustes → Tokens de API → Nuevo token. Le pones un nombre («n8n · señales diarias»), eliges caducidad —30 días, 90 días, 1 año o sin caducidad— y lo copias: solo se enseña una vez.

PropiedadQué significa
Atado a un workspaceEl del que se creó, y no se puede mover: aunque tú cambies de workspace en la app o alguien mande la cabecera X-Workspace, ese token sigue escribiendo donde se configuró.
Hereda tu rolNo amplía permisos. Si bajas de MANAGER a VIEWER, sus llamadas de escritura empiezan a dar 403.
Sobrevive a tu contraseñaCambiar la contraseña cierra las demás sesiones del navegador, pero no revoca los tokens de API: rotar la contraseña no tumba tus integraciones.
Se revoca al instanteDesde la misma pantalla. Deja de funcionar en la siguiente llamada, y ahí ves también cuándo se usó por última vez.

Consejo: crea un usuario aparte para la máquina («automatizaciones@tuempresa.com») con el rol mínimo que necesite y saca el token desde su cuenta. Así se distingue en la actividad lo que hizo un humano de lo que hizo n8n, y puedes cortarle el acceso sin tocar el tuyo.

Token de sesión (para un script de usar y tirar)

El mismo login de la app devuelve un token, pero caduca a los 30 días y sigue al workspace activo de tu usuario. Vale para probar en un curl; no para una automatización que tiene que aguantar meses:

curl -X POST https://app.linkedflow.pro/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"email":"tu@email.com","password":"tu-contraseña"}'
{
  "user": { "id": "…", "name": "Valen", "current_workspace": { "id": "…", "role": "OWNER" } },
  "token": "198|eMdBPK8g…"
}

A partir de ahí, cada llamada lleva dos cabeceras:

Authorization: Bearer 198|eMdBPK8g…
Accept: application/json

El token es tu contraseña. Guárdalo como credencial en n8n (tipo «Header Auth»: nombre Authorization, valor Bearer <token>), nunca en la URL ni en el cuerpo de un nodo. Si un token de API se te escapa, revócalo desde Ajustes → Tokens de API: es inmediato y no afecta a los demás.

Workspace y roles

No hay que mandar el workspace en ninguna llamada: el token trabaja siempre sobre el workspace actual del usuario. Si perteneces a varios, POST /auth/switch-workspace/{workspace} lo cambia. Cada endpoint exige el mismo rol que la pantalla equivalente de la app (VIEWER < MEMBER < MANAGER < ADMIN < OWNER); si te falta rango, la respuesta es un 403. Los roles están explicados en Ajustes.

Consejo para integraciones: crea un usuario aparte para la máquina («automatizaciones@tuempresa.com») con el rol mínimo que necesite. Así puedes cortarle el acceso sin tocar el tuyo, y en la actividad del workspace se distingue lo que hizo un humano de lo que hizo n8n.

Convenciones

  • Sin Accept: application/json no hay JSON: la app respondería con una redirección o HTML. Es el error número uno al empezar.
  • Errores: 401 sin token o caducado, 403 rol insuficiente o suscripción no activa, 404 fuera de tu workspace, 422 validación ({"message":"…","errors":{"campo":["…"]}}), 429 demasiadas llamadas.
  • Listados: los prospectos vienen paginados (data, current_page, last_page, total); otros recursos devuelven la colección directa o dentro de items. Mira siempre la primera respuesta antes de mapear campos.
  • Idioma: los mensajes de error salen en el idioma de tu usuario. Se puede forzar con Accept-Language: en.
  • Ritmo: no hay un límite global, pero los endpoints caros llevan el suyo (el webhook de workflow, 30 llamadas por minuto; el compositor de IA, 20).

Endpoints principales

La lista completa es la de la app; esto es lo que de verdad se usa desde fuera.

Prospectos y listas

EndpointRolQué hace
GET /prospectsVIEWERListado paginado. Filtros por search, status, list_id, tag.
POST /prospectsMEMBERCrea un prospecto. Acepta list_id para meterlo en una lista de paso.
GET /prospects/{id}VIEWERFicha completa.
PUT /prospects/{id}MEMBEREdita campos (no el estado: ese lo mueve el motor).
POST /prospects/bulk-tagsMEMBEREtiqueta en bloque.
GET /prospects/{id}/conversationVIEWEREl hilo real de LinkedIn.
POST /prospects/{id}/conversation/messagesMANAGEREnvía un DM de verdad (respeta cupos y horario).
GET · POST /listsVIEWER · MEMBERListar y crear listas.
POST /lists/{id}/prospectsMEMBERAñade prospectos existentes a una lista.
POST /suppressionMANAGERManda a alguien a la lista de supresión.

Workflows y ejecuciones

EndpointRolQué hace
GET /workflowsVIEWERListado con estado, versión actual y última ejecución.
POST /workflows/{id}/runMANAGERLanza sobre list_id o prospect_ids[]. Admite account_id y allow_repeat.
POST /workflows/{id}/activate · /pauseMANAGEREnciende o apaga los disparadores.
POST /workflows/{id}/validate · /dry-runMEMBERValida y simula sin tocar LinkedIn.
GET /executions · /executions/{id}VIEWEREjecuciones y su detalle con KPIs por nodo.
GET /prospect-executions/{id}VIEWEREl recorrido de una persona, nodo a nodo.
POST /executions/{id}/cancelMANAGERDetiene lo que quede pendiente.
GET /approvals · POST /approvals/{id}/approveVIEWER · MANAGERBandeja de aprobaciones desde fuera (Slack, por ejemplo).
GET /dashboard/funnel · /stats · /activityVIEWERLos números del dashboard, para tus propios informes.
GET /errors/unmanaged · /pausedVIEWERLo que espera decisión humana. Ideal para una alerta diaria.

La receta que resuelve el 80 %: crear y disparar

Un prospecto nuevo entra en el CRM y, si lo dejas caer en una lista, el workflow que escucha esa lista arranca solo. Son dos llamadas, o incluso una:

curl -X POST https://app.linkedflow.pro/api/v1/prospects \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{
    "linkedin_url": "https://www.linkedin.com/in/alguien",
    "first_name": "Ana",
    "company": "Consultora Norte",
    "tags": ["n8n", "señal:contratando"],
    "source": "n8n",
    "list_id": "01a05d4e-23b2-725c-9aa4-e1ed9e8fd6da"
  }'

¿De dónde sale el list_id? De la app: Prospectos → haz clic en la lista para seleccionarla → botón Copiar ID. Por API, GET /lists devuelve el id de cada una. Es un UUID (01a05d4e-23b2-725c-…); si mandas cualquier otra cosa, la respuesta es un 422 diciendo que list_id no es válido.

Tres cosas que conviene saber de esta llamada:

  • Basta con linkedin_url o public_identifier. Si la URL no es de un perfil, responde 422.
  • El duplicado responde 409 y no es un fallo: devuelve el prospecto que ya existía y lo añade igualmente a la lista. En n8n, configura el nodo para no abortar con 409 — es el camino normal cuando reprocesas una fuente.
  • Al entrar en la lista se dispara el trigger «Al añadir a una lista» de cualquier workflow activo que la escuche, tanto si el prospecto es nuevo como si ya existía y no estaba en ella. Ese es el enganche: n8n no necesita saber nada de workflows, solo llenar una lista.

Un list_id con forma de UUID pero que no existe (o que es de otro workspace) no da error: el prospecto se crea y no entra en ninguna lista. Es aislamiento entre inquilinos —la respuesta no puede servir para averiguar qué listas tiene otro—, así que comprueba el campo lists de la respuesta si quieres estar seguro de que entró donde querías.

Si prefieres lanzar tú explícitamente, usa POST /workflows/{id}/run con {"list_id":"…"} o {"prospect_ids":["…"]}. Requiere rol MANAGER y una versión guardada del workflow.

Webhook entrante: disparar un workflow desde fuera

Un workflow que empieza por el nodo Webhook expone una URL con token propio (visible en el builder, roles MANAGER o superior):

POST https://app.linkedflow.pro/api/v1/webhooks/workflows/{token}
Content-Type: application/json

{ "linkedin_url": "https://www.linkedin.com/in/alguien" }

Identificadores válidos, al menos uno: public_identifier, linkedin_url o email. Lo que mandes de más queda disponible dentro del recorrido como {{trigger.*}}, así que puedes pasar el motivo de la señal y usarlo en el texto del mensaje.

RespuestaSignifica
202 {"status":"accepted"}Recibido. Siempre es esta, exista o no el prospecto y arranque o no el recorrido.
404Token desconocido, workflow no activo, o su primer nodo no es un Webhook.
422No mandaste ningún identificador.

Este endpoint no crea prospectos. Resuelve uno que ya esté en tu CRM; si no lo encuentra, responde 202 igual y no pasa nada. Es deliberado: la respuesta no puede servir para averiguar quién está y quién no está en tu base. Si tu integración trae gente nueva, créala antes con POST /prospects.

El 202 tampoco garantiza que el recorrido empiece: un prospecto suprimido, marcado «no contactar» o que ya te respondió se queda fuera por las protecciones de siempre. Lo que pasó de verdad se ve en Ejecuciones.

Salidas: cuando LinkedFlow llama a tu herramienta

Webhook saliente

El nodo Webhook saliente hace un POST a la URL que le pongas. Si no defines cuerpo, manda este:

{
  "prospect": {
    "id": "01a0…",
    "full_name": "Ana García",
    "linkedin_url": "https://www.linkedin.com/in/…",
    "company": "Consultora Norte",
    "status": "REPLIED"
  },
  "execution_id": "01a0…",
  "node_id": "webhook_1"
}

El POST no va firmado, y el nodo solo tiene dos campos: método y URL. No hay cabeceras ni cuerpo personalizable, así que no puedes mandar una firma ni un secreto en una cabecera. Todo lo que quieras que viaje contigo va en la URL, que sí admite variables:

https://tu-n8n/webhook/respuestas?s=UN-SECRETO-LARGO&cat={{previous.classification}}

En n8n eso llega como {{ $json.query.s }} y {{ $json.query.cat }} — no en headers ni en body. Comprueba el secreto con un nodo Si nada más entrar y descarta lo que no lo traiga: sin esa comprobación, cualquiera que descubra la URL puede inyectarte datos falsos.

Detalles operativos: 15 segundos de tiempo máximo; un 5xx se considera transitorio y se reintenta hasta tres veces con espera creciente; un 4xx se marca como fallo de configuración y espera decisión tuya en la bandeja de errores. Responde rápido y con 200: si tu automatización es lenta, acepta primero y procesa después.

Petición HTTP: pedir un dato y seguir

El nodo Petición HTTP es igual pero pensado para usar la respuesta. Lo que devuelvas queda disponible en el nodo siguiente:

{{previous.status}}              → 200
{{previous.response.tier}}       → "A"   (tu JSON, bajo "response")
{{previous.response.angulo}}     → "contratando SDR"

Con eso un nodo Si bifurca por tu propio scoring: {{previous.response.tier}} == "A". Devuelve siempre un JSON plano y responde en menos de 15 segundos; si tu servicio puede tardar, contesta un valor por defecto antes que hacer esperar al recorrido.

Cinco flujos de n8n que funcionan

1 · Señal externa → contacto (captar)

Schedule a las 7:30 → HTTP Request a tu fuente de señales (posts, cambios de puesto, ofertas de empleo) → Code que normaliza a linkedin_url → Remove Duplicates → HTTP Request a POST /prospects con list_id de «Señales de hoy» y la señal en tags.

En LinkedFlow: un workflow activo con disparador Al añadir a una lista → Leer perfil → Puntuar con IA → Si {{previous.score}} >= 70 → Reaccionar a su último post → Esperar 1 día → Enviar invitación con nota. Configura el nodo de n8n para tratar el 409 como éxito.

2 · Respuesta clasificada → CRM y agenda (atender)

En LinkedFlow: disparador Mensaje recibido → nodo Clasificar respuesta → todas las salidas al mismo Webhook saliente, con la categoría en la URL: ?cat={{previous.classification}}.

En n8n: Webhook → Si que compara {{ $json.query.s }} con tu secreto → Switch por {{ $json.query.cat }}: INTERESTED crea el negocio en tu CRM, avisa por Slack y manda el enlace de agenda; QUESTION redacta un borrador con IA y lo deja en Slack para aprobar; NOT_NOW escribe la fecha de recontacto en una hoja y un cron la reinyecta a los 90 días; DO_NOT_CONTACT llama a POST /suppression y cierra.

3 · «Comenta GUÍA y te la mando»

En LinkedFlow: disparador Comentario en un post con palabra clave → Reaccionar al comentario → Responder al comentario → Enviar mensaje con el enlace → Webhook saliente.

En n8n: alta en tu herramienta de email, fila en una hoja con comentario → entregado → abrió, y a los tres días, si no hubo respuesta, un POST al webhook entrante de un workflow de seguimiento. Recuerda que los comentarios se sondean cada 5 minutos y que responder a un comentario no gasta cupo de mensajes.

4 · Enriquecimiento y scoring propio a mitad de recorrido

Aquí es LinkedFlow quien llama a n8n. En el recorrido: Leer perfil → Petición HTTP a tu webhook de n8n (modo «responder con el último nodo») → Si {{previous.response.tier}} == "A" → invitación con nota personalizada; si no, a una lista de nurturing.

En n8n: Webhook → scrape de la web de la empresa → modelo de IA que devuelve JSON estricto (tier, angulo, dolor) → Respond to Webhook. Pon un fallback (tier: "B") para que un fallo tuyo no atasque el recorrido.

5 · El informe del lunes (vigilar)

Schedule lunes a las 7:00 → GET /dashboard/funnel y GET /executions → GET /errors/unmanaged → un modelo de IA con el prompt «tres decisiones, no tres gráficas» → email. Cero paneles nuevos: los números salen de la misma API que pinta el dashboard.

Descárgalos ya montados

Cuatro workflows de n8n listos para importar desde archivo. Antes de activarlos: crea una credencial Header Auth con nombre Authorization y valor Bearer <tu-token>, y sustituye el id de lista de ejemplo por el tuyo.

Buenas prácticas

  • Deduplica antes de llamar, por linkedin_url y día. Dos POST iguales seguidos no duplican el prospecto, pero sí pueden meterlo dos veces en el flujo si lo sacas y lo vuelves a meter en la lista.
  • No pelees contra los cupos. Da igual lo rápido que empujes: las acciones salen al ritmo de la cuenta (25 visitas, 20 invitaciones y 30 mensajes al día por defecto). Encolar 500 prospectos no acelera nada, solo llena la cola.
  • Registra el execution_id que te llega en los webhooks salientes: es la llave para volver a mirar ese recorrido en la app.
  • Un usuario por integración, con rol mínimo, y rota su token si cambia de manos.

¿Te falta un endpoint? Escríbenos desde el chat de soporte de la app: la lista de lo que se documenta y se abre primero la marcan las integraciones que la gente está montando de verdad.