Outbound

Connection requests, DMs, reactions, comments, follows, and saves — through the user's own LinkedIn session.

Outbound endpoints let an agent act on the LinkedIn graph on behalf of an authenticated user. Connection requests, DMs, reactions, comments, follows, and saves all dispatch through the LinkFetch Chrome extension on the user's signed-in tab — the API itself never talks to LinkedIn for writes.

This is intentional. Outbound is the surface where compliance posture matters most: the user is the principal, the action is audit-logged with provenance, and we throttle locally to keep the user's account out of LinkedIn's anti-spam crosshairs. No strangers' DMs: the extension verifies a 1st-degree connection before sending.

Send connection request

POST/v1/outbound/connections10 credits
Send Connection Request
Invite a member to connect by slug or profile URL (experimental).

Invites a LinkedIn member to connect via the extension on the user's signed-in session. Pass the vanity slug (e.g. `jdoe`) or a full `/in/` URL — the extension resolves the internal profile URN for you via a cheap `identity/dash/profiles` lookup, then issues the voyager `verifyQuotaAndCreateV2` mutation. The backend route is a 501 stub — use the Capture button to run end-to-end through the extension. The `note` variant (invite with custom message) isn't wired yet; shape pending capture.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Pass the recipient's vanity slug (reidhoffman) or full /in/ URL. The extension resolves the internal profile URN via a cheap identity-dash lookup, then issues the verifyQuotaAndCreateV2 mutation through the user's session.

LinkedIn's invitation cap is roughly 80/week per account and LinkFetch will refuse new requests when you're at the cap (429 outbound_throttled with next_available_at).

Send DM

POST/v1/outbound/messages10 credits
Send DM
Send a direct message to a 1st-degree connection (experimental).

Sends a direct message via the extension on the user's signed-in session. Pass the vanity slug or `/in/` URL — the extension resolves it to a profile URN, **verifies the target is a 1st-degree connection**, and only then issues the voyager `createMessage` mutation. Non-1st-degree targets return `409 not_connected` instead — LinkFetch refuses stranger DMs to avoid message-request caps and ban risk. Send a connection request first if you're not connected yet.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Sends a direct message via the extension. Strangers blocked: the extension verifies the target is a 1st-degree connection before issuing the createMessage mutation. Non-1st-degree targets return 409 not_connected instead — send a connection request first.

body is plain text; LinkedIn strips Markdown. Mentions and attachments are not supported on this surface yet.

Withdraw a pending invitation

POST/v1/outbound/connections/withdraw2 credits
Withdraw Invitation
Retract a pending connection request (shape pending capture).

Stub. Voyager path confirmed alive: `DELETE /voyager/api/voyagerRelationshipsDashMemberRelationships/<invitation-urn>`. Request body shape pending a UI capture (next session). The invitation URN comes from the Sent-Invitations page — not the same as the invitee's profile URN.

parameters
invitationUrnstring · in body · required

`urn:li:fsd_invitation:<id>` — fetched from the sent-invitations listing. The underlying voyager call is `DELETE`, but the LinkFetch wrapper takes a POST.

This endpoint isn’t directly callable — it’s invoked by the LinkFetch extension or another LinkFetch service. The shape above is documented so you can build matching integrations.

open in full playground →

Retracts a connection request you've sent that hasn't been accepted yet. Pass the invitation URN (different from the profile URN) — it's the urn:li:fsd_invitation:<id> value from the sent-invitations listing.

React to a post

POST/v1/outbound/posts/{activityId}/reactions5 credits
React to Post
Like / praise / empathy / interest / appreciation / entertainment / funny.

Adds a reaction to a LinkedIn post via the extension on the user's session. Voyager path: graphql mutation `voyagerSocialDashReactions.<hash>` with `{entity: {reactionType}, threadUrn: urn:li:activity:<id>}`. Modern posts use the activity URN directly as threadUrn — no ugcPost namespace split. The backend route is a 422 extension_required stub — Run fires the Capture path end-to-end via the extension.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Reaction types: LIKE, PRAISE, EMPATHY, INTEREST, APPRECIATION, ENTERTAINMENT, FUNNY. Modern posts use the activity URN directly as threadUrn — no ugcPost namespace split. Idempotent on repeats.

Comment on a post

POST/v1/outbound/posts/{activityId}/comments10 credits
Comment on Post
Add a top-level comment to a post.

Posts a top-level comment on a LinkedIn post via the extension. Voyager path: `POST /voyager/api/voyagerSocialDashNormComments?decorationId=…NormComment-43`. Body: `{commentary: {text, attributesV2: [], $type: TextViewModel}, threadUrn: urn:li:activity:<id>}`. Reply-to-comment threading is a separate surface (not wired yet).

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Posts a top-level comment. Plain text only; reply-to-comment threading is a separate surface (not wired yet — coming soon).

Share / repost

POST/v1/outbound/posts/{ugcPostId}/shares5 credits
Share / Repost
Repost an existing post (shape pending capture).

Stub. Two voyager paths probed and both alive — we'll prefer the dash route: `POST /voyager/api/contentcreation/normShares`. Legacy REST `POST /voyager/api/feed/updates?action=createReshare` also responds but is likely retiring. Body pending capture.

parameters
ugcPostIdstring · in path · required

Numeric id of the source post's ugcPost URN.

commentarystring · in body · optional

Optional commentary to attach to the repost.

This endpoint isn’t directly callable — it’s invoked by the LinkFetch extension or another LinkFetch service. The shape above is documented so you can build matching integrations.

open in full playground →

Reposts a source post on the user's feed. commentary is the optional repost note. Body shape pending capture; not directly runnable yet — you can subscribe to ship updates on the changelog.

Follow / unfollow a member

POST/v1/outbound/follows/member5 credits
Follow Member
Follow a LinkedIn member.

Follows a member via the extension. Voyager path: `POST /voyager/api/feed/dash/followingStates/urn:li:fsd_followingState:urn:li:fsd_profile:<tail>` with PATCH body `{patch: {$set: {following: true}}}`. The profile UI moved to SDUI but this voyager endpoint is still alive — LinkFetch bypasses SDUI entirely. Pass a full `urn:li:fsd_profile:<tail>` or just the opaque tail. For `following: false` (unfollow) use the matching entry.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.
POST/v1/outbound/follows/member/remove5 credits
Unfollow Member
Stop following a member.

Same voyager endpoint as Follow Member, toggled: PATCH body `{patch: {$set: {following: false}}}`.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Targets the profile URN — pass the full urn:li:fsd_profile:<tail> or just the opaque ACoAA… tail. The same voyager endpoint serves both follow and unfollow; LinkFetch toggles the patch body on your behalf.

Follow / unfollow a company

POST/v1/outbound/follows/company5 credits
Follow Company
Follow a company page.

Same voyager endpoint as Follow Member, with a company URN target. Pass the numeric company id or full `urn:li:fsd_company:<id>`.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.
POST/v1/outbound/follows/company/remove5 credits
Unfollow Company
Stop following a company page.

Same endpoint toggled to `following: false`.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Same shape, with a company URN target. Pass urn:li:fsd_company:<id> or just the numeric ID.

Save / unsave a post

POST/v1/outbound/posts/{activityId}/save2 credits
Save Post
Bookmark a post to the viewer's saved items.

PATCH-style state update: `POST /voyager/api/voyagerFeedDashSaveStates/<urn:li:fsd_saveState:(SAVE,urn:li:activity:<id>)>` with `{patch: {$set: {saved: true}}}`. Pass `saved: false` via the Unsave entry to remove the bookmark.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.
POST/v1/outbound/posts/{activityId}/save/remove2 credits
Unsave Post
Remove a post from the viewer's saved items.

Same save-state endpoint toggled to `saved: false`.

parameters
This endpoint resolves through the Chrome extension when the row isn't cached. Open it in the full playground to capture via extension.

Bookmarks the post in the user's saved-items list. Same endpoint as save, toggled to saved: false.

Throttling and idempotency

  • All outbound actions are throttled both per-tier (LinkFetch) and per-user (LinkedIn-side; the extension enforces locally) — see Rate limits.
  • Pass Idempotency-Key: <uuid> to dedupe retries — the cached response is replayed for 24 hours. See Errors.
  • When LinkedIn serves a security challenge to the user, the extension automatically pauses outbound for 24 hours. The API returns 429 outbound_throttled until it clears.

Why "extension-only"

LinkedIn's terms of service forbid automated logins. Running the write directly from a centralised service that holds session cookies is — at best — a TOS violation; in practice it's how every prior generation of LinkedIn outbound vendor has been shut down. LinkFetch dispatches every action from the user's own browser, so LinkedIn sees what it expects: a real person on a real device. We sell typed access, not impersonation.