Free Tool

LinkedIn Post API Example Builder

Get a working LinkedIn post API example for your exact post: text, image, multi-image, article or poll, in curl, Python or Node, with the headers LinkedIn requires and every reserved character escaped so the post is not cut off.

How to create a LinkedIn post with the API

A LinkedIn post is POST https://api.linkedin.com/rest/posts with Authorization Bearer, Linkedin-Version YYYYMM and X-Restli-Protocol-Version 2.0.0 headers, and a JSON body with author, commentary, visibility, distribution and lifecycleState PUBLISHED.

1 request: one POST /rest/posts.

  • No person ID yet, so the author is a placeholder. The ID is the sub claim from the OpenID Connect userinfo endpoint.
# Create the post. The new post URN comes back in the x-restli-id response header.
curl -i -X POST 'https://api.linkedin.com/rest/posts' \
  -H "Authorization: Bearer $LINKEDIN_TOKEN" \
  -H 'Linkedin-Version: 202609' \
  -H 'X-Restli-Protocol-Version: 2.0.0' \
  -H 'Content-Type: application/json' \
  --data '{
  "author": "urn:li:person:{PERSON_ID}",
  "commentary": "Q3 results \\(up 40%\\) are in. Thanks to \\@\\[Jane\\]\\(urn:li:person:abc123\\) and the team \\#growth\n\n\\* Revenue: \\[redacted\\] \\<for now\\>\n\\* Churn: down\\_2 \\~ flat",
  "visibility": "PUBLIC",
  "distribution": {
    "feedDistribution": "MAIN_FEED",
    "targetEntities": [],
    "thirdPartyDistributionChannels": []
  },
  "lifecycleState": "PUBLISHED",
  "isReshareDisabledByAuthor": false
}'

Built in your browser. Nothing is sent to LinkedIn or to OpenTweet. Set LINKEDIN_TOKEN to an access token with the w_member_social scope before you run it.

What each content type needs

Every type goes through the same /rest/posts call. What changes is the content field and how many uploads come first. Limits are from LinkedIn's Posts, Images, MultiImage and Poll API pages on Microsoft Learn.

Post typeBody fieldRequestsLimits
Text onlyno content field1commentary only
Single imagecontent.media.id3JPG, GIF or PNG, under 36,152,320 pixels, altText up to 4,086 characters
Multi-imagecontent.multiImage.images[]2 per image + 12 to 20 images, organic posts only
Articlecontent.article1, or 3 with a thumbnailsource, title, description and thumbnail set by you, no scraping
Pollcontent.poll1question 140, options 30 each, 2 to 4 options, 1 to 14 days

What the API will not do

Organic carousels are not supported (carousels are sponsored only). Polls are single-vote only and cannot be edited after creation. After publishing, only commentary, the call to action, the landing page, lifecycleState and ad context can be changed with a PARTIAL_UPDATE.

The fields in the body

author is urn:li:person:{id}, where the id is the sub from Sign In with LinkedIn using OpenID Connect, or urn:li:organization:{id} for a Company Page.

commentary is the post text in little text format. It is required, and its reserved characters need escaping.

visibility is PUBLIC, CONNECTIONS (first-degree network) or LOGGED_IN. A fourth value, CONTAINER, hands visibility to a container such as a group.

distribution is { feedDistribution: MAIN_FEED, targetEntities: [], thirdPartyDistributionChannels: [] } for a normal feed post.

lifecycleState must be PUBLISHED. It is the only value LinkedIn accepts on create.

Linkedin-Version is a month in YYYYMM form. LinkedIn has no unversioned calls, and a missing or retired version is rejected. If you get a 426, see LinkedIn API 426 NONEXISTENT_VERSION.

Escaping: why API posts get cut off

LinkedIn's little text format reserves fifteen characters, and its docs say each one needs a backslash even when it is not part of a mention or hashtag. The builder escapes them by default. Switch to the escaper tab to see which characters in your text were the problem.

\|{}@[]()<>#*_~

The tradeoff: an escaped #tag or @ publishes as plain text. To keep a real mention, leave @[Name](urn:li:person:id) unescaped with the keep option, and see how to mention someone with the LinkedIn API. The full write-up is in why a LinkedIn API post is cut off at a parenthesis.

Or skip the LinkedIn app setup

Connect your LinkedIn profile to OpenTweet once and post with one call. No developer app, no image upload dance, and OpenTweet escapes the reserved characters for you. The same call can post to X and Bluesky too.

one call to OpenTweet
curl -X POST https://opentweet.io/api/v1/posts \
  -H "Authorization: Bearer ot_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Q3 results (up 40%) are in. Thanks to the team.",
    "platforms": ["linkedin"],
    "publish_now": true
  }'

OpenTweet posts to personal LinkedIn profiles with text and images. Polls, article cards and Company Pages still need LinkedIn's API directly.

7-day free trial, then from $11.99/mo. API, X, Bluesky and LinkedIn on every plan.

LinkedIn Posts API FAQ

What does a LinkedIn post API example request look like?

POST https://api.linkedin.com/rest/posts with three headers: Authorization: Bearer and your token, Linkedin-Version with a month such as 202609, and X-Restli-Protocol-Version: 2.0.0. The JSON body needs author (a person or organization URN), commentary, visibility, distribution with feedDistribution MAIN_FEED, and lifecycleState PUBLISHED. A 201 response carries the new post URN in the x-restli-id header.

Why is my LinkedIn API post truncated?

LinkedIn reads commentary as little text format, where | { } @ [ ] ( ) < > # \ * _ ~ are markup. LinkedIn says every one of them must be escaped with a backslash, even outside a mention or hashtag. An unescaped parenthesis or bracket can cut the post off. The escaper tab marks each one and gives you the escaped text.

How many requests does an image post take?

Three for one image: POST /rest/images?action=initializeUpload with the author as owner, a PUT of the bytes to the uploadUrl it returns, then POST /rest/posts with content.media.id set to the image URN. A multi-image post repeats the first two calls for each image, so four images take nine requests.

What are the LinkedIn poll limits in the API?

The question can be up to 140 characters, each option up to 30, and a poll takes 2 to 4 options. Duration is ONE_DAY, THREE_DAYS, SEVEN_DAYS or FOURTEEN_DAYS. Only single-vote polls exist, setting isVoterVisibleToAuthor to false returns 400, and a poll cannot be edited after it is created.

Does the API fetch the title and image for an article link?

No. LinkedIn says the Posts API does not scrape the URL. You set content.article.source, title and description yourself, and the thumbnail is an image URN you upload through the Images API first.

Is there a LinkedIn API Postman collection?

LinkedIn publishes curl samples on Microsoft Learn, and this builder turns them into requests you can run as they are: copy the curl tab and paste it into Postman with Import (replace $LINKEDIN_TOKEN with your token first), or run it in a terminal after setting LINKEDIN_TOKEN.

Can I post as a Company Page?

Yes, with author set to urn:li:organization and an access token that has w_organization_social. The signed-in member also needs the ADMINISTRATOR, CONTENT_ADMIN or DIRECT_SPONSORED_CONTENT_POSTER role on that Page. Posting as yourself needs only w_member_social.

Can OpenTweet post to LinkedIn for me?

Yes, to your personal LinkedIn profile, with text and images, from the dashboard or one call to the OpenTweet API with platforms set to linkedin. OpenTweet escapes every reserved character for you. It does not post polls, article cards or to Company Pages. Plans start at $11.99/month with a 7-day trial.