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.
- POST10 credits
/v1/outbound/connectionsSend Connection Request
Invite a member to connect by slug or profile URL (experimental).
- POST10 credits
/v1/outbound/messagesSend DM
Send a direct message to a 1st-degree connection (experimental).
- POST2 credits
/v1/outbound/connections/withdrawWithdraw Invitation
Retract a pending connection request (shape pending capture).
- POST5 credits
/v1/outbound/posts/{activityId}/reactionsReact to Post
Like / praise / empathy / interest / appreciation / entertainment / funny.
- POST10 credits
/v1/outbound/posts/{activityId}/commentsComment on Post
Add a top-level comment to a post.
- POST5 credits
/v1/outbound/follows/memberFollow Member
Follow a LinkedIn member.
- POST5 credits
/v1/outbound/follows/member/removeUnfollow Member
Stop following a member.
- POST5 credits
/v1/outbound/follows/companyFollow Company
Follow a company page.
- POST5 credits
/v1/outbound/follows/company/removeUnfollow Company
Stop following a company page.
- POST5 credits
/v1/outbound/posts/{ugcPostId}/sharesShare / Repost
Repost an existing post (shape pending capture).
- POST2 credits
/v1/outbound/posts/{activityId}/saveSave Post
Bookmark a post to the viewer's saved items.
- POST2 credits
/v1/outbound/posts/{activityId}/save/removeUnsave Post
Remove a post from the viewer's saved items.
Send connection request
/v1/outbound/connections10 creditsInvites 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.
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
/v1/outbound/messages10 creditsSends 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.
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
/v1/outbound/connections/withdraw2 creditsStub. 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.
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
/v1/outbound/posts/{activityId}/reactions5 creditsAdds 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.
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
/v1/outbound/posts/{activityId}/comments10 creditsPosts 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).
Posts a top-level comment. Plain text only; reply-to-comment threading is a separate surface (not wired yet — coming soon).
Share / repost
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
/v1/outbound/follows/member5 creditsFollows 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.
/v1/outbound/follows/member/remove5 creditsSame voyager endpoint as Follow Member, toggled: PATCH body `{patch: {$set: {following: false}}}`.
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
/v1/outbound/follows/company5 creditsSame voyager endpoint as Follow Member, with a company URN target. Pass the numeric company id or full `urn:li:fsd_company:<id>`.
/v1/outbound/follows/company/remove5 creditsSame endpoint toggled to `following: false`.
Same shape, with a company URN target. Pass urn:li:fsd_company:<id>
or just the numeric ID.
Save / unsave a post
/v1/outbound/posts/{activityId}/save2 creditsPATCH-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.
/v1/outbound/posts/{activityId}/save/remove2 creditsSame save-state endpoint toggled to `saved: false`.
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_throttleduntil 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.