Automating LinkedIn Posts with the REST Share API: A Practical Guide
Automate LinkedIn posts with the Share API (v2). Learn how to set up OAuth 2.0, craft UGC post requests, handle media uploads, respect rate limits, and avoid policy violations.
13 Feb 2026, 04:12 UTC

Problem: Manual Posting Is Time‑Consuming
Marketers, social teams, and content creators often need to publish the same update across multiple channels. Manually hitting LinkedIn’s web interface for every post is tedious and error‑prone, especially when you want to schedule content or integrate it into a CI/CD pipeline.
Thesis: Use LinkedIn’s Share API (v2) with OAuth 2.0 to Post Programmatically
The Share API (also known as the UGC Posts endpoint) lets an authenticated application create status updates, articles, or media attachments on a user’s or company’s feed. By following the steps below you can automate posting while staying within LinkedIn’s rate limits and policy constraints.
1. Set Up a LinkedIn Developer App
- Register at LinkedIn Developers and create a new app.
- Enable the following OAuth scopes:
r_liteprofile– read basic profile data (required for member posts)w_member_social– write posts on behalf of a userw_organization_social– write posts on behalf of an organization (optional, needed for company pages)
- Set the redirect URI for the OAuth flow (e.g.,
https://yourapp.com/auth/linkedin/callback).
Obtaining an Access Token
Use the standard OAuth 2.0 Authorization Code Flow. After the user authorizes your app, exchange the code for an access token:
curl -X POST \
https://www.linkedin.com/oauth/v2/accessToken \
-d grant_type=authorization_code \
-d code=<AUTH_CODE> \
-d redirect_uri=<REDIRECT_URI> \
-d client_id=<CLIENT_ID> \
-d client_secret=<CLIENT_SECRET>
Store the access_token securely; it expires in 60 days and must be refreshed with a refresh token.
2. Crafting the POST /ugcPosts Request
The core endpoint is https://api.linkedin.com/v2/ugcPosts. A minimal text post payload looks like this:
{
"author": "urn:li:person:YOUR_PERSON_URN",
"lifecycleState": "PUBLISHED",
"specificContent": {
"com.linkedin.ugc.ShareContent": {
"shareCommentary": {
"text": "Hello LinkedIn!"
},
"shareMediaCategory": "NONE"
}
},
"visibility": {
"com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
}
}
Replace YOUR_PERSON_URN with the user’s URN (e.g., urn:li:person:12345678) or, for organization posts, use urn:li:organization:ORG_ID. The visibility field controls who can see the post.
Headers & Execution
Run this request from any environment that can make HTTPS calls. Example with curl:
curl -X POST \
https://api.linkedin.com/v2/ugcPosts \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "X-Restli-Protocol-Version: 2.0.0" \
-H "Content-Type: application/json" \
-d @post_payload.json
Expected response:
- Status
201 Created - Body contains the URN of the new post, e.g.,
{"id":"urn:li:share:1234567890"}
3. Adding Media (Images, PDFs, Video)
Media requires a two‑step process: upload the file to LinkedIn’s media endpoint to obtain a media_id, then reference that ID in the ugcPosts payload.
- Upload the file to
https://api.linkedin.com/v2/assets?action=registerUploadwith a JSON body that includes the upload URL and asset type. - Transfer the file to the URL returned in the previous step (usually a signed PUT request).
- Use the resulting asset URN in the
specificContentfield, e.g.:"shareMediaCategory": "IMAGE", "media": [ { "status": "READY", "description": {"text": "An image"}, "media": "urn:li:digitalmediaAsset:1234567890", "title": {"text": "Sample"} } ]
Full details are in the LinkedIn API docs; keep the upload flow separate from the final share request.
4. Rate Limits & Error Handling
LinkedIn enforces per‑token limits to prevent abuse. The current defaults are:
| Post Type | Requests | Window | Burst |
|---|---|---|---|
| Member posts | 100 | 10 minutes | 10 |
| Organization posts | 200 | 10 minutes | 10 |
When you hit a limit you’ll receive HTTP 429 Too Many Requests and the response header X-Restli-Error-Count indicates how many requests are still allowed in the current window. Keep a counter in your application to throttle accordingly.
Other common errors:
401 Unauthorized– token expired or missing scopes.403 Forbidden– insufficient permissions (e.g., posting to an org withoutw_organization_social).400 Bad Request– malformed JSON or missing required fields.
5. Trade‑offs & Limitations
- **Limited to LinkedIn’s API** – you cannot post to other networks automatically with the same token.
- **Policy constraints** – LinkedIn’s developer policy discourages bulk or repetitive posting. Excessive automation can trigger account restrictions.
- **Media upload complexity** – images and videos require a separate upload flow and can be error‑prone if the transfer step fails.
- **Rate limits** – for high‑volume schedules you need to implement back‑off and queueing logic.
Actionable Closing
- Create a LinkedIn developer app and request the necessary OAuth scopes.
- Implement the OAuth 2.0 Authorization Code Flow to obtain an
access_token. - Write a small wrapper around
/ugcPosts(and/assetsfor media) that respects rate limits and retries on 429. - Test with a simple text post using the
curlexample above; verify a201 Createdand the returned post URN. - Integrate the wrapper into your content pipeline or scheduler, ensuring you monitor LinkedIn’s usage dashboard.
By following these steps you can reliably automate LinkedIn posting while staying compliant with LinkedIn’s API policies.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.