LinkedIn API: how to post to profiles and Company Pages in 2026
Is the LinkedIn API free, which product you need, and how the Posts API works: tokens, headers, the little text format, images, video and limits.
9 minute read By SocialHelper team
The LinkedIn API is free to use, and posting to your own profile needs no approval. Add the Share on LinkedIn product to a developer app, sign in with OAuth, and send the post to POST /rest/posts. Posting as a Company Page is harder. It needs the Community Management API, which LinkedIn vets, and which starts at 100 calls per member a day until you reach its Standard tier.
Post text goes in LinkedIn’s “little” format, where 15 characters, including brackets and the hash sign, have to be escaped. Pricing, products, tokens, the posting call, media and limits follow, with examples from the code SocialHelper uses to post to LinkedIn.
Is the LinkedIn API free?
Yes. LinkedIn’s API terms say it “currently does not charge a fee for use of the APIs, but may choose to in the future” (LinkedIn API Terms of Use, section 8.2). You also may not charge your users extra fees for access to LinkedIn content or APIs. Monthly prices you see quoted online are third-party estimates or the price of someone else’s product. LinkedIn publishes no rate card.
What LinkedIn controls instead is access. A few permissions are open to everyone, and the rest need LinkedIn to approve your app for a product. That decides what you can post and for whom.
Which LinkedIn API product you need
A LinkedIn API product is a bundle of permissions you add to your app in the Developer Portal, under Products. Posting needs one of two.
| You want to | What you need |
|---|---|
| Sign people in | Sign In with LinkedIn using OpenID Connect (openid, profile, email). Self-serve. |
| Post as a member | Share on LinkedIn (w_member_social). Self-serve. |
| Post as a Company Page | Community Management API (w_organization_social). Vetted, with a Development and a Standard tier. |
| Read a member’s posts | r_member_social. Approved apps only. |
| Run ads | Advertising API. Vetted. |
LinkedIn calls the first two Open Permissions, “the only permissions that are available to all developers without special approval” (LinkedIn: Getting access). Posting as a Page also needs the right role. w_organization_social works only on Pages where the member is an administrator, a content admin or a sponsored content poster (LinkedIn: Posts API).
Community Management API tiers
The Community Management API has two tiers. The Development tier is the default once you’re approved, and it allows 500 calls per app and 100 per member a day. You have 12 months to finish building on it (LinkedIn: Increasing access). The Standard tier is for live use. To get it, you send a screencast that shows each use case.
LinkedIn asks you to request Development access only on a new app with no other API products (LinkedIn: Community Management API). So SocialHelper runs LinkedIn Pages on a second app that holds that product alone, separate from the app for LinkedIn profiles. At 100 calls per member a day, it reads only what posting needs when someone connects.
LinkedIn API keys and access tokens
LinkedIn has no single API key. Your app gets a client ID and a client secret in the Developer Portal, and every call carries an access token for one member. Products such as the Community Management API also need the app tied to a LinkedIn Page. A Page super admin approves that link, and they have 30 days to use the verification URL you send them (LinkedIn Help: App verification).
Tokens come from the three-legged OAuth flow. The member signs in and approves your scopes, and you swap the code for a token. Mind three details from LinkedIn’s OAuth guide (LinkedIn: Authorization code flow).
- The code expires fast. It has “a 30-minute lifespan and must be used immediately”.
- Tokens last 60 days. All access tokens currently get a 60-day lifespan.
- Changing scopes resets tokens. If you request different scopes than before, all earlier tokens for that member are invalidated.
Refresh tokens are for approved Marketing Developer Platform partners only. Theirs last 365 days from the first sign-in, and refreshing doesn’t extend that (LinkedIn: Refresh tokens). Everyone else sends the member through sign-in again. LinkedIn skips the consent screen if the member is still logged in and the old token hasn’t expired. SocialHelper flags a profile for reconnecting when its token runs out, and LinkedIn Pages refresh on their own until the year is up.
Post to LinkedIn with the Posts API
The Posts API is LinkedIn’s endpoint for creating posts, and it replaces the older ugcPosts API. Every call needs two headers: Linkedin-Version with a month in YYYYMM form, and X-Restli-Protocol-Version: 2.0.0. A post is written by an author, which is a URN: urn:li:person:{id} for a member or urn:li:organization:{id} for a Page.
First, get the member’s ID. The sub field of the userinfo response is the ID in the person URN.
curl https://api.linkedin.com/v2/userinfo \
-H "Authorization: Bearer $LI_TOKEN"
Then create the post.
curl https://api.linkedin.com/rest/posts \
-H "Authorization: Bearer $LI_TOKEN" \
-H "Linkedin-Version: 202610" \
-H "X-Restli-Protocol-Version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{"author": "urn:li:person:YOUR_MEMBER_ID",
"commentary": "Hello from the Posts API",
"visibility": "PUBLIC",
"distribution": {"feedDistribution": "MAIN_FEED"},
"lifecycleState": "PUBLISHED"}'
It returns 201. The x-restli-id header holds the new post’s ID, such as urn:li:share:6844785523593134080. The post’s address is https://www.linkedin.com/feed/update/ followed by that ID. Version 202610, from October 2026, is the latest (LinkedIn: Versioning).
The Posts API has no field for a future publish time. To schedule a post, your app stores it and sends it at the right moment.
Escape your text: the little format
Little is the text format LinkedIn uses for a post’s commentary. It marks mentions and hashtags inline, so it reserves 15 characters: | { } @ [ ] ( ) < > # \ * _ ~. LinkedIn’s rule is that “all reserved characters need to be escaped with a backslash”, even when they aren’t part of a mention or a hashtag (LinkedIn: little text format). Hashtags have their own template, {hashtag|\#|tag}.
Take this post, typed as normal.
We’re hiring 2 engineers (remote, Canada) 🍁 #hiring
SocialHelper sends it to LinkedIn like this.
We’re hiring 2 engineers \(remote, Canada\) 🍁 {hashtag|\#|hiring}
The parentheses get backslashes and the hashtag becomes a template, so it still shows as a hashtag. In JSON, each backslash is doubled. SocialHelper does this for every LinkedIn post. It also escapes the # in #1 or C#, so they stay plain text instead of turning into hashtags. The example is 52 characters by LinkedIn’s count, because LinkedIn counts UTF-16 code units and the maple leaf takes two. The limit is 3,000. Bold and italics are another matter, covered in the guide to LinkedIn text formatting.
Images, video and multi-image posts
Media is uploaded before the post. For an image, call initializeUpload with the author as the owner. LinkedIn returns an upload URL and an image URN.
curl "https://api.linkedin.com/rest/images?action=initializeUpload" \
-H "Authorization: Bearer $LI_TOKEN" \
-H "Linkedin-Version: 202610" \
-H "X-Restli-Protocol-Version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{"initializeUploadRequest": {"owner": "urn:li:person:YOUR_MEMBER_ID"}}'
Send the file to the upload URL with PUT. Then add the image URN to the post as "content": {"media": {"id": "urn:li:image:…"}}. Images must have fewer than 36,152,320 pixels, in JPG, GIF or PNG, and a GIF can have up to 250 frames (LinkedIn: Images API).
- Several images. A multi-image post holds 2 to 20 images under
content.multiImage, each with alt text of up to 4,086 characters (LinkedIn: MultiImage API). Swipeable carousels are for sponsored posts only. - Video. Videos are MP4, 3 seconds to 30 minutes, and 75 KB to 500 MB. You initialize, upload in 4 MB parts, then finalize (LinkedIn: Videos API). The same page’s schema allows 5 GB, so LinkedIn’s own docs disagree. SocialHelper keeps to 500 MB.
- Wait for processing. Check the image or video until its status is
AVAILABLEbefore you post it. SocialHelper checks images every 3 seconds for up to 30 seconds, and videos every 15 seconds for up to 5 minutes.
SocialHelper posts images to profiles and Pages, and video to Pages. Video on member profiles isn’t supported yet.
Rate limits and API versions
LinkedIn doesn’t publish its standard rate limits. Each app has a daily limit per app and per member, both reset at midnight UTC, and calls over the limit get a 429. You can see the limits for endpoints you’ve called in your app’s Analytics tab, and admins get an email at 75% of the app’s quota (LinkedIn: Rate limits).
Versions are monthly, and each is supported for at least a year. Version 202511 sunsets on November 16, 2026. A request with a retired version fails, so pin a recent version and move it forward a few times a year.
Errors and duplicate posts
SocialHelper’s LinkedIn integration turns these responses into plain messages for the person who posted.
| Response | Usually means | What to do |
|---|---|---|
401 | Token expired or revoked | Sign the member in again |
403 | App lacks the product, or the token predates it | Add the product, then reconnect |
422 duplicate | Same content as a recent post | Don’t retry; the first one is live |
426 | API version not accepted | Move Linkedin-Version to a current month |
429 | Daily limit reached | Wait for the reset at midnight UTC |
The hard case is a timeout on the create call. The post may be live, and sending it again could post it twice. For a Page, SocialHelper reads the Page’s recent posts first. If LinkedIn rejects a retry as a duplicate, its error names the earlier post, which SocialHelper records as the result. Member posts can’t be checked that way, because reading them needs r_member_social, which LinkedIn restricts to approved apps. So SocialHelper marks an unclear member post as failed rather than risk a second copy. The guide to idempotent posting explains the pattern.
The shortcut: one request
If you’d rather not run the OAuth app, the version header, the escaping and the media uploads yourself, SocialHelper does them. Connect a LinkedIn profile or Page once in the dashboard, then send the text as you’d type it.
curl https://socialhelper.app/api/v1/posts \
-H "Authorization: Bearer $SOCIALHELPER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"text": "We’re hiring 2 engineers (remote, Canada) 🍁 #hiring",
"accounts": [
"LINKEDIN_ACCOUNT_ID"
]
}'
LinkedIn gets the escaped version. The same call can post to your other accounts, attach media or set scheduled_at. The comparison of social media APIs shows how LinkedIn’s rules stack up against the other platforms. AI assistants use the same actions through MCP, and the MCP vs API guide shows the difference.
Frequently asked questions
Where do I get a LinkedIn API key?
Create an app in the LinkedIn Developer Portal. Its Auth tab shows the client ID and client secret. Add a product such as Share on LinkedIn, then get an access token for each member through OAuth.
Does LinkedIn have a public API?
Yes, with limits. Sign-in and posting to the member’s own profile are open to any developer. Company Pages, ads, member post reading and most data need LinkedIn to approve your app for a product.
How much does the LinkedIn API cost?
Nothing today. LinkedIn’s API terms say it doesn’t charge a fee but may in the future. The cost is approval time for the vetted products and the work of keeping up with monthly versions.
Can I post to a LinkedIn Company Page with the API?
Yes, with the Community Management API and w_organization_social, as an administrator or content admin of the Page. The author in the post is the Page’s organization URN.
Can I schedule LinkedIn posts with the API?
Not directly, since the Posts API has no publish-time field. Your app has to hold the post and send it when it’s due. SocialHelper does that when you set scheduled_at.
How long does a LinkedIn access token last?
Sixty days. Approved partners can refresh it for up to 365 days in total, and everyone else signs the member in again.
How we checked
We read LinkedIn’s docs on Microsoft Learn on October 17, 2026. That included the Posts, Images, Videos and MultiImage APIs, the little text format, the OAuth, refresh token, rate limit and versioning pages, and the access tiers. We also read LinkedIn’s API Terms of Use and its help page on app verification, and ran a fact check of every number and quote against them.
We tested the escaping by running the example through SocialHelper’s LinkedIn code on October 17, 2026, and our test suite checks the example request against LinkedIn’s rules. If you spot something that has changed, contact us and we’ll correct it.