Skip to main content
Before you start. v1 supports personal posting only (urn:li:person:*). Organization / Company Page posting requires LinkedIn’s Marketing Developer Platform (MDP) approval plus the w_organization_social scope — passing an urn:li:organization:* author URN today fails preflight with linkedin.author.org_not_supported.

Quick reference

Limit / capabilityValue
Character limit3,000 graphemes (emoji-aware)
Author URN formaturn:li:person:{id} (org URNs gated behind MDP)
VisibilityPUBLIC or CONNECTIONS
Post types supportedtext
Images / video / documentNot supported in v1 (media slice TBD)
SchedulingYes (via scheduledAt)
Reply / thread supportNot supported in v1
First commentNot supported in v1
Inbox / DMNot supported in v1
AnalyticsNot supported in v1

Connect an account

POST /v1/accounts/connect/linkedin. OAuth 2.0, three-legged. After the callback the provider calls /v2/userinfo to mint a stable urn:li:person:{id} author URN, stored on tokenMetadata.authorUrn. That URN is what posts.author carries on every publish.

Scopes

scoperequested
w_member_socialalways — required to post on a personal account.
openid, profilealways — needed to mint the URN via /v2/userinfo.
emailextended only.
r_organization_social, w_organization_socialextended only — gated behind MDP approval.
Until MDP clears for your app, extended org scopes are off by default and any attempt to post against an org URN fails preflight.

Version pinning

LinkedIn sunset five API versions in six months from 2024 – 2025. letmepost pins a single version on the Linkedin-Version header and upgrades internally; the public version tracker (GET /v1/platform-versions) shows the current pin and any in-flight migration. When LinkedIn announces a sunset, version.deprecated fires on the affected accounts.

Token lifecycle

LinkedIn tokens last 60 days with no refresh — re-auth is mandatory at expiry. letmepost fires token.expiring seven days ahead so you can prompt the user.

Post types

Text post

text.json
{
  "targets": [{ "accountId": "..." }],
  "text": "Personal LinkedIn post"
}
The author URN is resolved from the connected account; passing an explicit author URN on the request body is not required (and is overridden by the connect-time URN).

Wisdom (platform-specific things that bite)

  • External URLs in the post body materially reduce LinkedIn’s organic reach. LinkedIn’s distribution algorithm de-prioritizes posts that link off-platform. The standard remediation is to keep the body link-free and put the URL in the first comment — but letmepost does not yet support a firstComment field on LinkedIn (the v2 comment API isn’t wired). For now, post without the link and drop it manually, or post the link in the body and accept the reach hit.
  • LinkedIn tokens have no refresh token. They die at 60 days, hard. Subscribe to token.expiring and prompt the user before they lose the connection — the publisher returns platform_auth_failed the moment the token aged out.
  • The post id and uri come back as the LinkedIn URN itself (urn:li:share:…), not a clickable URL — LinkedIn’s create response doesn’t include a web permalink. Construct the public URL with the URN’s numeric tail if you need one.
  • Org / Company posting needs both MDP approval and the w_organization_social extended scope. Posting against an urn:li:organization:* URN fails preflight with a remediation that points at the post-MDP follow-up slice.
  • LinkedIn’s character counter is grapheme-aware: emoji + ZWJ sequences count as one grapheme, matching the publisher’s preflight counter.
  • The version tracker is the canonical source for “what LinkedIn API version letmepost is running against right now” — when LinkedIn ships a versioned change, our migration runs centrally and you see the rollover via the version.deprecated webhook.

Common errors

Error ruleWhat it meansHow to fix
linkedin.text.non_emptyEmpty post bodyProvide non-whitespace text.
linkedin.text.max_graphemesBody > 3,000 graphemesTrim under 3,000.
linkedin.author.urn_formatAuthor URN doesn’t match urn:li:person:* or urn:li:organization:*Use the URN persisted at connect (the publisher does this for you).
linkedin.author.org_not_supportedTried to publish under an urn:li:organization:* URNUse a person URN. Org posting requires MDP approval and lands in a follow-up slice.
linkedin.author.unresolvedAccount row missing the cached author URNDisconnect and reconnect — the URN is minted at connect from /v2/userinfo.
linkedin.visibility.enumVisibility wasn’t PUBLIC or CONNECTIONSPass one of those two values, or omit (defaults to PUBLIC).

What you can’t do (yet)

  • Organization / Company Page posts (requires MDP).
  • Image, video, multi-image, or document posts (media slice deferred).
  • Polls.
  • First comment / threaded replies as the author.
  • Mentions of other LinkedIn members (requires the v2 entity resolution surface).
  • Reading post engagement, comments, or impressions.
  • Scheduling via LinkedIn’s own scheduled-post API — scheduledAt runs in letmepost’s queue instead.

API reference