Cómo Usar la API de LinkedIn: Guía Completa de Integración Profesional (2026)

Ashley Innocent

Ashley Innocent

25 March 2026

Cómo Usar la API de LinkedIn: Guía Completa de Integración Profesional (2026)

TL;DR

La API de LinkedIn permite a los desarrolladores integrarse programáticamente con la red profesional de LinkedIn. Utiliza autenticación OAuth 2.0, puntos finales RESTful y GraphQL para perfiles, publicaciones, comentarios, páginas de empresa y anuncios, con límites de tasa de 100-500 solicitudes por día por aplicación. Esta guía cubre la configuración de la autenticación, el acceso al perfil, la publicación de contenido, la gestión de páginas de empresa, la API de anuncios y las estrategias de integración en producción.

Introducción

LinkedIn tiene más de 900 millones de usuarios profesionales en más de 200 países. Para los desarrolladores que crean herramientas de reclutamiento, plataformas de marketing o aplicaciones B2B, la integración de la API de LinkedIn es esencial para llegar a esta audiencia profesional.

Esta es la realidad: los especialistas en marketing B2B que gestionan manualmente la presencia en LinkedIn pierden de 15 a 20 horas semanales en la publicación, el seguimiento del engagement y la generación de leads. Una sólida integración de la API de LinkedIn automatiza la distribución de contenido, la captura de leads, el análisis del engagement y los flujos de trabajo de reclutamiento.

Esta guía le guiará a través del proceso completo de integración de la API de LinkedIn. Aprenderá sobre la autenticación OAuth 2.0, el acceso al perfil, la publicación de contenido, la gestión de páginas de empresa, la integración de anuncios, los webhooks y las estrategias de implementación en producción. Al final, tendrá una integración de LinkedIn lista para producción.

💡
Apidog simplifica las pruebas de integración de API. Pruebe sus puntos finales de LinkedIn, valide los flujos de OAuth, inspeccione las respuestas de la API y depure los problemas de permisos en un solo espacio de trabajo. Importe especificaciones de API, simule respuestas y comparta escenarios de prueba con su equipo.
botón

¿Qué es la API de LinkedIn?

LinkedIn proporciona APIs RESTful y GraphQL para acceder a los datos de la red profesional. La API maneja:

Características Clave

Característica Descripción
RESTful + GraphQL Múltiples estilos de API
OAuth 2.0 Requiere autorización de usuario
Límite de Tasa 100-500 solicitudes/día por aplicación
Páginas de Empresa Operaciones CRUD completas
API de Anuncios Gestión de campañas
Webhooks Notificaciones en tiempo real
Carga de Medios Imágenes y vídeos

Productos de la API

API Nivel de Acceso Caso de Uso
Iniciar Sesión con LinkedIn Abierto Autenticación de usuario
API de Perfil Socio Leer perfil de usuario
API de Administración de Empresa Socio Gestionar páginas de empresa
API de Anuncios Socio Gestión de campañas publicitarias
API de Publicación de Empleos Socio Publicar y gestionar empleos
Plataforma de Desarrolladores de Marketing Socio Acceso completo a la API

Versiones de la API

Versión Estado Fecha de Finalización
v2 Actual Activa
v1 Retirada Diciembre de 2023

Primeros Pasos: Configuración de la Autenticación

Paso 1: Crear una Cuenta de Desarrollador de LinkedIn

Antes de acceder a la API:

  1. Visite el Portal de Desarrolladores de LinkedIn
  2. Inicie sesión con su cuenta de LinkedIn
  3. Haga clic en Crear Aplicación en el panel de control de Mis Aplicaciones
  4. Rellene los detalles de la aplicación (nombre, logotipo, descripción)

Paso 2: Configurar los Ajustes de la Aplicación

Configure la autenticación de la aplicación:

const LINKEDIN_CLIENT_ID = process.env.LINKEDIN_CLIENT_ID;
const LINKEDIN_CLIENT_SECRET = process.env.LINKEDIN_CLIENT_SECRET;
const LINKEDIN_REDIRECT_URI = process.env.LINKEDIN_REDIRECT_URI;

// Obtenga estos datos del panel de su aplicación
// https://www.linkedin.com/developers/apps/{appId}/auth

Paso 3: Solicitar los Permisos Necesarios

LinkedIn requiere aprobación de permisos:

Permiso Descripción Aprobación Requerida
r_liteprofile Perfil básico (nombre, foto) Aprobación automática
r_emailaddress Dirección de correo electrónico Aprobación automática
w_member_social Publicar en nombre del usuario Verificación de socio
r_basicprofile Perfil completo Verificación de socio
r_organization_social Acceso a página de empresa Verificación de socio
w_organization_social Publicar en página de empresa Verificación de socio
rw_ads Gestión de anuncios Verificación de socio
r_ads_reporting Análisis de anuncios Verificación de socio

Paso 4: Construir la URL de Autorización

Implemente el flujo de OAuth 2.0:

const getAuthUrl = (state, scopes = ['r_liteprofile', 'r_emailaddress']) => {
  const params = new URLSearchParams({
    response_type: 'code',
    client_id: LINKEDIN_CLIENT_ID,
    redirect_uri: LINKEDIN_REDIRECT_URI,
    scope: scopes.join(' '),
    state: state
  });

  return `https://www.linkedin.com/oauth/v2/authorization?${params.toString()}`;
};

// Uso
const state = require('crypto').randomBytes(16).toString('hex');
const authUrl = getAuthUrl(state, ['r_liteprofile', 'r_emailaddress', 'w_member_social']);
console.log(`Redirigir usuario a: ${authUrl}`);

Paso 5: Intercambiar el Código por un Token de Acceso

Manejar la devolución de llamada de OAuth:

const exchangeCodeForToken = async (code) => {
  const response = await fetch('https://www.linkedin.com/oauth/v2/accessToken', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code: code,
      client_id: LINKEDIN_CLIENT_ID,
      client_secret: LINKEDIN_CLIENT_SECRET,
      redirect_uri: LINKEDIN_REDIRECT_URI
    })
  });

  const data = await response.json();

  return {
    accessToken: data.access_token,
    expiresIn: data.expires_in // 60 días
  };
};

// Manejar la devolución de llamada
app.get('/oauth/callback', async (req, res) => {
  const { code, state } = req.query;

  try {
    const tokens = await exchangeCodeForToken(code);

    // Almacenar tokens de forma segura
    await db.users.update(req.session.userId, {
      linkedin_access_token: tokens.accessToken,
      linkedin_token_expires: Date.now() + (tokens.expiresIn * 1000)
    });

    res.redirect('/success');
  } catch (error) {
    console.error('Error de OAuth:', error);
    res.status(500).send('Autenticación fallida');
  }
});

Paso 6: Refrescar el Token de Acceso

Los tokens de acceso expiran después de 60 días:

const refreshAccessToken = async (refreshToken) => {
  // Nota: LinkedIn no proporciona tokens de refresco
  // Los usuarios deben volver a autenticarse después de 60 días
  // Implementar notificación de caducidad
};

// Verificar la caducidad del token antes de las llamadas a la API
const ensureValidToken = async (userId) => {
  const user = await db.users.findById(userId);

  if (user.linkedin_token_expires < Date.now() + 86400000) { // 24 horas
    // Notificar al usuario para que vuelva a autenticarse
    await notifyUserToReauth(user.id);
    throw new Error('Token expirado, por favor, vuelva a autenticarse');
  }

  return user.linkedin_access_token;
};

Paso 7: Realizar Llamadas Autenticadas a la API

Crear cliente de API reutilizable:

const LINKEDIN_BASE_URL = 'https://api.linkedin.com/v2';

const linkedinRequest = async (endpoint, options = {}) => {
  const accessToken = await ensureValidToken(options.userId);

  const response = await fetch(`${LINKEDIN_BASE_URL}${endpoint}`, {
    ...options,
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      'X-Restli-Protocol-Version': '2.0.0',
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Error de la API de LinkedIn: ${error.message}`);
  }

  return response.json();
};

// Uso
const profile = await linkedinRequest('/me');
console.log(`Hola, ${profile.localizedFirstName} ${profile.localizedLastName}`);

Acceso al Perfil

Obtener el Perfil del Usuario

Obtener el perfil del usuario autenticado:

const getUserProfile = async () => {
  const response = await linkedinRequest('/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))');
  return response;
};

// Uso
const profile = await getUserProfile();

console.log(`Nombre: ${profile.localizedFirstName} ${profile.localizedLastName}`);
console.log(`ID: ${profile.id}`);
console.log(`Foto: ${profile.profilePicture?.['displayImage~']?.elements?.[0]?.identifiers?.[0]?.identifier}`);

Obtener la Dirección de Correo Electrónico

Obtener el correo electrónico del usuario:

const getUserEmail = async () => {
  const response = await linkedinRequest('/emailAddress?q=members&projection=(emailAddress*)');
  return response;
};

// Uso
const email = await getUserEmail();
console.log(`Correo electrónico: ${email.elements?.[0]?.emailAddress}`);

Campos de Perfil Disponibles

Campo Permiso Descripción
id r_liteprofile ID de miembro de LinkedIn
firstName r_liteprofile Nombre
lastName r_liteprofile Apellido
profilePicture r_liteprofile URL de la foto de perfil
headline r_basicprofile Titular profesional
summary r_basicprofile Sección "Acerca de"
positions r_basicprofile Historial laboral
educations r_basicprofile Historial educativo
emailAddress r_emailaddress Correo electrónico principal

Publicación de Contenido

Crear una Publicación

Compartir publicación de texto en el feed del usuario:

const createPost = async (authorUrn, postContent) => {
  const response = await linkedinRequest('/ugcPosts', {
    method: 'POST',
    body: JSON.stringify({
      author: authorUrn,
      lifecycleState: 'PUBLISHED',
      specificContent: {
        'com.linkedin.ugc.ShareContent': {
          shareCommentary: {
            text: postContent.text
          },
          shareMediaCategory: 'NONE'
        }
      },
      visibility: {
        'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
      }
    })
  });

  return response;
};

// Uso
const post = await createPost('urn:li:person:ABC123', {
  text: '¡Emocionados de anunciar el lanzamiento de nuestro nuevo producto! 🚀 #innovación #startup'
});

console.log(`Publicación creada: ${post.id}`);

Crear una Publicación con Imagen

Compartir publicación con medios:

const createPostWithImage = async (authorUrn, postData) => {
  // Paso 1: Registrar la carga de medios
  const uploadRegistration = await linkedinRequest('/assets?action=registerUpload', {
    method: 'POST',
    body: JSON.stringify({
      registerUploadRequest: {
        recipes: ['urn:li:digitalmediaRecipe:feedshare-image'],
        owner: authorUrn,
        serviceRelationships: [
          {
            relationshipType: 'OWNER',
            identifier: 'urn:li:userGeneratedContent'
          }
        ]
      }
    })
  });

  const uploadUrl = uploadRegistration.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl;
  const assetUrn = uploadRegistration.value.asset;

  // Paso 2: Subir imagen a la URL proporcionada
  await fetch(uploadUrl, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + await getAccessToken(),
      'Content-Type': 'application/octet-stream'
    },
    body: postData.imageBuffer
  });

  // Paso 3: Crear publicación con la imagen subida
  const post = await linkedinRequest('/ugcPosts', {
    method: 'POST',
    body: JSON.stringify({
      author: authorUrn,
      lifecycleState: 'PUBLISHED',
      specificContent: {
        'com.linkedin.ugc.ShareContent': {
          shareCommentary: {
            text: postData.text
          },
          shareMediaCategory: 'IMAGE',
          media: [
            {
              status: 'READY',
              description: {
                text: postData.imageDescription || ''
              },
              media: assetUrn,
              title: {
                text: postData.title || ''
              }
            }
          ]
        }
      },
      visibility: {
        'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
      }
    })
  });

  return post;
};

Crear una Publicación con Vídeo

Compartir contenido de vídeo:

const createPostWithVideo = async (authorUrn, postData) => {
  // Registrar la carga de vídeo
  const uploadRegistration = await linkedinRequest('/assets?action=registerUpload', {
    method: 'POST',
    body: JSON.stringify({
      registerUploadRequest: {
        recipes: ['urn:li:digitalmediaRecipe:feedshare-video'],
        owner: authorUrn,
        serviceRelationships: [
          {
            relationshipType: 'OWNER',
            identifier: 'urn:li:userGeneratedContent'
          }
        ]
      }
    })
  });

  const assetUrn = uploadRegistration.value.asset;

  // Subir vídeo (usar URLs de carga pre-firmadas de la respuesta)
  // ... lógica de carga ...

  // Crear publicación
  const post = await linkedinRequest('/ugcPosts', {
    method: 'POST',
    body: JSON.stringify({
      author: authorUrn,
      lifecycleState: 'PUBLISHED',
      specificContent: {
        'com.linkedin.ugc.ShareContent': {
          shareCommentary: { text: postData.text },
          shareMediaCategory: 'VIDEO',
          media: [{ status: 'READY', media: assetUrn }]
        }
      },
      visibility: { 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' }
    })
  });

  return post;
};

Especificaciones de Medios

Tipo de Medio Formato Tamaño Máx. Duración
Imagen JPG, PNG, GIF 8MB N/A
Vídeo MP4, MOV 5GB 15 min máx.
Documento PDF, PPT, DOC 100MB N/A

Gestión de Páginas de Empresa

Obtener Información de la Empresa

Obtener los detalles de la página de empresa:

const getCompanyInfo = async (companyId) => {
  const response = await linkedinRequest(
    `/organizations/${companyId}?projection=(id,localizedName,vanityName,tagline,description,universalName,logoV2(original~:playableStreams),companyType,companyPageUrl,confirmedLocations,industries,followerCount,staffCountRange,website, specialties)`
  );
  return response;
};

// Uso
const company = await getCompanyInfo('1234567');
console.log(`Empresa: ${company.localizedName}`);
console.log(`Seguidores: ${company.followerCount}`);
console.log(`Sitio web: ${company.website}`);

Publicar en la Página de Empresa

Compartir actualización en la página de empresa:

const createCompanyPost = async (organizationUrn, postContent) => {
  const response = await linkedinRequest('/ugcPosts', {
    method: 'POST',
    body: JSON.stringify({
      author: organizationUrn,
      lifecycleState: 'PUBLISHED',
      specificContent: {
        'com.linkedin.ugc.ShareContent': {
          shareCommentary: {
            text: postContent.text
          },
          shareMediaCategory: postContent.media ? 'IMAGE' : 'NONE',
          media: postContent.media ? [
            {
              status: 'READY',
              media: postContent.media.assetUrn
            }
          ] : []
        }
      },
      visibility: {
        'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
      }
    })
  });

  return response;
};

// Uso
const post = await createCompanyPost('urn:li:organization:1234567', {
  text: '¡Estamos contratando! Únase a nuestro creciente equipo. #carreras #contratación'
});

Obtener Seguidores de la Empresa

Obtener el recuento de seguidores:

const getFollowerCount = async (organizationId) => {
  const response = await linkedinRequest(
    `/organizationalEntityFollowerStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:${organizationId}`
  );
  return response;
};

Límites de Tasa

Comprendiendo los Límites de Tasa

LinkedIn aplica límites de tasa por aplicación:

API Límite Ventana
API de Perfil 100 solicitudes Por día
Publicaciones UGC 50 publicaciones Por día
Administración de Empresa 500 solicitudes Por día
API de Anuncios 100 solicitudes Por minuto

Cabeceras de Límite de Tasa

Cabecera Descripción
X-Restli-Quota-Remaining Solicitudes restantes
X-Restli-Quota-Reset Segundos hasta el reinicio

Resolución de Problemas Comunes

Problema: 401 No Autorizado

Soluciones:

  1. Verifique que el token de acceso no haya expirado (60 días)
  2. Compruebe que el alcance del token incluye el recurso solicitado
  3. Asegúrese de que la cabecera Authorization: Bearer {token} esté presente

Problema: 403 Prohibido

Soluciones:

  1. Verifique que la aplicación tenga los permisos necesarios
  2. Compruebe que el usuario aprobó los ámbitos solicitados
  3. Puede ser necesaria la verificación de socio

Problema: 429 Límite de Tasa Alcanzado

Soluciones:

  1. Implementar cola de solicitudes
  2. Almacenar en caché las respuestas para reducir las llamadas
  3. Usar webhooks en lugar de sondeo

Lista de Verificación de Implementación en Producción

Antes de salir en vivo:

Casos de Uso en el Mundo Real

Plataforma de Reclutamiento

Una herramienta de reclutamiento automatiza las publicaciones de empleo:

Automatización de Marketing B2B

Una plataforma de marketing programa contenido de LinkedIn:

Conclusión

La API de LinkedIn proporciona un acceso completo a las características de la red profesional. Puntos clave:

botón

Sección de Preguntas Frecuentes

¿Cómo obtengo acceso a la API de LinkedIn?

Cree una cuenta de desarrollador de LinkedIn, cree una aplicación y complete la verificación de socio para obtener acceso avanzado a la API.

¿Puedo publicar en LinkedIn automáticamente?

Sí, utilice la API UGC (Contenido Generado por el Usuario) con el permiso w_member_social para publicaciones personales o w_organization_social para publicaciones de empresa.

¿Cuáles son los límites de tasa de LinkedIn?

Los límites de tasa varían de 100 a 500 solicitudes por día, dependiendo de la API. La API de Anuncios permite 100 solicitudes por minuto.

¿Cuánto tiempo duran los tokens de LinkedIn?

Los tokens de acceso expiran después de 60 días. Los usuarios deben volver a autenticarse para continuar con el acceso a la API.

¿Puedo acceder a las conexiones de los usuarios?

No, LinkedIn eliminó el acceso a la API de conexiones para la mayoría de las aplicaciones debido a cambios de privacidad.

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs