What “the LinkedIn API” actually is
There is no single LinkedIn API you sign up for. The LinkedIn Developer Portal gives you an app, and the app gets access to products. Each product grants a set of OAuth scopes and endpoints. Some products you add yourself in a click; others LinkedIn vets before approving. What you can build depends entirely on which products your app holds, so that is the first decision.
This page is the map. Two companion pages go deeper on specific questions:
- LinkedIn API access and pricing: what access costs you in approvals, time and engineering.
- How to post to LinkedIn via API: step-by-step video, image, text and company page posts with Upload-Post.
Which LinkedIn API product do you need?
| You want to | Product | Scopes | How you get it |
|---|---|---|---|
| Log members in, read name, photo and email | Sign In with LinkedIn using OpenID Connect | openid, profile, email | Self-serve, Products tab |
| Post, comment and react as the member | Share on LinkedIn | w_member_social | Self-serve, Products tab |
| Post as a company page, read page posts and comments, page and follower analytics | Community Management API | w_organization_social, r_organization_social and others | Vetted: Development tier, then Standard tier with a screencast |
| Read the member’s own posts, comments and likes | Member Post Management | r_member_social | Closed. LinkedIn is not accepting requests |
| Campaigns, ad accounts, lead forms | Advertising API and other Marketing APIs | Product-specific | Vetted, separate application |
Sources: Sign In with LinkedIn, Share on LinkedIn, Posts API, Community Management overview. Read 29 September 2026.
Rule of thumb: if your users post to their own profiles, the two self-serve products are enough and you can ship this week. The moment you need company pages, analytics or comments on page posts, you are in the Community Management API and its review process. A few details worth knowing before you plan around it:
- Sign In with LinkedIn is not identity verification. LinkedIn says so explicitly. It tells you who the member says they are, and the
emailandemail_verifiedfields are optional in the response. - Community Management API wants its own app. LinkedIn asks you to request the Development tier on a new app that has no other API products. If you already have Advertising API access, the documented path is a second app for the review, then Standard tier access added to your original app.
r_member_socialis closed. The Community Management FAQ says it is “a closed permission” and that LinkedIn is not accepting access requests. You can publish to a member’s profile, but you cannot list their posts back.
How to get LinkedIn API access
- Create an app in the Developer Portal and associate it with a LinkedIn Page. A Page admin has to verify the association. (The access and pricing page covers why this step is where most projects stall.)
- Add the self-serve products from the Products tab: Sign In with LinkedIn using OpenID Connect and Share on LinkedIn.
- Register your redirect URL in the Auth tab.
- For company pages, apply for the Community Management API. You start on the Development tier, which LinkedIn documents at 500 requests per app and 100 per member. To move to the Standard tier you fill in the access request form and submit a screencast showing each use case you listed.
OAuth 2.0: 30-minute codes and 60-day tokens
Members authorize your app through the standard three-legged flow:
https://www.linkedin.com/oauth/v2/authorization
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&state=RANDOM_STRING
&scope=openid%20profile%20email%20w_member_socialThe code that comes back to your redirect URL expires after 30 minutes, so exchange it immediately (authorization code flow):
# The code is valid for 30 minutes
curl -X POST https://www.linkedin.com/oauth/v2/accessToken \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=authorization_code \
-d code=AUTH_CODE \
-d redirect_uri=https://yourapp.com/callback \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET
# -> {"access_token": "...", "expires_in": 5184000, ...} (60 days)All access tokens are issued for 60 days. Two rules catch people out. First, if you request a different set of scopes than the member granted before, LinkedIn invalidates the earlier tokens, so adding a scope later means everyone’s old token stops working. Second, refresh tokens are only issued to approved Marketing Developer Platform partners. Those last 365 days from the original authorization and do not reset when you use them (refresh tokens). Without partner status, expect to send every member back through the consent screen every 60 days.
Versioning: the Linkedin-Version header
Since June 2022 LinkedIn’s Marketing APIs live under https://api.linkedin.com/rest/ and are versioned monthly (versioning docs). Every call to /rest/ needs two headers:
Linkedin-Version: YYYYMM, for example202609for September 2026.X-Restli-Protocol-Version: 2.0.0.
Each version is supported for at least one year. After that it is sunset and requests using it return an error, as do requests with no version header at all. The migrations page lists the dates: 202510 sunsets on 15 October 2026 and 202511 on 16 November 2026. Put the version in one config value and put a yearly reminder next to it.
You will still see /v2/ URLs. /v2/userinfo is the OpenID Connect endpoint, and the Share on LinkedIn guide still shows POST /v2/ugcPosts. For new code, LinkedIn’s Posts API documentation says it “replaces the ugcPosts API”, so build on /rest/posts.
Posting with the LinkedIn Posts API
1. Find the author URN
A member post needs the member’s person URN. With the OpenID Connect scopes, the sub field of /v2/userinfo is the ID:
curl https://api.linkedin.com/v2/userinfo \
-H "Authorization: Bearer ACCESS_TOKEN"
# -> {"sub": "782bbtaQ", "name": "...", "picture": "...", ...}
# author URN = urn:li:person:782bbtaQFor a company page, the author is urn:li:organization:{id} instead.
2. Create the post
curl -X POST https://api.linkedin.com/rest/posts \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Linkedin-Version: 202609" \
-H "X-Restli-Protocol-Version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{
"author": "urn:li:person:782bbtaQ",
"commentary": "Shipping notes for this week are up.",
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": false
}'
# 201 Created, post ID in the x-restli-id response header
A successful call returns 201 with the new post’s URN in the x-restli-id header, as urn:li:share:… or urn:li:ugcPost:…. Store it; it is the ID you use for comments, analytics and deletion later (Posts API).
Posting as a page uses the same request with the organization URN. It needs w_organization_social, and the member whose token you use must have the ADMINISTRATOR, CONTENT_ADMIN or DIRECT_SPONSORED_CONTENT_POSTER role on that page.
3. Images, video and documents
Media is never sent inline. You upload it to a separate API first, get back a URN (urn:li:image:…, urn:li:video:… or urn:li:document:…) and reference that URN in the post’s content. For images (Images API):
# 1. Register the upload
curl -X POST "https://api.linkedin.com/rest/images?action=initializeUpload" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Linkedin-Version: 202609" \
-H "X-Restli-Protocol-Version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{"initializeUploadRequest": {"owner": "urn:li:organization:5583111"}}'
# -> {"value": {"uploadUrl": "https://www.linkedin.com/dms-uploads/...",
# "image": "urn:li:image:C4E10AQ..."}}
# 2. Upload the bytes to uploadUrl
curl -X PUT "UPLOAD_URL" \
-H "Authorization: Bearer ACCESS_TOKEN" \
--upload-file chart.png
# 3. Create the post with "content": {"media": {"id": "urn:li:image:C4E10AQ..."}}Images can be JPG, GIF or PNG under 36,152,320 pixels, and GIFs up to 250 frames. Video goes through the Videos API (upload in parts, then finalize) and PDFs or slide decks through the Documents API. Posts with several images use the MultiImage API.
One more difference from the LinkedIn app: the Posts API does not scrape a URL for its preview. For an article post you set the source URL, title, description and thumbnail yourself, uploading the thumbnail through the Images API.
LinkedIn API in Python
LinkedIn has no official Python SDK for the Posts API. You only need requests:
import requests
TOKEN = "ACCESS_TOKEN"
VERSION = "202609" # bump at least once a year
def headers():
return {
"Authorization": f"Bearer {TOKEN}",
"Linkedin-Version": VERSION,
"X-Restli-Protocol-Version": "2.0.0",
"Content-Type": "application/json",
}
def member_urn():
r = requests.get("https://api.linkedin.com/v2/userinfo",
headers={"Authorization": f"Bearer {TOKEN}"})
r.raise_for_status()
return f"urn:li:person:{r.json()['sub']}"
def create_post(author, text):
body = {
"author": author,
"commentary": text,
"visibility": "PUBLIC",
"distribution": {"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": False,
}
r = requests.post("https://api.linkedin.com/rest/posts",
json=body, headers=headers())
if r.status_code == 429:
raise RuntimeError("Daily LinkedIn limit reached, resets at midnight UTC")
r.raise_for_status()
return r.headers["x-restli-id"] # urn:li:share:... or urn:li:ugcPost:...
print(create_post(member_urn(), "Posted with the LinkedIn Posts API."))In production you also need the 60-day re-authorization, the yearly version bump, retries for 5xx responses and, for media, the upload-then-reference sequence above. For the same flow run through Upload-Post, see the LinkedIn posting how-to.
LinkedIn API limits
| Limit | Value |
|---|---|
| Rate limits | Per app and per member, per endpoint, per 24 hours; reset at midnight UTC |
| Where to see them | Not published; the Analytics tab of your app shows endpoints called at least once that day |
| Alerts | Email to developer admins at 75% of the app-level quota |
| Community Management, Development tier | 500 requests per app, 100 per member |
| Authorization code | 30 minutes |
| Access token | 60 days |
| Refresh token | 365 days, approved Marketing Developer Platform partners only |
| API version support | At least one year per monthly version |
| Images | JPG, GIF, PNG; under 36,152,320 pixels; GIF up to 250 frames |
Sources: rate limits, Community Management overview, authorization code flow, refresh tokens, versioning, Images API. Read 29 September 2026.
Because standard limits are not published, do not hardcode one. Make a single test call to every endpoint you use, read the limit off the Analytics tab, and treat a 429 as “stop until midnight UTC” rather than “retry in a second”. LinkedIn notes it can also return 429 briefly to protect its infrastructure.
Common LinkedIn API errors
| Symptom | Usual cause | Fix |
|---|---|---|
| 429 | Daily app or member limit for that endpoint reached | Wait for the midnight UTC reset; check the Analytics tab |
| Version error | Linkedin-Version missing, or set to a sunset version | Send a supported YYYYMM value |
| 401 | Token older than 60 days, revoked, or invalidated by a new scope request | Send the member through OAuth again |
| 403 on page posts | App lacks w_organization_social, or the member has no admin, content admin or sponsored content poster role | Get Community Management access; ask a page admin to assign the role |
| 403 reading member posts | r_member_social is closed | Store post URNs when you create posts; read pages via r_organization_social |
| Code exchange fails | Code older than 30 minutes, reused, or redirect URI mismatch | Exchange immediately with the exact registered URI |
| Link post has no preview | The Posts API does not scrape URLs | Send title, description and an uploaded thumbnail |
The shortcut: LinkedIn posting without the approvals
If LinkedIn is one channel among several, the expensive part is not the POST request. It is the products, the Community Management review, the 60-day re-consent, the version header and three different media upload APIs. Upload-Post’s LinkedIn API runs an approved app, so you connect a profile once and post to it, or to any company page that profile administers, with one request:
# A PDF carousel on a company page, scheduled
curl -X POST https://api.upload-post.com/api/upload_document \
-H "Authorization: Apikey YOUR_KEY" \
-F "user=my-brand" \
-F "platform[]=linkedin" \
-F "[email protected]" \
-F "title=Q3 hiring report" \
-F "description=What we learned hiring 40 engineers this quarter." \
-F "target_linkedin_page_id=107579166" \
-F "scheduled_date=2026-10-02T15:00:00" \
-F "timezone=Europe/London"
That publishes a PDF as a native document carousel on the page at the scheduled time. GET /api/uploadposts/linkedin/pages lists the page IDs you can use in target_linkedin_page_id; leave it out to post to the personal profile. Other options in the docs:
- Every format: text (
/api/upload_text), images (/api/upload_photos), video with custom thumbnail and.srtsubtitles (/api/upload) and documents (/api/upload_document). - Link previews:
linkedin_link_urlbuilds the card, with optionallinkedin_link_titleandlinkedin_link_description. - Visibility and reshares:
linkedin_visibility(PUBLIC,CONNECTIONS,LOGGED_IN,CONTAINER) andlinkedin_disable_reshare. - Scheduling:
scheduled_datewith atimezone, up to 365 days ahead, oradd_to_queue=true. - First comment:
linkedin_first_commentis posted under the new post. - Comments and analytics for company page posts, through the same API as the other platforms.
Polls work on profiles and pages:
curl -X POST https://api.upload-post.com/api/upload_text \
-H "Authorization: Apikey YOUR_KEY" \
-F "user=my-brand" \
-F "platform[]=linkedin" \
-F "title=Quick question for the platform teams out there:" \
-F "linkedin_poll_question=Best day to ship a release?" \
-F "linkedin_poll_options[]=Monday" \
-F "linkedin_poll_options[]=Wednesday" \
-F "linkedin_poll_options[]=Friday" \
-F "linkedin_poll_duration=THREE_DAYS"
The same request can target X, Threads, Facebook and the other supported networks by adding more platform[] values. If you work from an AI assistant, the LinkedIn MCP server exposes the same publishing tools to Claude, ChatGPT and Cursor.
The Free plan is free forever with no card: 10 uploads a month and 2 profiles, with LinkedIn and API access included. Paid plans with unlimited uploads start at $24 a month ($16 billed annually). Compare options in the social media API overview.
Frequently asked questions
Is there a public LinkedIn API?
Yes, but it is split into products, and most of them are gated. Two are self-serve: Sign In with LinkedIn using OpenID Connect (openid, profile, email) and Share on LinkedIn (w_member_social). You add them from the Products tab of your app. Company page posting, page analytics and ads sit behind vetted products such as the Community Management API, which you apply for.
How do I get LinkedIn API access?
Create an app in the LinkedIn Developer Portal, associate it with a LinkedIn Page, and add the products you need from the Products tab. Self-serve products are available straight away. For the Community Management API you request the Development tier on a new app that has no other API products, then upgrade to the Standard tier by submitting a screencast of every use case in your access request.
Which LinkedIn API do I use to post?
The Posts API (POST https://api.linkedin.com/rest/posts). It replaces the older ugcPosts API. To post as a member you need w_member_social, which comes with the self-serve Share on LinkedIn product. To post as a company page you need w_organization_social, which comes with the Community Management API, and the member must be an administrator, content admin or direct sponsored content poster of that page.
What is the LinkedIn-Version header?
LinkedIn versions its /rest/ APIs monthly. Every request needs Linkedin-Version set to a release in YYYYMM format, for example 202609, plus X-Restli-Protocol-Version: 2.0.0. Each version is supported for at least one year. A missing or sunset version returns an error, so plan to bump the header at least once a year. Version 202510 sunsets on 15 October 2026.
Can I read a member’s own posts with the LinkedIn API?
Not unless LinkedIn approves you for r_member_social, and it currently does not. Its Community Management documentation says r_member_social is a closed permission and that LinkedIn is not accepting access requests. Reading posts is possible for company pages you administer, through r_organization_social.
How long do LinkedIn access tokens last?
Sixty days. The authorization code you exchange for a token is valid for 30 minutes. Refresh tokens exist, but only for approved Marketing Developer Platform partners; they last 365 days from the first authorization and do not reset when used. Everyone else sends the member through the OAuth flow again when the token expires.
What are the LinkedIn API rate limits?
LinkedIn sets a daily limit per application and per member for each endpoint, resets them at midnight UTC and returns 429 when you exceed them. Standard limits are not published: you see yours in the Analytics tab of your app after calling an endpoint at least once that day. The Community Management API Development tier is documented at 500 requests per app and 100 per member.
Is the LinkedIn API free?
LinkedIn does not publish a price for its developer products. The cost is the approval process and the engineering work: OAuth, token expiry, version upgrades and media uploads. Our LinkedIn API pricing page covers that in detail.
Can I post to a LinkedIn company page with the API?
Yes, with the Posts API and author set to urn:li:organization:{id}. It needs w_organization_social from the Community Management API, and the authenticated member must hold the ADMINISTRATOR, CONTENT_ADMIN or DIRECT_SPONSORED_CONTENT_POSTER role on the page. Upload-Post supports page posting with target_linkedin_page_id on a connected account.
Does the LinkedIn API generate link previews automatically?
No. The Posts API does not scrape URLs for article posts. You set the article source, title, description and thumbnail yourself, uploading the thumbnail with the Images API first. Upload-Post builds the preview for you from linkedin_link_url.