# Outbound (/docs/api/outbound)



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](/docs/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.

<EndpointList topic="outbound" />

## Send connection request [#send-connection-request]

<EndpointDemo id="outbound-send-connection" />

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 [#send-dm]

<EndpointDemo id="outbound-send-message" />

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 [#withdraw-a-pending-invitation]

<EndpointDemo id="outbound-withdraw-invitation" />

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 [#react-to-a-post]

<EndpointDemo id="outbound-react-post" />

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 [#comment-on-a-post]

<EndpointDemo id="outbound-comment-post" />

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

## Share / repost [#share--repost]

<EndpointDemo id="outbound-share-post" />

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](/changelog).

## Follow / unfollow a member [#follow--unfollow-a-member]

<EndpointDemo id="outbound-follow-member" />

<EndpointDemo id="outbound-unfollow-member" />

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 [#follow--unfollow-a-company]

<EndpointDemo id="outbound-follow-company" />

<EndpointDemo id="outbound-unfollow-company" />

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

## Save / unsave a post [#save--unsave-a-post]

<EndpointDemo id="outbound-save-post" />

<EndpointDemo id="outbound-unsave-post" />

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

## Throttling and idempotency [#throttling-and-idempotency]

* All outbound actions are throttled both per-tier (LinkFetch) and
  per-user (LinkedIn-side; the extension enforces locally) — see
  [Rate limits](/docs/rate-limits).
* Pass `Idempotency-Key: <uuid>` to dedupe retries — the cached
  response is replayed for 24 hours. See [Errors](/docs/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" [#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.
