linkedin

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.

Skill file

Preview skill file
---
name: linkedin
description: 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.
when_to_use: |
  Trigger when the user wants to publish a text or link share to their
  own LinkedIn feed. Posting is public on their profile — confirm the
  text (and link, if any) before publishing. Requires the
  w_member_social scope (granted by the connector at install).
connections: [linkedin]
allowed_tools: [Bash]
license: Apache-2.0
metadata:
  author: acedatacloud
  version: "1.0"
---

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}`.

```bash
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).

```bash
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`.

Source

Creator's repository · acedatacloud/skills

View on GitHub

License: Apache-2.0

Security

Security checks in progress
Results will appear here once audits complete
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk