API y servidor MCP de LKDN Autopilot
Con la API de LKDN Autopilot, tus programas, tu CRM, tus automatizaciones (n8n, Make, Zapier) y tus asistentes de IA (Claude, ChatGPT) usan tu cuenta de LinkedIn conectada, a través de nosotros: leen las conversaciones y los contactos, buscan personas, envían mensajes y solicitudes de conexión, publican y comentan.
Tres cosas que debes saber antes que nada:
- Una sola cuenta, la tuya. La clave está vinculada a tu cuenta de LKDN Autopilot y a tu cuenta de LinkedIn. No se conectan otras cuentas ni se elige una cuenta: la clave ya sabe cuál es.
- Un solo presupuesto, compartido con el piloto automático. Cada visita, solicitud de conexión, mensaje, comentario, reacción y publicación hecha desde la API consume el mismo presupuesto diario del piloto automático, y lo mismo vale para cada lectura que llega hasta LinkedIn (perfiles, búsquedas, listas, publicaciones, empresas), con los mismos límites y las mismas pausas entre una acción y otra. Si la API usa 5 solicitudes de conexión, el piloto automático tendrá 5 menos ese día. Así es como tu cuenta se mantiene a salvo.
- No guardamos las conversaciones. Cuando lees un chat desde la API, lo leemos en ese momento desde tu cuenta y te lo pasamos. No lo guardamos en nuestros archivos ni en nuestros registros: si necesitas conservarlo, lo conserva tu CRM.
El acceso a la API se activa a petición, por cuenta: escríbenos a info@lkdnautopilot.com.
Índice #
- Empezar en cinco minutos
- Claves y autenticación
- Límites y presupuesto compartido
- Formato de las respuestas
- Idempotency-Key
- Modo simulado
- Endpoints
- Webhook
- Servidor MCP: Claude, ChatGPT, n8n
- Prompts listos para usar
- Errores
- Privacidad y responsabilidad
- Qué no hace
Empezar en cinco minutos #
- En la app ve a API e integraciones (arriba en la página de inicio).
- Crea una clave: un nombre (por ejemplo "mi CRM") y lo que puede hacer, Solo lectura o Lectura y escritura. La clave aparece una sola vez: cópiala y guárdala en un lugar seguro.
- Pruébala:
curl https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/public-api/v1/me \
-H "Authorization: Bearer lkdn_sk_LA_TUA_CHIAVE"
La respuesta es tu perfil, el estado de la conexión y el plan de LinkedIn detectado:
{
"data": {
"id": "per_3mQ8...",
"name": "Giulia Demo",
"headline": "Consulente, Demo Consulting Srl",
"public_identifier": "giulia-demo",
"linkedin_status": "connected",
"linkedin_plan": "premium",
"inmail_credits": 5,
"simulated": false
}
}
La dirección base de todas las llamadas es:
https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/public-api/v1
La especificación OpenAPI completa está en openapi.json: impórtala en Postman, Insomnia o en un generador de clientes.
Claves y autenticación #
Cada solicitud lleva la clave en la cabecera:
Authorization: Bearer lkdn_sk_...
- Una clave tiene uno o dos permisos:
read(leer) ywrite(actuar: mensajes, invitaciones, publicaciones, comentarios, reacciones, visitas, webhooks). Una clave de solo lectura que intenta actuar recibe403 insufficient_scope. - Puedes tener hasta 5 claves activas. Da una clave distinta a cada programa: si hay que revocar una, los demás siguen funcionando.
- La revocación es inmediata: la siguiente solicitud con esa clave recibe
401 invalid_api_key. - Nosotros guardamos solo una huella de la clave (un hash), nunca la clave en sí: si la pierdes, crea una nueva.
- La clave va en un servidor, nunca en una página web ni en una app en el navegador. La API no responde a las llamadas directas desde un navegador.
Límites y presupuesto compartido #
Tu cuenta de LinkedIn tiene un presupuesto diario, igual para el piloto automático y para la API. Lo decidimos en un solo lugar, con las mismas reglas: el plan de LinkedIn detectado, el periodo de calentamiento de una cuenta nueva, los límites que has elegido tú y los que podemos bajar nosotros si la cuenta está en riesgo. La API no puede superarlo, en ningún caso.
| Acción | Valor predeterminado al día | Endpoint |
|---|---|---|
| Visitas con notificación | 30 | POST /v1/people/{id}/visits |
| Solicitudes de conexión | 20 (unas 5 en una cuenta de LinkedIn gratuita), 100 en 7 días | POST /v1/invitations |
| Mensajes | 25 | POST /v1/conversations, POST /v1/conversations/{id}/messages |
| InMail | 3 | POST /v1/conversations con inmail: true |
| Comentarios | 10 | POST /v1/posts/{id}/comments |
| Reacciones | 20 | POST /v1/posts/{id}/reactions |
| Publicaciones | 2 | POST /v1/posts |
| Retirada de solicitudes | 10 | DELETE /v1/invitations/{id} |
| Total de las acciones anteriores | 70 | |
| Perfiles leídos (sin notificación) | 40 | GET /v1/people/{id} |
| Perfiles abiertos en total: visitas y perfiles leídos juntos | 70 | POST /v1/people/{id}/visits, GET /v1/people/{id} |
| Resultados de búsqueda | 300 | POST /v1/searches |
| Listas, publicaciones y páginas leídas | 40 | GET /v1/me (hasta 2), GET /v1/connections, GET /v1/invitations, GET /v1/people/{id}/posts, GET /v1/posts/{id}, GET /v1/posts/{id}/comments, GET /v1/posts/{id}/reactions, GET /v1/companies/{id} |
Las conversaciones y los mensajes (GET /v1/conversations...) no consumen presupuesto: ya están sincronizados desde tu cuenta, sin una solicitud a LinkedIn por cada lectura. Los comentarios y las reacciones leen primero la publicación: esa lectura siempre se cuenta, aunque luego la acción no se realice, pero una acción nunca se rechaza por el presupuesto de lecturas.
Son los valores predeterminados: los de tu cuenta pueden ser más bajos (calentamiento, plan gratuito, límites elegidos por ti). Los reales, los de hoy, están siempre en GET /v1/usage, junto con lo que ya has usado y lo que ha usado la API.
Ningún número, ni siquiera los que podemos subir nosotros a petición, supera el 80% de los límites recomendados para una cuenta de LinkedIn por la infraestructura que usamos para conectarnos: por ejemplo, como máximo 64 solicitudes de conexión al día y 160 en 7 días, 80 perfiles abiertos al día entre visitas y lecturas, 800 resultados de búsqueda al día (2000 con Sales Navigator o Recruiter). La base de datos rechaza cualquier ajuste que supere este margen.
Otras reglas que protegen la cuenta:
- Las acciones están espaciadas. Entre una acción y la siguiente en tu perfil pasan algunos minutos, con un intervalo aleatorio, como haría una persona; de vez en cuando la pausa es más larga (hasta tres cuartos de hora). Si pides una acción demasiado pronto recibes
429 action_pacedconRetry-Afteren segundos. - Las acciones hacia personas nuevas siguen tu horario de actividad. Las visitas, las solicitudes de conexión y los InMail solo se realizan en los días y las horas que has elegido en la app (fuera de horario:
429 outside_activity_window). Los mensajes en las conversaciones, los comentarios, las reacciones y las publicaciones no. - A las personas que no se deben contactar no se las contacta. Quien ha pedido no ser contactado, quien has excluido, quien pertenece a las categorías que no contactamos (por ejemplo el network marketing) recibe
403 person_not_contactable, también desde la API. - A quien contactas desde la API no lo vuelve a contactar el piloto automático. La persona pasa a ser tuya: el piloto automático la omite desde ese momento.
- Un rechazo definitivo de LinkedIn sigue siendo definitivo. Si LinkedIn ya no acepta solicitudes hacia una persona, la API responde
422 invitation_not_allowedy no vuelve a intentarlo. - Cuando LinkedIn pide ir más despacio, la cuenta va más despacio. Si LinkedIn señala demasiadas solicitudes (un
429), todas las acciones y las lecturas se detienen hasta la medianoche de tu zona horaria; si ocurre dos días seguidos, durante 7 días las solicitudes de conexión y los mensajes bajan a la mitad. Si LinkedIn señala el límite de las solicitudes de conexión, las solicitudes se detienen hasta el final del día siguiente. Mientras tanto recibes429 account_backoffconRetry-After, yGET /v1/usageindica el motivo enbackoff. Vale para el piloto automático y para la API a la vez. - Solicitudes a la API: como máximo 60 por minuto por clave y 2000 al día por cuenta, lecturas incluidas (
429 rate_limited,429 daily_request_limit).
Cada 429 tiene la cabecera Retry-After: después de cuántos segundos volver a intentarlo. Cuando el presupuesto del día se ha agotado, Retry-After apunta a la apertura del próximo horario de actividad. Un agente de IA que recibe un 429 debe detenerse y decirlo, no reintentar en bucle.
Formato de las respuestas #
Las respuestas son JSON, con nombres en inglés y siempre los mismos:
- un objeto:
{"data": {...}} - una lista:
{"data": [...], "page": {"next_cursor": "cur_..." }}; para la página siguiente pasacursor=cur_...;next_cursoresnullen la última página. Los cursores caducan después de una hora y solo valen para la lista que los ha dado. - las fechas son ISO 8601 en UTC (
2026-10-25T09:30:00.000Z) y terminan en_at. - los
idson opacos y estables, con un prefijo que dice qué son:per_persona,cnv_conversación,msg_mensaje,inv_solicitud de conexión,pst_publicación,cmt_comentario,cmp_empresa,flt_filtro de búsqueda,whk_webhook. Puedes guardarlos en tu CRM: la misma persona tiene siempre el mismoid. Solo valen para tu cuenta. - donde hacen falta, también están las referencias públicas de LinkedIn:
public_identifier(la parte después delinkedin.com/in/) yprofile_url. degreees el grado de contacto:1,2,3onull(fuera de la red o desconocido).
Cada respuesta tiene la cabecera X-Request-Id: cítala si nos escribes por un problema.
Los errores siguen el estándar RFC 9457 (Content-Type: application/problem+json):
{
"type": "https://lkdnautopilot.com/api-doc/#errori-daily_budget_exhausted",
"title": "The daily budget for this action is used up, by the autopilot and the API together.",
"status": 429,
"code": "daily_budget_exhausted",
"request_id": "req_9f2c...",
"retry_after": 52310
}
El campo que hay que leer en el código es code: es estable y nunca cambia de significado. La lista completa está en Errores.
Idempotency-Key #
Cada solicitud que actúa (POST y DELETE, excepto POST /v1/searches, que es una lectura) requiere la cabecera Idempotency-Key: un valor único elegido por ti, de 8 a 200 caracteres, por ejemplo un UUID.
curl -X POST https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/public-api/v1/invitations \
-H "Authorization: Bearer lkdn_sk_..." \
-H "Idempotency-Key: 6b1f0e5e-2f4a-4c39-9a0e-4d8f2f0a1c11" \
-H "Content-Type: application/json" \
-d '{"person_id": "per_3mQ8...", "message": "Ciao Marco, ho letto il tuo post sulla logistica e mi è piaciuto."}'
- Si repites la misma solicitud con la misma clave (un timeout, un error de red), recibes la misma respuesta y la acción no se repite. La respuesta tiene
Idempotency-Replayed: true. - La misma clave con una solicitud distinta:
422 idempotency_key_reused. - Si la primera solicitud todavía está en curso:
409 idempotency_in_progress. - Si la solicitud no ha actuado (un 429, un 400, un 409 de estado de la cuenta), la clave queda libre y puedes volver a intentarlo con la misma.
- Las claves se recuerdan durante 24 horas.
502 action_outcome_unknown significa que LinkedIn no nos ha dado una respuesta legible y que la acción podría haberse realizado o no. No vuelvas a intentarlo con una clave nueva: comprueba primero (para un mensaje, lee la conversación).
Modo simulado #
Mientras tu cuenta está en preparación, la API responde con datos simulados (personas ficticias) y ninguna acción se realiza de verdad: aun así, las acciones pasan por los límites y quedan registradas. Las respuestas simuladas tienen la cabecera LKDN-Mode: simulated y, para las acciones, "simulated": true. Es la forma adecuada de construir y probar una integración sin tocar a nadie.
Endpoints #
Todas las rutas son relativas a la dirección base. Lectura: permiso read. Acción: permiso write e Idempotency-Key.
Tu cuenta #
GET /v1/me (lectura). Tu perfil, linkedin_status (connected, reconnect_required, not_connected), linkedin_plan (free, premium, sales_navigator), los créditos de InMail. Consume hasta dos lecturas de listas (el perfil y los créditos de InMail).
GET /v1/usage (lectura). El presupuesto de hoy, compartido con el piloto automático:
{
"data": {
"date": "2026-10-25",
"timezone": "Europe/Rome",
"linkedin_plan": "premium",
"invitation_note_available": true,
"requests": { "today": 41, "per_day": 2000, "per_minute": 60 },
"budget": {
"invitations": { "used": 7, "limit": 20, "used_by_api": 2, "weekly_limit": 100 },
"messages": { "used": 3, "limit": 25, "used_by_api": 3 },
"list_reads": { "used": 6, "limit": 40, "used_by_api": 6 },
"profile_retrievals": { "used": 21, "limit": 70, "used_by_api": 4 },
"total_actions": { "used": 18, "limit": 70 }
},
"activity_window": { "open_now": true, "start": "09:00", "end": "18:00", "working_day": true },
"backoff": null,
"shared_with_autopilot": true
}
}
backoff es null, o bien dice por qué hoy la cuenta va más despacio: {"kind": "all_stop" | "invite_stop" | "halved", "reason": "...", "until": "2026-10-26T23:00:00.000Z"} (todo detenido, solicitudes de conexión detenidas, ritmo reducido a la mitad) y hasta cuándo.
Personas #
GET /v1/people/{id} (lectura). Un perfil: id es un per_... o el public_identifier. La persona no recibe ningún aviso. Consume un "perfil leído" (y cuenta en los perfiles abiertos en total). No devuelve correos electrónicos ni teléfonos de otras personas.
POST /v1/people/{id}/visits (acción). Visita el perfil: la persona ve que lo has mirado. Consume una visita.
GET /v1/people/{id}/posts (lectura). Las publicaciones recientes de la persona. limit hasta 50, cursor. Consume una lectura de listas por página.
GET /v1/connections (lectura). Tus contactos de primer grado, del más reciente al más antiguo. q filtra por nombre, limit hasta 200, cursor. Consume una lectura de listas por página.
Búsqueda #
GET /v1/search/filters?type=location&q=verona (lectura). Convierte un lugar (type=location) o un sector (type=industry) en un filtro flt_... para usar en la búsqueda. Úsalo siempre: la búsqueda rechaza un filtro que no venga de aquí (400 invalid_filter), porque LinkedIn ignoraría en silencio un filtro desconocido y te daría resultados de una búsqueda distinta de la que querías.
POST /v1/searches (lectura). Busca personas:
{
"keywords": "logistica",
"titles": ["CFO", "direttore finanziario"],
"locations": ["flt_..."],
"industries": ["flt_..."],
"degree": [2, 3],
"limit": 10
}
Al menos uno entre keywords, titles, locations, industries. limit hasta 10 (hasta 25 con Sales Navigator); cada resultado consume un "resultado de búsqueda". Para la página siguiente repite la misma búsqueda con cursor. La respuesta también tiene page.total_estimate.
Conversaciones #
GET /v1/conversations (lectura). Tus conversaciones, de la más reciente a la más antigua: type (direct o group), participant_id, kind (message, inmail, sponsored, offer), inbox, unread_count, last_activity_at. unread=true para solo las no leídas, limit hasta 100, cursor.
GET /v1/conversations/{id} (lectura). Una conversación.
GET /v1/conversations/{id}/messages (lectura). Los mensajes, del más reciente al más antiguo: text, from_me, sender_id, sent_at, kind, seen, attachments (tipo y nombre, sin enlace). El texto lo leemos desde tu cuenta en ese momento y no lo guardamos.
POST /v1/conversations/{id}/messages (acción). Responde en una conversación uno a uno: {"text": "..."} (hasta 8000 caracteres). Las conversaciones de grupo no son compatibles (422 group_conversation_not_supported).
POST /v1/conversations (acción). Escribe a una persona: {"person_id": "per_...", "text": "..."}. Funciona con los contactos de primer grado (si no, 422 not_first_degree). Para un InMail a alguien que no es un contacto: {"person_id": "per_...", "text": "...", "inmail": true, "subject": "..."}; consume un InMail del presupuesto y un crédito de InMail de tu plan.
Solicitudes de conexión #
GET /v1/invitations?direction=sent (lectura). Las solicitudes que has enviado y están pendientes; direction=received para las recibidas. Consume una lectura de listas por página.
POST /v1/invitations (acción). {"person_id": "per_...", "message": "..."}. La nota (message, hasta 300 caracteres) no está disponible en una cuenta de LinkedIn gratuita (403 invitation_note_not_available): en ese plan la solicitud se envía sin nota. Ya son contactos: 409 already_connected; solicitud ya pendiente: 409 already_invited.
DELETE /v1/invitations/{id} (acción). Retira una solicitud enviada y todavía pendiente.
Publicaciones #
GET /v1/posts/{id} (lectura). Una publicación: id es un pst_..., un URN de LinkedIn (urn:li:activity:...) o el número de la actividad. Consume una lectura de listas.
GET /v1/posts/{id}/comments, GET /v1/posts/{id}/reactions (lectura). Comentarios y reacciones. Consume una lectura de listas por página.
POST /v1/posts (acción). Publica en tu perfil: {"text": "..."} (hasta 3000 caracteres).
POST /v1/posts/{id}/comments (acción). {"text": "...", "reply_to": "cmt_..."}; reply_to para responder a un comentario. El autor de la publicación recibe una notificación.
POST /v1/posts/{id}/reactions (acción). {"type": "like"}; type es uno entre like, celebrate, support, love, insightful, funny.
Empresas #
GET /v1/companies/{id} (lectura). Una página de empresa: id es un cmp_... o el nombre público después de linkedin.com/company/. Consume una lectura de listas.
Webhooks #
GET /v1/webhooks (lectura), POST /v1/webhooks (acción), DELETE /v1/webhooks/{id} (acción). Consulta Webhook.
Webhook #
En lugar de preguntar cada minuto "¿hay novedades?", te llamamos nosotros. Crea un webhook desde la app (API e integraciones) o con:
curl -X POST https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/public-api/v1/webhooks \
-H "Authorization: Bearer lkdn_sk_..." -H "Idempotency-Key: $(uuidgen)" -H "Content-Type: application/json" \
-d '{"url": "https://crm.example.com/hooks/lkdn", "events": ["message.received", "connection.accepted"]}'
La respuesta contiene el secreto de firma (whsec_...) una sola vez.
| Evento | Cuándo | data |
|---|---|---|
message.received | una persona te escribe | conversation_id, message_id, sender_id, sent_at |
connection.accepted | se acepta una solicitud de conexión (puede llegar hasta 8 horas después) | person_id, public_identifier, accepted_at |
invitation.sent | se envía una solicitud de conexión, desde el piloto automático o desde la API | invitation_id, person_id, source (autopilot o api), sent_at |
account.status_changed | la conexión de tu cuenta cambia de estado | status, previous_status, changed_at; estados: connected, connecting, reconnect_required, disconnected, error |
El cuerpo de la llamada:
{
"id": "evt_0b6f1f40000040008000000000000001",
"type": "message.received",
"created_at": "2026-10-25T10:00:03.000Z",
"data": {
"conversation_id": "cnv_...",
"message_id": "msg_...",
"sender_id": "per_...",
"sent_at": "2026-10-25T10:00:00.000Z"
}
}
El texto del mensaje no viaja en el webhook: léelo con GET /v1/conversations/{conversation_id}/messages. Así ningún texto se queda en nuestras colas de envío.
Cada llamada tiene las cabeceras LKDN-Event-Id, LKDN-Event-Type y LKDN-Signature: t=<secondi unix>,v1=<firma>. La firma es el HMAC-SHA256, en hexadecimal, de la cadena <t>.<corpo esatto> con tu secreto. Verifícala siempre y rechaza una llamada con más de 5 minutos de antigüedad:
// Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(secret, rawBody, header, now = Math.floor(Date.now() / 1000)) {
const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? '');
if (!m || Math.abs(now - Number(m[1])) > 300) return false;
const expected = createHmac('sha256', secret).update(`${m[1]}.${rawBody}`).digest('hex');
return timingSafeEqual(Buffer.from(expected), Buffer.from(m[2]));
}
# Python
import hashlib, hmac, re, time
def verify(secret: str, raw_body: str, header: str) -> bool:
m = re.fullmatch(r"t=(\d+),v1=([0-9a-f]{64})", header or "")
if not m or abs(time.time() - int(m.group(1))) > 300:
return False
expected = hmac.new(secret.encode(), f"{m.group(1)}.{raw_body}".encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, m.group(2))
Responde con un código 2xx en un plazo de 10 segundos. Si no, lo volvemos a intentar después de 1, 5 y 30 minutos, luego 2, 6, 12 y 24 horas; después de 8 intentos el evento se pierde, y después de 20 eventos perdidos seguidos el webhook se desactiva (lo vuelves a activar desde la app). Un 410 Gone lo desactiva de inmediato para ese evento. El mismo evento puede llegar dos veces: usa id para reconocerlo. Solo aceptamos direcciones https en el puerto 443, nunca direcciones internas o privadas, y no seguimos las redirecciones.
Servidor MCP: Claude, ChatGPT, n8n #
El servidor MCP expone las mismas funciones como herramientas para un asistente de IA, con la misma clave y los mismos límites: no existe ningún camino que se los salte. Las herramientas que actúan lo dicen en su descripción, y piden al asistente que te muestre el texto exacto y espere tu sí.
Dirección:
https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/mcp
Autenticación: Authorization: Bearer lkdn_sk_.... Para los programas que no permiten configurar una cabecera existe la forma con la clave en la dirección, .../functions/v1/mcp/lkdn_sk_...: trátala como una contraseña, porque quien tiene la dirección tiene la clave. Usa para ello una clave dedicada, y de solo lectura si al asistente le basta con leer.
Herramientas: get_my_profile, get_usage, get_person, visit_profile, list_person_posts, list_connections, find_search_filters, search_people, list_conversations, get_conversation_messages, send_message, start_conversation, list_invitations, send_invitation, withdraw_invitation, get_post, list_post_comments, list_post_reactions, publish_post, comment_on_post, react_to_post, get_company.
Claude Code #
claude mcp add --transport http lkdn-autopilot \
https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/mcp \
--header "Authorization: Bearer lkdn_sk_..."
Claude Desktop #
En Configuración, Desarrollador, Editar configuración (claude_desktop_config.json), con el puente mcp-remote (necesita Node.js):
{
"mcpServers": {
"lkdn-autopilot": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/mcp",
"--header", "Authorization:Bearer ${LKDN_API_KEY}"],
"env": { "LKDN_API_KEY": "lkdn_sk_..." }
}
}
}
Reinicia Claude Desktop: las herramientas aparecen en el menú de herramientas.
Claude.ai (conector personalizado) #
En Configuración, Conectores, Añadir conector personalizado: como URL usa la forma con la clave en la dirección, https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/mcp/lkdn_sk_..., y deja vacíos los campos de OAuth. El conector personalizado está disponible en los planes de Claude que lo incluyen.
ChatGPT #
En Configuración, Aplicaciones y conectores, con el modo desarrollador activado: crea un conector con la URL en la forma con la clave en la dirección y autenticación "ninguna". Las herramientas que actúan piden confirmación antes de ejecutarse.
n8n #
En el nodo MCP Client Tool de un AI Agent: Endpoint https://ayuhpqrbmizgsjstmcrt.supabase.co/functions/v1/mcp, transporte HTTP Streamable, autenticación Bearer con tu clave. Para un flujo sin IA usa el nodo HTTP Request sobre la API REST, con una credencial "Header Auth" (Authorization = Bearer lkdn_sk_...), y un nodo Webhook como destino de nuestros webhooks.
Prompts listos para usar #
Para pegar en Claude o ChatGPT con el servidor MCP conectado.
Las respuestas de hoy
Mira mis conversaciones no leídas de LinkedIn. Para cada una dime quién es la persona (nombre, cargo, empresa),
qué me ha escrito en una línea y si en tu opinión hace falta responder hoy. No respondas a nadie: proponme
un borrador de respuesta solo para las que importan, y espera mi sí para cada texto.
Preparar una reunión
Lee el perfil de LinkedIn de <nombre o enlace> y sus últimas publicaciones. Prepárame cinco líneas: quién es, a qué se
dedica ahora, qué ha escrito recientemente, un punto en común conmigo y una pregunta inteligente para hacerle.
No visites el perfil con notificación y no le escribas.
Encontrar personas para un segmento
Busca en LinkedIn propietarios y directores de clínicas dentales en el Véneto (usa find_search_filters para el lugar).
Muéstrame los 10 primeros en una tabla con nombre, cargo, ciudad y grado de contacto. Antes de buscar dime
cuántos resultados de búsqueda me quedan hoy (get_usage). No envíes solicitudes de conexión.
Solicitudes de conexión con una nota de verdad
Para cada una de estas personas <lista de enlaces>: lee el perfil y escríbeme una nota de conexión de 250 caracteres
como máximo, en italiano, que hable de algo real de su perfil, sin vender nada y sin enlaces.
Muéstrame todas las notas. Envía solo las que apruebe, de una en una, y detente si se agota el presupuesto del día.
Responder a los comentarios de mis publicaciones
Toma mi última publicación (búscala entre las publicaciones de mi perfil) y lee los comentarios. Para los que todavía
no he respondido, proponme una respuesta breve y cordial. Publica solo las respuestas que apruebe.
El resumen de la semana
Dime cuántas solicitudes de conexión tengo pendientes desde hace más de dos semanas y quiénes son. Proponme cuáles
retirar. No retires ninguna sin mi visto bueno.
Reglas que valen para cada prompt: el asistente no debe inventar datos sobre la persona, debe mostrarte cada texto antes de enviarlo, y cuando recibe action_paced, daily_budget_exhausted o outside_activity_window debe detenerse y decírtelo.
Errores #
Cada error tiene un code estable: es un contrato, nunca cambia de significado. Lee el code, no el texto.
| Estado | code | Qué significa, qué hacer |
|---|---|---|
| 400 | invalid_request | falta un campo o no es válido (field, detail dicen cuál) |
| 400 | invalid_cursor | cursor mal formado, caducado o de otra lista: vuelve a empezar desde la primera página |
| 400 | invalid_filter | un filtro de búsqueda no viene de GET /v1/search/filters |
| 400 | idempotency_key_required | falta Idempotency-Key en una solicitud que actúa |
| 401 | invalid_api_key | clave ausente, desconocida o revocada |
| 403 | insufficient_scope | la clave no tiene el permiso write |
| 403 | api_access_not_enabled | la API no está activada para tu cuenta |
| 403 | subscription_inactive | la suscripción no está activa |
| 403 | person_not_contactable | esta persona no debe ser contactada desde esta cuenta |
| 403 | invitation_note_not_available | en tu plan de LinkedIn la solicitud no puede llevar una nota |
| 403 | linkedin_feature_missing | hace falta un producto de LinkedIn que la cuenta no tiene |
| 404 | not_found | el recurso no existe o no es de tu cuenta |
| 404 | route_not_found | el endpoint no existe |
| 405 | method_not_allowed | el endpoint existe, pero no con este método |
| 409 | linkedin_not_connected | ninguna cuenta de LinkedIn conectada: conéctala desde la app |
| 409 | linkedin_reconnect_required | hay que volver a conectar la cuenta desde la app |
| 409 | linkedin_account_unavailable | la cuenta está suspendida por ahora |
| 409 | account_paused | nuestro equipo ha puesto en pausa las acciones de esta cuenta |
| 409 | idempotency_in_progress | la solicitud con esta Idempotency-Key todavía está en curso o no ha terminado |
| 409 | already_connected | ya son contactos |
| 409 | already_invited | ya hay una solicitud pendiente hacia esta persona |
| 422 | idempotency_key_reused | la misma Idempotency-Key con una solicitud distinta |
| 422 | invitation_not_allowed | LinkedIn no permite otra solicitud a esta persona: definitivo |
| 422 | recipient_unreachable | no se puede llegar a la persona |
| 422 | not_first_degree | para un mensaje hace falta un contacto de primer grado: envía una solicitud o un InMail |
| 422 | inmail_not_allowed | a esta persona no se le puede enviar un InMail |
| 422 | insufficient_inmail_credits | créditos de InMail agotados |
| 422 | comments_disabled | los comentarios están cerrados en esta publicación |
| 422 | group_conversation_not_supported | las conversaciones de grupo no son compatibles |
| 422 | action_refused | LinkedIn ha rechazado la acción |
| 422 | invalid_webhook | no se puede crear el webhook (reason dice por qué) |
| 429 | rate_limited | demasiadas solicitudes para esta clave: espera Retry-After |
| 429 | daily_request_limit | solicitudes del día agotadas para esta cuenta |
| 429 | daily_budget_exhausted | el presupuesto del día para esta acción se ha agotado, piloto automático y API juntos |
| 429 | weekly_budget_exhausted | el presupuesto semanal de solicitudes de conexión se ha agotado |
| 429 | action_paced | acciones espaciadas para proteger la cuenta: espera Retry-After |
| 429 | outside_activity_window | fuera de tu horario de actividad |
| 429 | linkedin_rate_limited | LinkedIn está limitando la cuenta en este momento: vuelve a intentarlo más tarde |
| 429 | account_backoff | LinkedIn ha pedido a la cuenta que vaya más despacio: esta acción está en pausa hasta Retry-After |
| 500 | internal_error | un error nuestro |
| 502 | linkedin_error | LinkedIn ha dado una respuesta que no sabemos leer |
| 502 | action_outcome_unknown | la acción podría haberse realizado o no: comprueba antes de volver a intentarlo |
| 503 | api_unavailable | la API está desactivada en este momento |
| 503 | service_not_configured | el servicio todavía no está configurado |
| 503 | linkedin_unavailable | LinkedIn no ha respondido a tiempo: vuelve a intentarlo más tarde |
Privacidad y responsabilidad #
- Mensajes en tránsito. Las conversaciones y los mensajes leídos desde la API pasan por nosotros y te llegan a ti; no los guardamos en nuestros archivos ni en nuestros registros. Lo mismo vale para los textos que envías: mensajes, notas, comentarios y publicaciones van a LinkedIn y no se quedan con nosotros. Del tráfico de la API registramos solo lo que se ha pedido (el tipo de solicitud, el resultado, la duración), durante 90 días, y las acciones realizadas (qué tipo, hacia qué persona, cuándo, sin texto), durante 180 días, porque sirven para hacer respetar los límites.
- El responsable eres tú. Para los datos de las personas que lees y contactas, el responsable del tratamiento eres tú, como con el piloto automático; nosotros somos encargados del tratamiento según el acuerdo (DPA) que has aceptado. Si guardas las conversaciones en tu CRM, esa conservación es tuya.
- Lo que hacen tus programas lo hace tu cuenta. Cada acción hecha con una clave tuya, desde un programa tuyo o desde un asistente de IA que has conectado, se hace en tu nombre y bajo tu responsabilidad, frente a LinkedIn y frente a las personas contactadas, como prevén los Términos del servicio. Mantén las claves a salvo y revoca de inmediato la que creas que ha caído en malas manos.
- Los límites de LinkedIn son reales. A LinkedIn no le gusta el uso automatizado: nuestros límites existen para reducir el riesgo, no lo eliminan. El riesgo de una restricción de la cuenta sigue siendo tuyo.
Qué no hace #
- No conecta otras cuentas, no crea ni elimina conexiones con LinkedIn: la conexión solo se hace desde la app.
- No da acceso libre a LinkedIn: solo las operaciones de esta página, cada una con sus límites.
- Nunca supera los límites de tu cuenta, ni siquiera si se lo pides.
- No guarda tus conversaciones.
- No trabaja con otras plataformas aparte de LinkedIn.