LinkedInへの公開はPOST https://api.linkedin.com/rest/postsの1回の呼び出しで完了し、作成された投稿のURNはボディではなくx-restli-idレスポンスヘッダーで返されます。メディアはまずアップロードを登録し、バイト列をアップロードしてから、返されたURNを参照する仕組みです。厄介なのは権限モデルとLinkedInの月次APIバージョニングです。
Posts APIで公開できるもの、できないもの
オーガニック(非スポンサー)投稿について、LinkedInのコンテンツタイプ表は明確です。
| コンテンツタイプ | オーガニック対応 |
|---|---|
| テキストのみ | 対応 |
| 画像 | 対応 |
| 動画 | 対応 |
| ドキュメント(PDF、DOC、DOCX、PPT、PPTX) | 対応 |
| 記事 | 対応 |
| MultiImage | 対応 |
| 投票 | 対応 |
| カルーセル | 非対応、スポンサーのみ |
ドキュメント投稿は嬉しい発見です。LinkedInで成果を出しやすいフォーマットであるPDFカルーセルは、Documents APIを通じて完全に対応しています。制限はファイルサイズ100MB以下、300ページ以下です。LinkedInの広告用語でいうオーガニックカルーセル投稿は対応しておらず、オーガニックでの相当機能はMultiImageです。記事投稿はURLを自動でスクレイピングしてくれないため、タイトル、説明、サムネイル画像のURNは自分で指定する必要があります。
構造上のギャップは権限の分割です。個人として投稿するにはw_member_socialが必要です。会社ページとして投稿するにはw_organization_socialが必要で、読み戻すにはr_organization_socialが必要、かつ認証されたメンバーがそのページでADMINISTRATOR、CONTENT_ADMIN、DIRECT_SPONSORED_CONTENT_POSTERのいずれかのロールを持っている必要があります。実際にはこれらは別々のAPIプロダクトで、アクセス申請も別々になるため、プロフィールとページの両方に投稿するツールは、最終的に2つの独立したLinkedInアプリを維持することになります。BulkPublishの実装もまさにそうしています。
注: ここに記載した数値は、2026年9月時点でMicrosoft Learn上のLinkedIn Posts API、Images API、Documents APIのドキュメントと照合済みです。プラットフォームは予告なくこれらの数値を変更することがあります。
認証はどう機能し、アクセス審査にはどれくらいかかるか
メンバートークンを取得するには3-legged OAuthを行い、以降すべてのリクエストにAuthorization: Bearer、X-Restli-Protocol-Version: 2.0.0、YYYYMM形式のLinkedIn-Versionの3つのヘッダーを付与します。最後のものは省略できず、永続的でもありません。LinkedInは月次でバージョンをリリースし、古いバージョンを廃止しており、現在のページにはMarketing Version 202508が2026年8月17日に廃止されるという非推奨通知が掲載されています。昨年固定したバージョンが、今日の障害の原因になり得ます。
コミュニティマネジメント関連のプロダクトへのアクセスは、申請ベースで許可されます。これらの開発者向けドキュメントに審査にかかる期間の記載はないため、期間は不明として扱ってください。また、r_member_socialは「承認されたユーザーのみ利用可能」な制限付き権限であるため、メンバー自身の投稿を読み戻すことは、書き込むこととは別の申請になる点にも注意してください。
Posts API、Images API、Documents APIのページからは、LinkedInのアクセストークンの有効期限を確認できませんでした。これらのページには記載がありません。この記事を含め、ブログ記事の数値ではなく、LinkedIn自身の認証ドキュメントで最新の数値を確認してください。
公開の呼び出しシーケンスはどうなっているか
テキストのみの投稿なら1回の呼び出しです。メディアを含む場合は3段階です。
POST /rest/images?action=initializeUpload(またはドキュメントの場合は/rest/documents?action=initializeUpload)を、initializeUploadRequest.ownerに個人または組織のURNを設定して呼び出します。- レスポンスの
valueオブジェクトからuploadUrlとアセットURN(imageまたはdocument)を読み取ります。 - バイト列を
uploadUrlにアップロードします。ドキュメントのアップロードが成功すると201が返ります。 author、commentary、visibility、distribution、lifecycleState: "PUBLISHED"を指定し、content.media.idにアセットのURNを設定してPOST /rest/postsを呼び出します。- 201のレスポンスの
x-restli-idヘッダーから、作成された投稿のURNを読み取ります。ボディには含まれません。
# 1. register the upload
curl -X POST 'https://api.linkedin.com/rest/documents?action=initializeUpload' \
-H "Authorization: Bearer $TOKEN" \
-H 'X-Restli-Protocol-Version: 2.0.0' -H 'LinkedIn-Version: 202608' \
-d '{"initializeUploadRequest":{"owner":"urn:li:organization:5515715"}}'
# -> value.uploadUrl, value.document = urn:li:document:...
# 2. upload the bytes
curl -i --upload-file ./deck.pdf -H "Authorization: Bearer $TOKEN" "$UPLOAD_URL"
# 3. create the post, then read x-restli-id from the 201
curl -i -X POST 'https://api.linkedin.com/rest/posts' \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-H 'X-Restli-Protocol-Version: 2.0.0' -H 'LinkedIn-Version: 202608' \
-d '{
"author": "urn:li:organization:5515715",
"commentary": "Our Q3 teardown, 12 pages.",
"visibility": "PUBLIC",
"distribution": {"feedDistribution":"MAIN_FEED","targetEntities":[],
"thirdPartyDistributionChannels":[]},
"content": {"media": {"title":"deck.pdf","id":"urn:li:document:..."}},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": false
}'
アセットには独自のステータスフィールドがあります。WAITING_UPLOAD、PROCESSING、PROCESSING_FAILED、AVAILABLEのいずれかです。AVAILABLEに達していないアセットを参照すると、メディアなしで投稿が公開されてしまう典型的な原因になります。
レート制限はどうなっているか
LinkedInのPosts APIのエラー一覧には429 TOO_MANY_REQUESTSが記載されており、リクエスト頻度を下げて遅延後にリトライするようガイダンスがありますが、ページにはアプリ単位・メンバー単位の具体的なリクエスト数は記載されていません。Posts API、Images API、Documents APIのページからは、具体的なスロットリングの数値を確認できませんでした。LinkedInは開発者ポータル上で、あなた自身のアプリについてアプリケーションレベル・メンバーレベルの1日あたりのスロットリングを公開しており、それがあなたのクォータについての唯一の正確な情報源なので、共有の数値を想定するのではなくそちらを確認してください。
具体的に明記されており、設計上考慮すべき制限が2つあります。ドキュメントは100MBかつ300ページまで、画像は36,152,320ピクセル未満で、JPG、GIF、PNGのいずれか、GIFは最大250フレームまでです。
注: ここに記載した数値は、2026年9月時点でMicrosoft Learn上のLinkedIn Posts API、Images API、Documents APIのドキュメントと照合済みです。プラットフォームは予告なくこれらの数値を変更することがあります。
実際に3週間分の工数を食うもの
2つのアプリ、2回の審査。 個人プロフィールへの投稿と会社ページへの投稿は、別々のプロダクトで別々の承認を必要とします。あなたの製品が両方を約束するなら、2つのOAuthフロー、2組の認証情報、2つの審査プロセスを運用することになり、片方だけが承認されて他方はされない、ということも起こり得ます。
月次バージョニング。 LinkedIn-Versionには計画が必要です。定期的な更新、現在のバージョンを検証するテスト、そして非推奨通知を読む担当者です。これは、構築の見積もり時に忘れられがちな運用コストです。
メディアパイプライン。 画像、ドキュメント、動画それぞれに固有のエンドポイントとアセットステータスの待機があり、2段階のアップロードが必要です。さらに、アップロードを無駄にしないためのフォーマットとサイズの検証も必要です。
非同期処理と部分的な失敗。 /rest/postsからの201は、大手プラットフォームの中でも最も強い確認応答ですが、その前段のアセット処理は非同期であり、lifecycleStateはPUBLISH_FAILEDとして返ってくることがあり、その場合は編集してリトライする必要があります。私たちのソーシャルメディア予約投稿APIガイドで扱っているprocessing状態をモデル化し、アップロード呼び出しだけで成功と報告しないようにしましょう。
文章も作成しているなら、LinkedIn文字数カウンターで「もっと見る」の切れ目がどこになるかを確認できます。
まとめ
POST /rest/postsの1回の呼び出し。投稿のURNはボディではなくx-restli-idで返ってきます。- メディアには
initializeUpload、アップロード、そしてcontent.media.idへのアセットURNの設定が必要です。 - ドキュメント(PDFやOfficeファイル)はオーガニックで対応しており、100MBかつ300ページまでです。
- 個人プロフィールと会社ページは異なる権限を使い、実際には2つのアプリになります。
LinkedIn-Versionは必須で、バージョンは廃止されていきます。更新のスケジュールを組みましょう。
プラットフォームごとに1回ずつではなく、まとめて1回で済ませる
LinkedInが対応が必要な複数のネットワークの1つに過ぎないなら、プラットフォームごとの作業は足し算ではなく掛け算で増えていきます。BulkPublishは、LinkedInの個人プロフィールと会社ページ(両方のアプリ、両方の審査済み)、LinkedInのドキュメント投稿を含む15のプラットフォームに、1つのREST APIから公開できます。バージョンヘッダー、アセットのポーリング、トークンのリフレッシュはこちら側で処理し、複数のネットワークを対象にした投稿は、そのうち1つが失敗した場合、成功したふりをするのではなくpartialとして報告します。APIリファレンスは/developers/、REST連携の概要は/integrations/rest-api/にあります。