The LinkedIn API for posting to company pages has a narrow surface and a wide front door. Once you are approved, the posting call itself is small: one POST, one author URN, a handful of headers. Getting approved is the long part, because every page post runs through Community Management API access and app review. This guide walks the whole path so you know exactly what you are signing up for, what the payload looks like, and when it is smarter to let Creator OS hold the tokens instead.
Your server LinkedIn API Company Page
| | |
| POST /rest/posts | |
| author=urn:li:org | |
|---------------------->| |
| | verify admin + scope |
| |------------------------>|
| | w_organization_social |
| |<------------------------|
| 201 Created | |
| x-restli-id: urn | |
|<----------------------| |
Token dies after ~60 days. Refresh it, or the next
post returns 401 and your queue backs up silently.What the LinkedIn API Actually Lets You Post to a Company Page
Company page posts through the API cover text, single images, video, polls (poll options with a 25 character cap and a duration between 5 minutes and 7 days), reposts via reshareUrl, a firstComment, and link preview control with disableLinkPreview. You can target an audience on a page post when the page has 300 or more members. You address the page with organizationUrn. When you post on behalf of a person instead, you use a member URN and a different scope.
Comment replies are supported. Direct messages are not available on LinkedIn through the API. Some formats simply are not in the API, so if a format is not in the list above, do not plan around it.
If you also run X or Threads, the same shape applies with different quirks. The X API thread posting guide covers where that surface diverges.
Access Requirements: w_organization_social, Community Management API and App Review
You need a LinkedIn app in the developer portal, a verified company page, and a human who is an admin on that page. Then you request Community Management API access, which is the product that unlocks organization posting. The scope you will actually use on the token is w_organization_social for writes. Reads of page analytics and comments come from the same product family.
App review is the gate. Reviewers want to know what your app does, why it needs page access, and how a page admin consents. Vague answers get bounced. A short video showing the consent screen and the resulting post tends to move faster than a long paragraph about your roadmap.
Practical notes from the field:
- Add every scope you will ever need at request time. Adding one later means another review cycle.
- The LinkedIn account you use as the app owner has to be a page admin, or the test post fails on permissions even with a valid token.
- Keep a second LinkedIn page that only exists for testing. Your real page’s members should not see review artifacts.
- Tokens are three legged. A two legged client credentials flow cannot act as a page admin.
The 3-Legged OAuth Flow for Company Page Posting, Step by Step
- Redirect the admin to the authorization URL with your client id, a redirect URI you registered exactly, and the scopes:
w_organization_social, plusr_organization_socialif you read comments or analytics. - The admin signs in and approves. LinkedIn sends a code to your redirect URI.
- Exchange the code for an access token. Store the refresh token too, not just the access token.
- Call the userinfo endpoint to get the member identifier. You need it to discover which pages the member administers.
- Look up the pages for that member and pick the organization URN you want to post as. That URN goes in every post.
- Refresh the token before it expires. Access tokens are short lived relative to refresh tokens, so schedule the refresh rather than reacting to a 401.
Step five is where multi page setups get messy. One admin may run several pages. Your app should store a mapping of member, page, and token, and treat each page as its own publishing target.
Finding Your Company Page URN and Author Field
The author field on an organization post is a URN of the form urn:li:organization:12345678. Two ways to get the number. Read it from the page URL in an admin browser tab, or call the organizational access endpoint with the member token and take the ids it returns. Do not guess from a vanity name. Vanity URLs and organization ids are different values.
Cache the URN in your database next to the connection record. Fetching it on every publish adds a round trip and a failure mode for no benefit.
Making Your First Post Request: Endpoint, Headers, and Payload
A minimal organization text post:
POST https://api.linkedin.com/rest/posts
Authorization: Bearer <access token>
X-Restli-Protocol-Version: 2.0.0
LinkedIn-Version: 202601
Content-Type: application/json
{
"author": "urn:li:organization:12345678",
"commentary": "We shipped the March release notes.",
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": false
}
The response carries a header with the created post id. Save that id. Editing and deleting later both need it, and there is no reliable way to find it again by matching text.
For an image, you upload the asset first with the register and upload steps, then reference the returned image URN in the content object. For a first comment, add firstComment to the payload so the link lands in a comment instead of the body. If you are posting the same asset to several networks, the media handling differences matter; the Instagram Graph API alternative breakdown shows how much per platform code this becomes.
Common Errors: 403 Access Denied, Missing scopes, and Expired Tokens
| Status | Usual cause | Fix |
|---|---|---|
| 401 | Token expired or malformed | Refresh, then retry once. Do not loop. |
| 403 | Token is valid but lacks w_organization_social, or the member is not a page admin |
Check the token scopes first, then check admin rights on that specific page. |
| 403 on a page you thought was fine | You posted as the wrong organization URN | Compare the URN to the page id you cached at connect time. |
| 426 | Missing or stale LinkedIn-Version header |
Send a dated version header on the request. |
| 400 on commentary | Text too long or contains unsupported characters | Trim and re-check before sending. |
A 403 that says access denied with a perfectly good token almost always means scope, not identity. A 403 that mentions the actor usually means the member lost admin rights on the page. Those are different bugs and different fixes. Log the response body, not just the status code, or you will spend an afternoon on the wrong one.
Rate Limits and Throttling for Organization Posts
LinkedIn meters calls per app and per member, with daily ceilings on the token and burst limits per window. The exact numbers sit in the developer docs and change, so read them rather than trusting a blog number. Two engineering habits matter more than the specific figure.
First, handle 429 with exponential backoff and a jitter, and honor any retry header you receive. The Facebook Graph API page posting guide covers the same pattern for a different network; the queueing logic is nearly identical. Second, write to a local queue instead of calling LinkedIn inline in a web request. If a user clicks publish and your handler calls LinkedIn synchronously, one 429 becomes a failed publish in your UI.
On the data side, treat the post id as the key for everything: analytics, comments, edits, deletes. The LinkedIn MCP server overview explains how Creator OS exposes the same page targets as typed tools, which is a useful mental model even if you are writing the OAuth flow yourself.
LinkedIn API vs Creator OS: When to Build and When to Skip the Review
Build it yourself when page posting is the core of your product, when you need custom LinkedIn only behavior, or when you already hold Community Management API access.
Skip the review when LinkedIn is one of several networks you need to publish to. A scheduling dashboard usually makes you maintain an OAuth dance, token refresh, per network payload rules and a retry layer for each network separately. Creator OS ships a hosted MCP server at https://mcp.creatoros.ca/mcp and a CLI so an AI agent can run your accounts, including LinkedIn company pages through organizationUrn, with the same create_post, list_comments and reply_to_comment tools you use for every other platform. API keys, the MCP server, the CLI and the agent skills are included in every plan, so you are not paying a per network premium to avoid the review.
You can also drive it from the terminal without writing any code. Connect and inspect accounts:
creatoros accounts:list
creatoros accounts:health
Then publish a page post and check it landed:
creatoros posts:create --text "March release notes are up." \
--platforms linkedin --draft
creatoros posts:list --status scheduled --limit 20
creatoros inbox:comments --platform linkedin --limit 20
If you want the agent to drive it, add the MCP server to Claude Code and let it use create_post with the LinkedIn page target, check_caption_length before sending, and get_post_analytics after. For the connection steps, see the MCP docs and the CLI docs. If you also write long form, the Make cross posting walkthrough shows the same pattern in a visual builder, and the read only API key guide covers scoping an agent that should never publish on its own.
One more option if you want a working example in front of you: Social Agents is an open source agent harness that runs your socials on Creator OS. Start it with npm start creatoros social-agents, answer its interview about your brand, and it posts, replies to comments and DMs, runs automations and reports on a local dashboard. The code is at github.com/kevinbadi/social-agents. You can watch the walkthroughs on the KevBuildsApps YouTube channel, and the launch video shows the harness end to end: https://www.youtube.com/watch?v=-QBJH_PK3pY.
Get Started With Creator OS for LinkedIn Company Page Posting
Sign up at https://www.creatoros.ca/sign-up. The Creator plan is $14.99/month or $59.99/year and covers 11 platforms plus Skool, one account on each. If you run several brands, agency plans cover 5 sets of socials, 11 platforms plus Skool for each, for $49.99/month, or 10 sets for $99/month.
Connect the LinkedIn account that is an admin on your page with creatoros accounts:connect linkedin, confirm it with creatoros accounts:health, then send your first page post. For payload options and per platform settings, the docs live at https://www.creatoros.ca/docs.
Get started for $0
Free trial for new subscribers. Cancel anytime.