LinkedIn API: Automate Company Page Posts

Publish to LinkedIn company pages via API: approval process, OAuth scopes, posting limits, rate limits, and what makes LinkedIn API automation tricky.

LinkedIn API: Automate Company Page Posts

LinkedIn is the B2B publishing channel that still runs on manual effort

Every B2B company with a content strategy eventually reaches the same conclusion: LinkedIn is where their audience is. Decision-makers scroll LinkedIn during working hours. Company updates on LinkedIn drive more qualified traffic than the same update on any other platform.

And yet, most B2B teams still publish to LinkedIn manually. Someone copies the blog excerpt, pastes it into the LinkedIn composer, adds an image, and clicks publish. Maybe they schedule it through a dashboard tool that costs more per month than the engineer who could automate it.

The reason is not that LinkedIn lacks an API. It has one. The reason is that LinkedIn’s API has enough friction — approval gates, posting quirks, and organizational access requirements — that many teams decide manual is easier than building the integration.

That calculation changes when publishing volume goes up. If you publish once a week, manual works. If you publish daily across a company page, executive profiles, and regional pages, manual does not scale.

What LinkedIn’s API can and cannot do

LinkedIn’s posting API — the Posts API at /rest/posts — handles text posts, image posts, video posts, multi-image posts, and link shares. It publishes to both personal profiles and company pages.

What it cannot do:

  • Publish articles. LinkedIn articles (the long-form content with a title, body, and cover image) are not available through the API. Articles can only be created through the LinkedIn web interface. If your content strategy includes LinkedIn articles, that part stays manual.
  • Publish newsletters. LinkedIn newsletters are an extension of articles. No API support.
  • Publish document posts. PDF carousel posts — where users swipe through slides — are created by uploading a PDF document. The API does not support document uploads as of 2026.
  • Publish polls. No API support for polls.
  • Tag people or companies. The API does not support @mentions in post text. You can write @CompanyName but it will render as plain text, not a clickable mention.

For most B2B automation use cases, the core functionality — text, images, videos, and links — covers 80% of publishing needs. But if your content strategy relies heavily on document carousels or articles, the API will not fully replace manual publishing.

Company pages vs. personal profiles

LinkedIn treats organizational publishing differently from personal publishing, and the permissions reflect this.

Company page publishing requires:

  • w_organization_social scope — approved through LinkedIn’s developer program
  • The publishing user must be an admin of the company page
  • Posts use the organization URN as the author: urn:li:organization:{id}

Personal profile publishing requires:

  • w_member_social scope
  • Posts use the member URN: urn:li:person:{id}

The practical difference: publishing to a company page requires your app to have organizational permissions approved by LinkedIn. This is a separate approval process from basic API access. LinkedIn reviews your use case, your app’s purpose, and how organizational data will be used.

For B2B teams, the company page is usually the priority. Most automated publishing flows target the company page first, with personal profiles as a secondary distribution channel for executives who want to amplify company content.

The approval timeline and what to expect

LinkedIn’s developer program has two tiers of access:

Self-serve products — Basic profile access, sign-in with LinkedIn. Available immediately.

Restricted products — Community Management API (which includes publishing), Marketing API, Compliance API. These require applying through the developer portal and waiting for approval.

The Community Management API is what you need for publishing. The approval process:

  1. Create an app in the LinkedIn Developer Portal
  2. Add the Community Management API product to your app
  3. Submit your use case description
  4. Wait 1–2 weeks for review
  5. If approved, configure OAuth redirect URIs and start building

LinkedIn may request additional documentation: screenshots of your app, a description of how you will use the data, your privacy policy. Unlike TikTok’s audit, LinkedIn does not require specific UX elements in your app. But they do evaluate whether your use case is legitimate.

If you are building a product where other companies connect their LinkedIn pages, the approval becomes more involved. LinkedIn wants to understand multi-tenant use cases and how organizational data is isolated between tenants.

The versioning requirement

Every LinkedIn API request must include a Linkedin-Version header with a date in YYYYMM format. LinkedIn uses this for API versioning — different version dates can return different response formats.

Linkedin-Version: 202402

This is not a minor detail. If you hardcode a version and LinkedIn deprecates it, your integration breaks. If you update the version without testing, response formats may change. You need a strategy for version management — either pinning to a known-good version and testing upgrades periodically, or tracking LinkedIn’s changelog and updating proactively.

All API requests also require these headers:

Authorization: Bearer {TOKEN}
Linkedin-Version: {YYYYMM}
X-Restli-Protocol-Version: 2.0.0
Content-Type: application/json

Publishing text posts

POST to /rest/posts:

{
"author": "urn:li:organization:5515715",
"commentary": "Your post text",
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": false
}

Returns 201 Created with the post URN in the x-restli-id response header.

Publishing images

Images require uploading the asset first, then creating the post that references it.

Step 1: Upload the image

POST to /rest/images?action=initializeUpload:

{
"initializeUploadRequest": {
"owner": "urn:li:organization:5515715"
}
}

Returns an uploadUrl and an image URN (urn:li:image:{id}). Upload the image binary directly to the uploadUrl.

Supported formats: JPG, PNG, GIF (up to 250 frames). Maximum 36,152,320 pixels.

Step 2: Create the post

Once the image status is AVAILABLE, POST to /rest/posts with the image URN in the content:

{
"author": "urn:li:organization:5515715",
"commentary": "Your caption",
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"lifecycleState": "PUBLISHED",
"content": {
"media": {
"id": "urn:li:image:C4E10AQFoyyAjHPMQuQ"
}
}
}

Publishing videos

Videos use a four-step chunked upload flow. The video must reach AVAILABLE status before it can be referenced in a post.

Step 1: Initialize the upload

POST to /rest/videos?action=initializeUpload:

{
"initializeUploadRequest": {
"owner": "urn:li:organization:5515715",
"fileSizeBytes": 1055736,
"uploadThumbnail": true
}
}

Returns a video URN (urn:li:video:{id}), an uploadToken, and uploadInstructions — an array of parts with byte ranges and upload URLs.

Step 2: Upload video parts

Split the video into 4 MB chunks and upload each part to its assigned URL. Save the ETag from each response header — these are required to finalize the upload.

Video requirements: MP4 only, 3 seconds to 30 minutes, 75 KB to 500 MB.

Step 3: Upload thumbnail and captions (optional)

Upload a custom thumbnail (JPG or PNG) to the thumbnailUploadUrl from step 1. SRT caption files can be uploaded to the captionsUploadUrl.

Step 4: Finalize the upload

POST to /rest/videos?action=finalizeUpload:

{
"finalizeUploadRequest": {
"video": "urn:li:video:C5505AQH-oV1qvnFtKA",
"uploadToken": "<TOKEN_FROM_STEP_1>",
"uploadedPartIds": ["etag1", "etag2", "etag3"]
}
}

Once the video status is AVAILABLE, create the post referencing the video URN the same way as images — using content.media.id.

Publishing multi-image posts

Multi-image posts support 2–20 images in a single post. Upload each image individually via the Images API first, then create the post:

{
"author": "urn:li:organization:5515715",
"commentary": "Multi-image post caption",
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"lifecycleState": "PUBLISHED",
"content": {
"multiImage": {
"images": [
{ "id": "urn:li:image:C4D22AQFttWMAaIqHaa", "altText": "First image" },
{ "id": "urn:li:image:C4D22AQG7uz0yPJh588", "altText": "Second image" }
]
}
}
}

altText is optional but recommended for accessibility. Maximum 4,086 characters per image.

Checking asset status

Image and video uploads are processed asynchronously. Poll the asset endpoint before referencing it in a post:

  • Images: GET /rest/images/{image-urn}
  • Videos: GET /rest/videos/{video-urn}

Status values:

  • WAITING_UPLOAD — Awaiting upload data
  • PROCESSING — Being processed by LinkedIn
  • AVAILABLE — Ready to use in a post
  • PROCESSING_FAILED — Upload or processing failed

Building a blog-to-LinkedIn pipeline

The most common B2B automation use case is publishing blog content to LinkedIn. The workflow:

  1. A new blog post is published on your site
  2. Your system extracts the title, excerpt, featured image, and URL
  3. The content is adapted for LinkedIn — shorter text, different tone, clear CTA
  4. The post is published to your company page via API

The adaptation step matters. Copying your blog excerpt verbatim to LinkedIn produces mediocre engagement. LinkedIn’s algorithm rewards posts that keep users on the platform, which means:

  • Lead with a hook in the first two lines (visible before “see more”)
  • Include the link in a comment or at the end of the post, not the first line
  • Use line breaks for readability — LinkedIn’s feed is narrow
  • Keep the post under 1,300 characters for optimal visibility

For teams using an LLM to rewrite blog content for social distribution, LinkedIn-specific prompting makes a measurable difference. A prompt that says “rewrite this blog excerpt for LinkedIn, lead with a question, use short paragraphs” produces better results than a generic “summarize this.”

Image and video considerations for company pages

LinkedIn’s media handling has quirks that affect automated workflows:

Images are uploaded via the Images API before being referenced in a post. The upload returns a URN; you include the URN in the post payload. Supported formats: JPG, PNG, GIF. Maximum resolution: 36 million pixels. No SVG support.

Videos require a multi-step chunked upload: initialize, upload in 4 MB parts, collect ETags, finalize. Videos must reach AVAILABLE status before they can be referenced in a post. This means your publishing pipeline needs to handle upload-then-wait-then-post as a single atomic operation.

Multi-image posts support 2–20 images. Each image is uploaded separately, then all URNs are included in the post payload. For automated workflows pulling from a CMS, you need to handle variable image counts.

Link previews are generated automatically when you include a URL. You cannot customize the preview image through the API — LinkedIn scrapes the URL’s Open Graph tags. If your blog does not have OG tags configured, the preview will be blank or wrong.

For B2B teams, video posts on LinkedIn consistently outperform image and text posts in engagement metrics. If your automation pipeline can repurpose video content for LinkedIn — even a 30-second clip from a webinar or product demo — it is worth including.

Rate limits and publishing cadence

LinkedIn’s rate limits for the Posts API are not publicly documented with exact numbers, but the practical constraints are:

  • Application-level rate limiting across all users of your app
  • Per-user rate limiting for individual account activity
  • Throttling that increases during periods of high API usage

More relevant than rate limits is LinkedIn’s algorithmic response to publishing cadence. Posting more than once or twice per day to a company page generally decreases per-post reach. LinkedIn’s algorithm surfaces content based on engagement, and high-frequency posting dilutes engagement across posts.

For automated workflows, this means scheduling matters more than throughput. The best B2B publishing cadence on LinkedIn is typically:

  • Company page: 1 post per business day, published between 8–10 AM in the target audience’s timezone
  • Executive profiles: 2–3 posts per week, staggered from company page content
  • Regional pages: 1–2 posts per week with localized content

Your automation should enforce this cadence, not just fire posts as fast as the API allows.

Share statistics

Retrieve organic post performance for an organization page via GET /rest/organizationalEntityShareStatistics:

?q=organizationalEntity
&organizationalEntity=urn:li:organization:2414183
&timeIntervals=(timeRange:(start:1551398400000,end:1552003200000),timeGranularityType:DAY)

Available metrics: impressions, unique impressions, clicks, likes, comments, shares, and engagement rate.

Data covers a rolling 12-month window. Omit timeIntervals for lifetime totals, or set timeGranularityType to DAY or MONTH for time-series data. This endpoint covers organic posts only — sponsored content metrics require the Ad Analytics API.

Publishing to LinkedIn through Postproxy

Postproxy handles LinkedIn’s approval requirements, media upload flow, and API versioning. One request publishes to LinkedIn alongside other platforms:

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": {
"body": "We analyzed 2,000 customer onboarding sessions.\n\nThe biggest drop-off was not where we expected.\n\nHere is what we found and what we changed."
},
"profiles": ["linkedin", "twitter", "threads"],
"media": ["https://example.com/onboarding-findings.png"]
}'

What Postproxy handles for LinkedIn specifically:

  • Community Management API approval — Postproxy maintains approved organizational access. You connect your LinkedIn page via OAuth; Postproxy handles the permissions.
  • Image and video uploads — The upload-then-reference flow, including chunked video upload with ETag tracking, happens inside Postproxy.
  • API versioning — Postproxy tracks LinkedIn API version changes and updates automatically. You do not manage version headers.
  • Token refresh — LinkedIn tokens last 60 days. Postproxy refreshes them before expiry.
  • Per-platform status — When a post goes to LinkedIn and three other platforms, you see individual outcomes per platform, not a single success/failure.

For B2B teams building a content pipeline from CMS to social, Postproxy is the publishing layer. Your system decides what to publish and when. Postproxy handles the platform-specific implementation for every connected account.

When manual still wins

If your LinkedIn strategy is primarily thought leadership — executives writing personal posts in their own voice, responding to comments, engaging with their network — the API is not the right tool. That kind of publishing benefits from the human touch of writing directly in the LinkedIn composer.

Where automation wins is repeatable, structured publishing: company page updates tied to product launches, blog distribution, event promotion, and multi-channel content distribution. The content is planned, the schedule is predictable, and the value of automation compounds with every post.

Connect your LinkedIn page and start publishing through the Postproxy API. For an overview of unified publishing, start with the developer guide.

Ready to get started?

Start with our free plan and scale as your needs grow. No credit card required.