linkedin

v2026.09.24

Publish text / link posts to your LinkedIn personal feed via the LinkedIn Posts API. Use when the user mentions LinkedIn, sharing or posting an update to LinkedIn, or cross-posting an article / link to their LinkedIn feed.

GitHub
Install command
npx skhub add acedatacloud/linkedin
Markdown
SKILL.md

Call the LinkedIn API with curl + jq. The user's bearer token is in $LINKEDIN_TOKEN; every call needs Authorization: Bearer $LINKEDIN_TOKEN.

LinkedIn posts must be authored by the member's URN. Get the member id from the OpenID userinfo endpoint, then build urn:li:person:{sub}.

SUB=$(curl -sS -H "Authorization: Bearer $LINKEDIN_TOKEN" \
  "https://api.linkedin.com/v2/userinfo" | jq -r .sub)
AUTHOR="urn:li:person:$SUB"
echo "$AUTHOR"

Errors are JSON with message / serviceErrorCode — show them verbatim. 401 → token expired (tokens last ~60 days), re-connect the LinkedIn connector.

Publish a post (Posts API)

Confirm the text with the user first. Use the versioned Posts API; set the LinkedIn-Version header to a recent YYYYMM (LinkedIn requires a valid recent version — if you get 426/version errors, bump to the current month).

jq -n --arg a "$AUTHOR" --arg t "My update text. Check out https://studio.acedata.cloud" \
  '{author:$a, commentary:$t, visibility:"PUBLIC",
    distribution:{feedDistribution:"MAIN_FEED", targetEntities:[], thirdPartyDistributionChannels:[]},
    lifecycleState:"PUBLISHED", isReshareDisabledByAuthor:false}' \
| curl -sS -X POST "https://api.linkedin.com/rest/posts" \
    -H "Authorization: Bearer $LINKEDIN_TOKEN" \
    -H "Content-Type: application/json" \
    -H "LinkedIn-Version: 202401" \
    -H "X-Restli-Protocol-Version: 2.0.0" \
    -d @- -D - -o /dev/null | tr -d '\r' | awk '/^[Xx]-[Rr]estli-[Ii]d:|^[Ll]ocation:/{print}'

A successful create returns 201 with the post URN in the x-restli-id (or Location) response header — report that URN / the resulting post URL.

Link posts: put the URL inline in commentary (LinkedIn auto-unfurls it). Rich article attachments need the assets/images API — out of scope for a simple text/link share; keep links inline.

Fallback: legacy ugcPosts

If the versioned endpoint is unavailable for the app, the older POST https://api.linkedin.com/v2/ugcPosts with a specificContent."com.linkedin.ugc.ShareContent" body also works with w_member_social. Prefer /rest/posts above.

Gotchas

  • Author URN must match the token's member (urn:li:person:{sub}) — you can't post as someone else.
  • w_member_social only allows posting to the member's own feed; company Page posts need w_organization_social + an admin role (not in this connector).
  • The LinkedIn-Version header is mandatory for /rest/*; a stale value returns a version error — bump to the current YYYYMM.

Record the output

After you successfully publish and obtain the live result URL, call the built-in publish_artifact tool ONCE so the user can track this deliverable in My Outputs:

publish_artifact(kind="article", channel="linkedin", title="<title>", url="<the REAL returned URL>", status="delivered")

Use the real returned URL — never fabricate one. Call it once per published item, only after delivery is confirmed; skip it (or use status="failed") if publishing failed. See _shared/artifacts.md.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

NOASSERTION

Source path

skills/linkedin

Default branch

main

Latest commit

57cc298

Tree SHA

acaa402