Comment Utiliser l'API LinkedIn: Guide Complet d'Intégration du Réseau Professionnel (2026)

Ashley Innocent

Ashley Innocent

25 March 2026

Comment Utiliser l'API LinkedIn: Guide Complet d'Intégration du Réseau Professionnel (2026)

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

En bref

L'API LinkedIn permet aux développeurs d'intégrer leur application au réseau professionnel de LinkedIn de manière programmatique. Elle utilise l'authentification OAuth 2.0, des points de terminaison RESTful et GraphQL pour les profils, les publications, les commentaires, les pages d'entreprise et les publicités, avec des limitations de débit de 100 à 500 requêtes par jour et par application. Ce guide couvre la configuration de l'authentification, l'accès au profil, la publication de contenu, la gestion des pages d'entreprise, l'API publicitaire et les stratégies d'intégration en production.

Introduction

LinkedIn compte plus de 900 millions d'utilisateurs professionnels dans plus de 200 pays. Pour les développeurs qui créent des outils de recrutement, des plateformes marketing ou des applications B2B, l'intégration de l'API LinkedIn est essentielle pour atteindre ce public professionnel.

Voici la réalité : les spécialistes du marketing B2B gérant manuellement leur présence sur LinkedIn perdent 15 à 20 heures par semaine à publier, suivre l'engagement et générer des prospects. Une solide intégration de l'API LinkedIn automatise la distribution de contenu, la capture de prospects, l'analyse de l'engagement et les flux de travail de recrutement.

Ce guide vous accompagne tout au long du processus complet d'intégration de l'API LinkedIn. Vous apprendrez l'authentification OAuth 2.0, l'accès au profil, la publication de contenu, la gestion des pages d'entreprise, l'intégration des publicités, les webhooks et les stratégies de déploiement en production. À la fin, vous disposerez d'une intégration LinkedIn prête pour la production.

💡
Apidog simplifie les tests d'intégration d'API. Testez vos points de terminaison LinkedIn, validez les flux OAuth, inspectez les réponses API et déboguez les problèmes d'autorisation dans un seul espace de travail. Importez des spécifications API, simulez des réponses et partagez des scénarios de test avec votre équipe.

bouton

Qu'est-ce que l'API LinkedIn ?

LinkedIn fournit des API RESTful et GraphQL pour accéder aux données du réseau professionnel. L'API gère :

Fonctionnalités clés

Fonctionnalité Description
RESTful + GraphQL Plusieurs styles d'API
OAuth 2.0 Autorisation utilisateur requise
Rate Limiting 100-500 requêtes/jour par application
Company Pages Opérations CRUD complètes
Ads API Gestion des campagnes
Webhooks Notifications en temps réel
Media Upload Images et vidéos

Produits API

API Niveau d'accès Cas d'utilisation
Sign In with LinkedIn Ouvert Authentification utilisateur
Profile API Partenaire Lire le profil utilisateur
Company Admin API Partenaire Gérer les pages d'entreprise
Ads API Partenaire Gestion des campagnes publicitaires
Job Posting API Partenaire Publier et gérer des offres d'emploi
Marketing Developer Platform Partenaire Accès API complet

Versions de l'API

Version Statut Date de fin
v2 Actuelle Active
v1 Retirée Décembre 2023

Démarrage : Configuration de l'authentification

Étape 1 : Créer un compte développeur LinkedIn

Avant d'accéder à l'API :

  1. Visitez le Portail développeur LinkedIn
  2. Connectez-vous avec votre compte LinkedIn
  3. Cliquez sur Créer une application dans le tableau de bord Mes applications
  4. Remplissez les détails de l'application (nom, logo, description)

Étape 2 : Configurer les paramètres de l'application

Configurez l'authentification de l'application :

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;

// Get these from your app dashboard
// https://www.linkedin.com/developers/apps/{appId}/auth

Étape 3 : Demander les autorisations requises

LinkedIn exige l'approbation des autorisations :

Permission Description Approbation requise
r_liteprofile Profil de base (nom, photo) Approuvé automatiquement
r_emailaddress Adresse e-mail Approuvé automatiquement
w_member_social Publier au nom de l'utilisateur Vérification partenaire
r_basicprofile Profil complet Vérification partenaire
r_organization_social Accès aux pages d'entreprise Vérification partenaire
w_organization_social Publier sur une page d'entreprise Vérification partenaire
rw_ads Gestion des publicités Vérification partenaire
r_ads_reporting Analyse des publicités Vérification partenaire

Étape 4 : Construire l'URL d'autorisation

Implémenter le flux 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()}`;
};

// Usage
const state = require('crypto').randomBytes(16).toString('hex');
const authUrl = getAuthUrl(state, ['r_liteprofile', 'r_emailaddress', 'w_member_social']);
console.log(`Redirect user to: ${authUrl}`);

Étape 5 : Échanger le code contre un jeton d'accès

Gérer le rappel 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 days
  };
};

// Handle callback
app.get('/oauth/callback', async (req, res) => {
  const { code, state } = req.query;

  try {
    const tokens = await exchangeCodeForToken(code);

    // Store tokens securely
    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('OAuth error:', error);
    res.status(500).send('Authentication failed');
  }
});

Étape 6 : Actualiser le jeton d'accès

Les jetons d'accès expirent après 60 jours :

const refreshAccessToken = async (refreshToken) => {
  // Note: LinkedIn doesn't provide refresh tokens
  // Users must re-authenticate after 60 days
  // Implement expiry notification
};

// Check token expiry before API calls
const ensureValidToken = async (userId) => {
  const user = await db.users.findById(userId);

  if (user.linkedin_token_expires < Date.now() + 86400000) { // 24 hours
    // Notify user to re-authenticate
    await notifyUserToReauth(user.id);
    throw new Error('Token expired, please re-authenticate');
  }

  return user.linkedin_access_token;
};

Étape 7 : Effectuer des appels API authentifiés

Créer un client API réutilisable :

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(`LinkedIn API Error: ${error.message}`);
  }

  return response.json();
};

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

Accès au profil

Obtenir le profil utilisateur

Récupérer le profil de l'utilisateur authentifié :

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

// Usage
const profile = await getUserProfile();

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

Obtenir l'adresse e-mail

Récupérer l'e-mail de l'utilisateur :

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

// Usage
const email = await getUserEmail();
console.log(`Email: ${email.elements?.[0]?.emailAddress}`);

Champs de profil disponibles

Champ Permission Description
id r_liteprofile ID du membre LinkedIn
firstName r_liteprofile Prénom
lastName r_liteprofile Nom de famille
profilePicture r_liteprofile URL de la photo de profil
headline r_basicprofile Titre professionnel
summary r_basicprofile Section À propos
positions r_basicprofile Historique professionnel
educations r_basicprofile Historique des études
emailAddress r_emailaddress E-mail principal

Publication de contenu

Créer une publication

Partager une publication texte sur le fil d'actualité de l'utilisateur :

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;
};

// Usage
const post = await createPost('urn:li:person:ABC123', {
  text: 'Excited to announce our new product launch! 🚀 #innovation #startup'
});

console.log(`Post created: ${post.id}`);

Créer une publication avec une image

Partager une publication avec un média :

const createPostWithImage = async (authorUrn, postData) => {
  // Step 1: Register media upload
  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;

  // Step 2: Upload image to provided URL
  await fetch(uploadUrl, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + await getAccessToken(),
      'Content-Type': 'application/octet-stream'
    },
    body: postData.imageBuffer
  });

  // Step 3: Create post with uploaded image
  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;
};

Créer une publication avec une vidéo

Partager du contenu vidéo :

const createPostWithVideo = async (authorUrn, postData) => {
  // Register video upload
  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;

  // Upload video (use presigned upload URLs from response)
  // ... upload logic ...

  // Create post
  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;
};

Spécifications des médias

Type de média Format Taille maximale Durée
Image JPG, PNG, GIF 8 Mo N/A
Vidéo MP4, MOV 5 Go 15 min max
Document PDF, PPT, DOC 100 Mo N/A

Gestion des pages d'entreprise

Obtenir des informations sur l'entreprise

Récupérer les détails de la page d'entreprise :

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;
};

// Usage
const company = await getCompanyInfo('1234567');
console.log(`Company: ${company.localizedName}`);
console.log(`Followers: ${company.followerCount}`);
console.log(`Website: ${company.website}`);

Publier sur une page d'entreprise

Partager une mise à jour sur une page d'entreprise :

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;
};

// Usage
const post = await createCompanyPost('urn:li:organization:1234567', {
  text: 'We're hiring! Join our growing team. #careers #hiring'
});

Obtenir les abonnés de l'entreprise

Récupérer le nombre d'abonnés :

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

Limitation de débit

Comprendre les limitations de débit

LinkedIn applique des limitations de débit par application :

API Limite Fenêtre
Profile API 100 requêtes Par jour
UGC Posts 50 publications Par jour
Company Admin 500 requêtes Par jour
Ads API 100 requêtes Par minute

En-têtes de limitation de débit

En-tête Description
X-Restli-Quota-Remaining Requêtes restantes
X-Restli-Quota-Reset Secondes avant réinitialisation

Dépannage des problèmes courants

Problème : 401 Non autorisé

Solutions :

  1. Vérifiez que le jeton d'accès n'a pas expiré (60 jours)
  2. Vérifiez que la portée du jeton inclut la ressource demandée
  3. Assurez-vous que l'en-tête Authorization: Bearer {token} est présent

Problème : 403 Interdit

Solutions :

  1. Vérifiez que l'application dispose des autorisations requises
  2. Vérifiez que l'utilisateur a approuvé les portées demandées
  3. Une vérification partenaire peut être requise

Problème : 429 Limitation de débit

Solutions :

  1. Mettre en œuvre une file d'attente de requêtes
  2. Mettre en cache les réponses pour réduire les appels
  3. Utiliser des webhooks au lieu de l'interrogation

Liste de contrôle du déploiement en production

Avant la mise en ligne :

Cas d'utilisation concrets

Plateforme de recrutement

Un outil de recrutement automatise la publication d'offres d'emploi :

Automatisation du marketing B2B

Une plateforme marketing planifie du contenu LinkedIn :

Conclusion

L'API LinkedIn offre un accès complet aux fonctionnalités du réseau professionnel. Principaux points à retenir :

bouton

Section FAQ

Comment puis-je accéder à l'API LinkedIn ?

Créez un compte développeur LinkedIn, créez une application et effectuez la vérification partenaire pour un accès avancé à l'API.

Puis-je publier automatiquement sur LinkedIn ?

Oui, utilisez l'API UGC (User Generated Content) avec la permission w_member_social pour les publications personnelles ou w_organization_social pour les publications d'entreprise.

Quelles sont les limitations de débit de LinkedIn ?

Les limitations de débit varient de 100 à 500 requêtes par jour selon l'API. L'API Ads autorise 100 requêtes par minute.

Combien de temps les jetons LinkedIn sont-ils valides ?

Les jetons d'accès expirent après 60 jours. Les utilisateurs doivent se réauthentifier pour continuer à accéder à l'API.

Puis-je accéder aux connexions utilisateur ?

Non, LinkedIn a supprimé l'accès à l'API des connexions pour la plupart des applications en raison de modifications liées à la confidentialité.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API