LinkedIn API の使い方:完全プロフェッショナルネットワーク連携ガイド(2026年)

Ashley Innocent

Ashley Innocent

25 3月 2026

LinkedIn API の使い方:完全プロフェッショナルネットワーク連携ガイド(2026年)

要点

LinkedIn APIは、開発者がLinkedInのプロフェッショナルネットワークとプログラムで統合することを可能にします。OAuth 2.0認証、プロファイル、投稿、コメント、企業ページ、広告のためのRESTfulおよびGraphQLエンドポイントを使用し、アプリごとに1日あたり100〜500リクエストのレート制限があります。このガイドでは、認証設定、プロファイルアクセス、コンテンツ投稿、企業ページ管理、広告API、および本番環境への統合戦略について説明します。

はじめに

LinkedInは200以上の国と地域に9億人以上のプロフェッショナルユーザーを抱えています。採用ツール、マーケティングプラットフォーム、またはB2Bアプリケーションを開発する開発者にとって、LinkedIn APIの統合は、このプロフェッショナルなオーディエンスにリーチするために不可欠です。

現実として、LinkedInでのプレゼンスを手動で管理しているB2Bマーケターは、投稿、エンゲージメント追跡、リード生成に毎週15~20時間を費やしています。堅実なLinkedIn API統合は、コンテンツ配信、リード獲得、エンゲージメント分析、採用ワークフローを自動化します。

このガイドでは、LinkedIn APIの統合プロセス全体を説明します。OAuth 2.0認証、プロファイルアクセス、コンテンツ投稿、企業ページ管理、広告統合、Webhook、および本番環境へのデプロイ戦略を学びます。このガイドを読み終える頃には、本番環境に対応したLinkedIn統合が完了しているでしょう。

💡
ApidogはAPI統合テストを簡素化します。LinkedInのエンドポイントをテストし、OAuthフローを検証し、API応答を検査し、権限の問題を1つのワークスペースでデバッグできます。API仕様をインポートし、モックレスポンスを作成し、テストシナリオをチームと共有できます。
ボタン

LinkedIn APIとは?

LinkedInは、プロフェッショナルネットワークデータにアクセスするためのRESTfulおよびGraphQL APIを提供します。APIは以下を処理します。

主な機能

機能 説明
RESTful + GraphQL 複数のAPIスタイル
OAuth 2.0 ユーザー認証が必要
レート制限 アプリごとに1日あたり100〜500リクエスト
企業ページ 完全なCRUD操作
広告API キャンペーン管理
Webhook リアルタイム通知
メディアアップロード 画像と動画

API製品

API アクセスレベル ユースケース
LinkedInでサインイン オープン ユーザー認証
プロファイルAPI パートナー ユーザープロファイルの読み取り
企業管理者API パートナー 企業ページの管理
広告API パートナー 広告キャンペーン管理
求人投稿API パートナー 求人の投稿と管理
マーケティング開発者プラットフォーム パートナー 完全なAPIアクセス

APIバージョン

バージョン ステータス 終了日
v2 現行 アクティブ
v1 廃止 2023年12月

開始方法:認証設定

ステップ1:LinkedIn開発者アカウントの作成

APIにアクセスする前に:

  1. LinkedIn開発者ポータルにアクセスします
  2. LinkedInアカウントでサインインします
  3. 「マイアプリ」ダッシュボードで「Create App」をクリックします
  4. アプリの詳細(名前、ロゴ、説明)を入力します

ステップ2:アプリ設定の構成

アプリ認証を設定します:

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;

// これらはアプリのダッシュボードから取得します
// https://www.linkedin.com/developers/apps/{appId}/auth

ステップ3:必要な権限の要求

LinkedInは権限の承認を要求します:

権限 説明 承認が必要
r_liteprofile 基本プロファイル(名前、写真) 自動承認
r_emailaddress メールアドレス 自動承認
w_member_social ユーザーの代わりに投稿 パートナー認証
r_basicprofile 完全なプロファイル パートナー認証
r_organization_social 企業ページアクセス パートナー認証
w_organization_social 企業ページへの投稿 パートナー認証
rw_ads 広告管理 パートナー認証
r_ads_reporting 広告分析 パートナー認証

ステップ4:認証URLの構築

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()}`;
};

// 使用法
const state = require('crypto').randomBytes(16).toString('hex');
const authUrl = getAuthUrl(state, ['r_liteprofile', 'r_emailaddress', 'w_member_social']);
console.log(`ユーザーを以下にリダイレクトします: ${authUrl}`);

ステップ5:コードをアクセストークンと交換する

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

// コールバックを処理します
app.get('/oauth/callback', async (req, res) => {
  const { code, state } = req.query;

  try {
    const tokens = await exchangeCodeForToken(code);

    // トークンを安全に保存します
    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);
    res.status(500).send('認証に失敗しました');
  }
});

ステップ6:アクセストークンの更新

アクセストークンは60日後に期限切れになります:

const refreshAccessToken = async (refreshToken) => {
  // 注:LinkedInはリフレッシュトークンを提供していません
  // ユーザーは60日後に再認証する必要があります
  // 有効期限通知を実装します
};

// API呼び出しの前にトークンの有効期限を確認します
const ensureValidToken = async (userId) => {
  const user = await db.users.findById(userId);

  if (user.linkedin_token_expires < Date.now() + 86400000) { // 24時間
    // ユーザーに再認証を通知します
    await notifyUserToReauth(user.id);
    throw new Error('トークンの有効期限が切れました。再認証してください');
  }

  return user.linkedin_access_token;
};

ステップ7:認証済みAPI呼び出しの実行

再利用可能なAPIクライアントを作成します:

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.message}`);
  }

  return response.json();
};

// 使用法
const profile = await linkedinRequest('/me');
console.log(`こんにちは、${profile.localizedFirstName} ${profile.localizedLastName}さん`);

プロファイルアクセス

ユーザープロファイルの取得

認証済みユーザーのプロファイルを取得します:

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

// 使用法
const profile = await getUserProfile();

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

メールアドレスの取得

ユーザーのメールアドレスを取得します:

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

// 使用法
const email = await getUserEmail();
console.log(`メール: ${email.elements?.[0]?.emailAddress}`);

利用可能なプロファイルフィールド

フィールド 権限 説明
id r_liteprofile LinkedInメンバーID
firstName r_liteprofile
lastName r_liteprofile
profilePicture r_liteprofile プロファイル写真URL
headline r_basicprofile プロフェッショナルヘッドライン
summary r_basicprofile 「概要」セクション
positions r_basicprofile 職歴
educations r_basicprofile 学歴
emailAddress r_emailaddress 主要メールアドレス

コンテンツの投稿

投稿の作成

ユーザーのフィードにテキスト投稿を共有します:

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

// 使用法
const post = await createPost('urn:li:person:ABC123', {
  text: '新製品の発売を発表できることを嬉しく思います!🚀 #イノベーション #スタートアップ'
});

console.log(`投稿が作成されました: ${post.id}`);

画像を伴う投稿の作成

メディア付きで投稿を共有します:

const createPostWithImage = async (authorUrn, postData) => {
  // ステップ1:メディアアップロードを登録します
  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;

  // ステップ2:提供されたURLに画像をアップロードします
  await fetch(uploadUrl, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + await getAccessToken(),
      'Content-Type': 'application/octet-stream'
    },
    body: postData.imageBuffer
  });

  // ステップ3:アップロードされた画像で投稿を作成します
  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;
};

動画を伴う投稿の作成

動画コンテンツを共有します:

const createPostWithVideo = async (authorUrn, postData) => {
  // 動画アップロードを登録します
  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;

  // 動画をアップロードします(応答からの署名付きアップロードURLを使用)
  // ... アップロードロジック ...

  // 投稿を作成します
  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;
};

メディアの仕様

メディアタイプ 形式 最大サイズ 期間
画像 JPG、PNG、GIF 8MB 該当なし
動画 MP4、MOV 5GB 最大15分
ドキュメント PDF、PPT、DOC 100MB 該当なし

企業ページ管理

企業情報の取得

企業ページの詳細を取得します:

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

// 使用法
const company = await getCompanyInfo('1234567');
console.log(`会社: ${company.localizedName}`);
console.log(`フォロワー: ${company.followerCount}`);
console.log(`ウェブサイト: ${company.website}`);

企業ページへの投稿

企業ページに更新情報を共有します:

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

// 使用法
const post = await createCompanyPost('urn:li:organization:1234567', {
  text: '採用募集中!成長中のチームに参加しませんか。#キャリア #採用'
});

企業のフォロワーの取得

フォロワー数を取得します:

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

レート制限

レート制限の理解

LinkedInはアプリごとにレート制限を適用します:

API 制限 期間
プロファイルAPI 100リクエスト 1日あたり
UGC投稿 50投稿 1日あたり
企業管理者 500リクエスト 1日あたり
広告API 100リクエスト 1分あたり

レート制限ヘッダー

ヘッダー 説明
X-Restli-Quota-Remaining 残りのリクエスト数
X-Restli-Quota-Reset リセットまでの秒数

一般的な問題のトラブルシューティング

問題:401 Unauthorized(未承認)

解決策:

  1. アクセストークンが期限切れになっていないか確認します(60日)
  2. トークンのスコープに要求されたリソースが含まれているか確認します
  3. Authorization: Bearer {token} ヘッダーが存在することを確認します

問題:403 Forbidden(禁止)

解決策:

  1. アプリが必要な権限を持っているか確認します
  2. ユーザーが要求されたスコープを承認したか確認します
  3. パートナー認証が必要な場合があります

問題:429 Rate Limited(レート制限)

解決策:

  1. リクエストキューイングを実装します
  2. 呼び出しを減らすために応答をキャッシュします
  3. ポーリングの代わりにWebhookを使用します

本番環境デプロイチェックリスト

本番稼働前に:

実際のユースケース

採用プラットフォーム

採用ツールが求人投稿を自動化します:

B2Bマーケティング自動化

マーケティングプラットフォームがLinkedInコンテンツをスケジュールします:

まとめ

LinkedIn APIは、プロフェッショナルネットワーク機能への包括的なアクセスを提供します。主なポイント:

ボタン

よくある質問

LinkedIn APIにアクセスするにはどうすればよいですか?

LinkedIn開発者アカウントを作成し、アプリを作成し、高度なAPIアクセスにはパートナー認証を完了してください。

LinkedInに自動的に投稿できますか?

はい、個人投稿にはw_member_social権限を持つUGC(User Generated Content)APIを、企業投稿にはw_organization_socialを使用できます。

LinkedInのレート制限とは何ですか?

レート制限はAPIによって1日あたり100〜500リクエストの範囲です。広告APIは1分あたり100リクエストを許可しています。

LinkedInトークンはどのくらい持続しますか?

アクセストークンは60日後に期限切れになります。APIアクセスを継続するには、ユーザーが再認証する必要があります。

ユーザーのつながりにアクセスできますか?

いいえ、プライバシー変更により、LinkedInはほとんどのアプリからのつながりAPIアクセスを削除しました。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる