Skip to content
Back to skills

Linkedin

ASecurity

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.

  • 17 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 17, 2026
ai-agentsgobashgcpapi

Works with

  • api

Security analysis

A100/100

Scanned October 17, 2026

npx -y skills add AceDataCloud/Skills --skill linkedin --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Linkedin?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Linkedin
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/acedatacloud-linkedin/badge)](https://www.skillsdirectory.com/skills/acedatacloud-linkedin)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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`.


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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.