# LinkedIn engagement endpoints — captured live 2026-08-07 (via the extension network hook)

## BUILD STATUS (voyager.js methods) — ALL 5 VERIFIED LIVE 2026-08-08 ✅
- `reshare(acc, parentUrn, commentary, opts)` — ✅ graphql `voyagerContentcreationDashShares` (origin RESHARE + parentUrn).
- `createPost(acc, text, opts)` — ✅ same graphql, **plain post = `origin:'FEED'`, no parentUrn, `visibilityType:'ANYONE'`**.
  (⚠️ `connectionsOnly` sends `visibilityType:'CONNECTIONS'` which the enum REJECTS — connections-only visibility enum
  still unconfirmed; PUBLIC posts work. Default to ANYONE.)
- `likePost(acc, link)` — ✅ SDUI **`com.linkedin.sdui.reactions.create`** with `{threadUrn.threadUrnActivityThreadUrn.
  activityUrn.activityId, reactionType:'ReactionType_LIKE', reactionSource:'Update'}` — CLEAN, just needs the activity id
  (extracted from any post link via `activityIdFromLink`). The old `fetchFeedUpdateActionPrompt` was indeed a prompt fetch.
- `follow(acc, memberId)` — ✅ SDUI `addaUpdateFollowState`, needs a NUMERIC member id.
- `getProfile` (profile view) — ✅ existing.
- `sduiAction(acc, sduiid, payload)` — the /flagship-web/rsc-action POST helper (jarFetch-based). RSC response is
  streamed text `0:{"states":…,"response":{…,"errors":[]}}` — success = 2xx + empty errors.
- COMMENT stays MANUAL (SDUI `createComment` is render-state-fragile + spammiest action — deliberately not wired).


**BIG FINDING:** LinkedIn moved **like / comment / follow** OFF the clean voyager API onto a new
**Server-Driven UI (SDUI / RSC)** system at `POST /flagship-web/rsc-action/actions/server-request?sduiid=<id>`.
These payloads are protobuf-shaped JSON that carry a LOT of **page-render state** (componentKeys, stateIds,
optimisticKeys, `updateKey` with a per-render `trackingId`), which makes them far harder + more fragile to
replay server-side than the old voyager calls. **Post/reshare stayed on clean voyager graphql.**

## POST / RESHARE — voyager graphql (CLEAN, replayable) ✅
`POST /voyager/api/graphql?action=execute&queryId=voyagerContentcreationDashShares.80089eb2e82a2dfa23cb621fb09eb7bf`
```json
{"variables":{"post":{"allowedCommentersScope":"ALL","intendedShareLifeCycleState":"PUBLISHED",
  "origin":"RESHARE","visibilityDataUnion":{"visibilityType":"ANYONE"},
  "commentary":{"text":"wow","attributesV2":[]},"parentUrn":"urn:li:share:7490383493743628288"}},
  "queryId":"voyagerContentcreationDashShares.80089eb2e82a2dfa23cb621fb09eb7bf","includeWebMetadata":true}
```
- **Plain original post** = same call, drop `parentUrn`, `origin` != RESHARE (need one plain-post capture to confirm the exact origin enum; everything else identical). `visibilityType`: ANYONE | CONNECTIONS.
- The Sharebox open (`voyagerContentcreationDashSharebox`) + `inSessionRelevance…ClientSignal` are just composer-open + telemetry — ignore.

## FOLLOW — SDUI (self-contained-ish, likely replayable) ✅
`POST /flagship-web/rsc-action/actions/server-request?sduiid=com.linkedin.sdui.requests.mynetwork.addaUpdateFollowState`
core payload: `{"followStateType":"FollowStateType_FOLLOW_ACTIVE","memberUrn":{"memberId":"528742374"},
"postActionSentConfigs":[],"followStateBinding":{"key":"urn:li:fsd_followingState:urn:li:member:528742374","namespace":"MemoryNamespace"}}`
→ needs just the target's NUMERIC member id. Unfollow = FollowStateType_FOLLOW_INACTIVE (guess).

## LIKE — SDUI (needs the feed item's trackingId) ⚠️
`POST /flagship-web/rsc-action/actions/server-request?sduiid=com.linkedin.sdui.comments.fetchFeedUpdateActionPrompt`
payload carries `reactionType:"ReactionType_LIKE"`, `threadUrn.…userGeneratedContentId`, and `updateKey.items[].trackingId`
(per-render) + activityId. **CAVEAT: the sduiid name says "fetch…ActionPrompt" — this may be the prompt fetch, not
the reaction mutation itself. Re-capture just a like to confirm the real react sduiid.** Replay needs the post's
`activityId` + `trackingId` (both come from fetching the feed first).

## COMMENT — SDUI (HARD / fragile) ❌ recommend skip for warmup
`POST /flagship-web/rsc-action/actions/server-request?sduiid=com.linkedin.sdui.comments.createComment`
text lives in `states[]`: `commentBoxText… = "cool"` + `richCommentBoxText… = {text:"cool"}`, plus dozens of
render-specific `componentKey`/`stateId`/`optimisticKey` bindings tied to the rendered comment box. Reconstructing
this headlessly is brittle. Auto-commenting is also the spammiest/most-penalized action (generic comments hurt) —
so the recommendation is to NOT automate comments; leave them manual.

## Implementation notes
- SDUI actions use `POST /flagship-web/rsc-action/...`, NOT `/voyager/api/`. Different base, likely different
  required headers + an RSC-streamed response (parse for success, not clean JSON). Capture the request HEADERS too
  before wiring (the extension already grabs x-li-track/UA/sec-ch-*).
- **Warmup priority given all this: post/reshare (clean) + follow (id-based) + profile-views (getProfile, clean)
  + the connection ramp (already enforced). Like = with feed-trackingId. Comment = manual.** This still gives a
  legit, human-looking warmup without the most fragile piece.
