API and developers

How to Post to LinkedIn API (The Easy Way)

LinkedIn's API is notoriously complex. Here's how to skip the OAuth headaches and post to LinkedIn programmatically in a single API call.

Robert LigthartFounder of OmniSocialsPublished Updated 12 min read
How to Post to LinkedIn API (The Easy Way)

LinkedIn's API is one of the most developer-hostile in the industry. OAuth 2.0 setup, a LinkedIn app that needs product access approval, three separate endpoints to compose a single post, and documentation that reads like it was written by a compliance lawyer.

Key takeaways

  • LinkedIn's native API needs a LinkedIn app, approved product access, and OAuth 2.0 before you can post.
  • With the OmniSocials API you connect LinkedIn once in the dashboard and post with one API key, using the linkedin channel for a profile or linkedin_page for a Company Page.
  • Add a future scheduled_at timestamp to schedule a post, or leave it out to save a draft.
  • The OmniSocials API allows 100 requests per minute per key and sends signed webhooks when a post publishes or fails.
  • OmniSocials costs $10 per seat a month billed yearly, while Ayrshare's cheapest plan is $149 a month (checked October 18, 2026).
On this page
  1. Key takeaways
  2. What Does It Take to Post to LinkedIn's Native API?
  3. How to Post to LinkedIn Using the OmniSocials API
  4. What is the OmniSocials API?
  5. Step 1: Get Your API Key
  6. Step 2: Make the API Call
  7. JavaScript
  8. Python
  9. Step 3: Post with an Image
  10. JavaScript
  11. Python
  12. Step 4: Handle the Response
  13. Post to LinkedIn and Other Platforms at Once
  14. How to Use the LinkedIn API with Python
  15. OmniSocials API vs. LinkedIn Native API
  16. Common Pitfalls
  17. 1. Passing a file path to mediaurls
  18. 2. Scheduling a time in the past
  19. 3. LinkedIn account not connected
  20. 4. Rate limit errors (429)
  21. 5. Expecting instant publish confirmation
  22. Frequently Asked Questions
  23. Sources

Most developers waste a full day just getting authentication working.

There's a faster path. The OmniSocials API wraps LinkedIn's entire API surface into a single authenticated endpoint. One request, one API key, no app review process. Here's how it works.


What Does It Take to Post to LinkedIn's Native API?

Before showing the easy way, it's worth understanding why the native approach is so painful.

LinkedIn's native posting API requires:

  1. Creating a LinkedIn app in their developer portal
  2. Requesting product access for the Share on LinkedIn or UGC Posts product (manual review, can take days)
  3. Implementing OAuth 2.0 with scopes like w_member_social
  4. Exchanging and storing tokens (access tokens expire; refresh tokens are limited)
  5. Making a POST to /v2/ugcPosts with a heavily nested JSON payload

Here's what a minimal LinkedIn UGC post payload looks like:

{
  "author": "urn:li:person:{personId}",
  "lifecycleState": "PUBLISHED",
  "specificContent": {
    "com.linkedin.ugc.ShareContent": {
      "shareCommentary": {
        "text": "Hello, LinkedIn."
      },
      "shareMediaCategory": "NONE"
    }
  },
  "visibility": {
    "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
  }
}

That payload is just for a plain text post. Add an image and you're looking at a separate media upload step with its own endpoint, followed by registering the asset, then referencing it in your post request.

It's three API calls to post one image to LinkedIn. Every time.


How to Post to LinkedIn Using the OmniSocials API

What is the OmniSocials API?

The OmniSocials API is a unified social media publishing API that covers 13 platforms, including LinkedIn, Instagram, TikTok, X, Bluesky, and more. You connect your accounts once through the OmniSocials dashboard, and all posting goes through a single endpoint with a single API key. No OAuth per platform. No app reviews. No token management.

At $10 per seat a month (billed yearly), it's also significantly cheaper than alternatives like Ayrshare, whose cheapest plan is $149/mo, or $129/mo billed yearly (prices checked October 18, 2026).


Step 1: Get Your API Key

Sign up at omnisocials.com and start a free 14-day trial.

Once you're in:

  1. Connect your LinkedIn profile or Company Page in the dashboard (takes about 30 seconds, standard OAuth flow, done once)
  2. Go to Settings > API
  3. Click Create API Key and copy the key. It starts with omsk_live_ and is shown once. Store it as OMNISOCIALS_API_KEY.

That's it. OmniSocials handles the LinkedIn app layer. You don't need to register anything with LinkedIn directly.

[Screenshot: OmniSocials Settings > API page showing API key generation and connected LinkedIn account]


Step 2: Make the API Call

With your key in hand, posting to LinkedIn is one call. The examples use the official SDKs for Node.js (npm install @omnisocials/sdk) and Python (pip install omnisocials), which both read OMNISOCIALS_API_KEY from the environment.

JavaScript

import { OmniSocials } from '@omnisocials/sdk';

const client = new OmniSocials(); // reads OMNISOCIALS_API_KEY

const { data: post } = await client.posts.create({
  content: 'Just shipped a new feature. Here is what changed and why.',
  channels: ['linkedin'],
  scheduled_at: '2027-03-02T09:00:00Z',
});

console.log(post.id, post.status); // "1019" "scheduled"

Python

from omnisocials import OmniSocials

client = OmniSocials()  # reads OMNISOCIALS_API_KEY

post = client.posts.create(
    content="Just shipped a new feature. Here is what changed and why.",
    channels=["linkedin"],
    scheduled_at="2027-03-02T09:00:00Z",
)

print(post["data"]["id"])      # 1019
print(post["data"]["status"])  # scheduled

linkedin posts to your personal profile. Use linkedin_page for a Company Page. Leave out scheduled_at and the post is saved as a draft; to publish immediately, call createAndPublish (Node) or create_and_publish (Python) with the same arguments.


Step 3: Post with an Image

Posting an image to LinkedIn natively requires uploading the asset to LinkedIn's media API first, registering it, then referencing it in the post. With OmniSocials, you pass the image URL directly in media_urls.

JavaScript

const { data: post } = await client.posts.create({
  content: 'Q1 results are in. Sharing our key metrics below.',
  channels: ['linkedin'],
  media_urls: ['https://yourcdn.com/q1-results.jpg'],
  scheduled_at: '2027-03-02T09:00:00Z',
});

Python

post = client.posts.create(
    content="Q1 results are in. Sharing our key metrics below.",
    channels=["linkedin"],
    media_urls=["https://yourcdn.com/q1-results.jpg"],
    scheduled_at="2027-03-02T09:00:00Z",
)

OmniSocials downloads the file and handles the upload and registration on LinkedIn's end. One request on your side. A PDF URL works too: it publishes as a swipeable LinkedIn document.


Step 4: Handle the Response

The OmniSocials API returns the same JSON structure regardless of which platforms you post to. After the post goes live, it looks like this (trimmed):

{
  "data": {
    "id": "1019",
    "status": "published",
    "type": "post",
    "content": { "default": "Q1 results are in. Sharing our key metrics below." },
    "schedule_at": "2027-03-02T09:00:00.000Z",
    "published_urls": {
      "linkedin": "https://www.linkedin.com/feed/update/urn:li:share:..."
    },
    "errors": null
  }
}

Status values you'll see:

  • draft: saved, not scheduled
  • scheduled: waiting for its scheduled_at time
  • posting: being published right now
  • published: live on LinkedIn, with the link in published_urls
  • failed or warning: every platform, or some platforms, failed. The reason is in errors (usually an expired connection or a content policy issue).

To check on a post later, fetch it by id:

const { data: latest } = await client.posts.get('1019');
console.log(latest.status, latest.published_urls.linkedin);

For real-time updates, subscribe to the post.published and post.failed webhooks (see our webhooks guide).


Post to LinkedIn and Other Platforms at Once

This is where the OmniSocials API earns its keep for teams managing multiple channels. Add more platforms to channels and OmniSocials handles the cross-posting.

await client.posts.create({
  content: 'Just published a new article. Link in the first comment.',
  channels: ['linkedin', 'instagram', 'bluesky', 'x'],
  media_urls: ['https://yourcdn.com/article-cover.jpg'], // Instagram needs media
  scheduled_at: '2027-03-02T08:00:00Z',
});

Replicating this natively would take four separate integrations. Here it's four strings in an array.


How to Use the LinkedIn API with Python

Steps 2 and 3 show single Python calls. Here's a complete script to copy. It posts a PDF to a Company Page as a swipeable document, adds the link as the first comment, and prints the result. It uses the official OmniSocials Python SDK: pip install omnisocials, Python 3.9 or newer.

from omnisocials import OmniSocials, ValidationError

client = OmniSocials()  # reads OMNISOCIALS_API_KEY

try:
    post = client.posts.create(
        content="Our Q1 report in 8 slides. Swipe through for the numbers.",
        channels=["linkedin_page"],
        media_urls=["https://yourcdn.com/q1-report.pdf"],
        linkedin_page={"first_comment": "Full report: https://yourcdn.com/q1"},
        scheduled_at="2027-03-02T09:00:00Z",
    )
    print(post["data"]["id"], post["data"]["status"])  # 1019 scheduled
except ValidationError as err:
    # platform_not_connected: no Company Page in this workspace
    print(err.code, err.message)
  • The PDF becomes a document. OmniSocials turns its pages into slides, and LinkedIn shows them as a swipeable document.
  • Posting as yourself? Use channels=["linkedin"] and linkedin={"first_comment": ...} for your personal profile.
  • Text or image post: drop media_urls for a text post, or pass a JPG or PNG URL instead of the PDF.

Once the post is live, client.posts.get(post_id)["data"]["published_urls"] holds the LinkedIn link.


OmniSocials API vs. LinkedIn Native API

OmniSocials APILinkedIn Native API
Auth setupOmniSocials API: One API keyLinkedIn Native API: OAuth 2.0 per app
App review requiredOmniSocials API: NoLinkedIn Native API: Yes
Text postOmniSocials API: 1 API callLinkedIn Native API: 1 API call
Image postOmniSocials API: 1 API callLinkedIn Native API: 3 API calls
Cross-platform postingOmniSocials API: Yes (13 platforms)LinkedIn Native API: LinkedIn only
SchedulingOmniSocials API: Built-inLinkedIn Native API: Manual (you build it)
Token managementOmniSocials API: Handled for youLinkedIn Native API: Your responsibility
PriceOmniSocials API: $10 per seat/mo (billed yearly)LinkedIn Native API: Free (LinkedIn tier)

Common Pitfalls

1. Passing a file path to media_urls

media_urls expects publicly accessible URLs, not local paths. If you're working with files on disk, upload them first and pass the returned id in media_ids:

const { data: image } = await client.media.upload({
  file: './q1-results.jpg', // a path, Buffer, or Blob, up to 100 MB
});

await client.posts.create({
  content: 'Q1 results are in.',
  channels: ['linkedin'],
  media_ids: [image.id],
  scheduled_at: '2027-03-02T09:00:00Z',
});

2. Scheduling a time in the past

If scheduled_at is earlier than the current time, the API returns a 400 validation error. Always use ISO 8601 format and include the timezone (a trailing Z means UTC).

3. LinkedIn account not connected

If you get a 400 with the code platform_not_connected, your LinkedIn account isn't connected in the workspace that owns your API key. Connect it in the OmniSocials dashboard. This is a one-time step. Also check that you picked the right channel: linkedin for a profile, linkedin_page for a Company Page.

4. Rate limit errors (429)

The OmniSocials API allows 100 requests per minute per API key. The SDKs retry a 429 automatically after the Retry-After delay. If you call the REST API directly, wait for the Retry-After header value before retrying, and spread bulk jobs over time.

5. Expecting instant publish confirmation

A post marked posting or scheduled hasn't confirmed yet. Publishing happens asynchronously, so use webhooks or poll GET /v1/posts/:id rather than assuming the post went live.


Frequently Asked Questions

Can you post to LinkedIn via API?

Yes. LinkedIn has a native API (the UGC Posts and Share APIs), but it requires OAuth 2.0, a verified LinkedIn app, and several API calls per post. A simpler option is the OmniSocials API, which wraps LinkedIn's API into a single authenticated request using one API key, with no app review process.

Does LinkedIn API require app review?

Yes. LinkedIn's native API requires requesting product access through their developer portal, which involves a manual review that can take days or weeks. Using the OmniSocials API bypasses this entirely. You connect your LinkedIn account in the OmniSocials dashboard once, and OmniSocials handles the verified app layer for you.

How do I schedule a LinkedIn post via API?

With the OmniSocials API, add a scheduled_at field (a future ISO 8601 timestamp) to your POST /v1/posts request. Example: "scheduled_at": "2027-03-02T09:00:00Z". OmniSocials queues the post and publishes it automatically at the specified UTC time.

What is the LinkedIn API rate limit?

LinkedIn's native API caps the Share API at around 100 calls per day per user token. The OmniSocials API allows up to 100 requests per minute per API key and handles LinkedIn's underlying rate limits for you.

Can I post to LinkedIn and other platforms in one API call?

Not with LinkedIn's native API. With the OmniSocials API, you can post to LinkedIn, Instagram, Bluesky, X, TikTok, and 7 other platforms in a single request by listing them in the channels array.

How do I use the LinkedIn API with Python?

The native route is a LinkedIn app with OAuth 2.0 and approved product access, then a POST to the UGC Posts API with requests. The shorter route is the OmniSocials Python SDK: pip install omnisocials, connect LinkedIn once in the dashboard, set OMNISOCIALS_API_KEY, and call client.posts.create() with channels=["linkedin"] for a profile or ["linkedin_page"] for a Company Page.


Sources

Written byRobert LigthartFounder of OmniSocials

Try OmniSocials for 14 days

Plan, schedule and answer on 13 platforms from one calendar, or let your AI agent do it. The first charge comes when the trial ends.