Platforms

LinkedIn

Publish text, article links, images, video and PDF documents to LinkedIn profiles and Company Pages.

Overview

The linkedin platform publishes with LinkedIn's versioned REST Posts API, to a personal profile or (with extra LinkedIn access) to Company Pages you administer. You can post:

  • Text posts
  • Link (article) posts with your own title and description
  • 1–20 images
  • 1 video
  • A PDF document (LinkedIn is the only platform that accepts "type": "document" media)
  • Company Page @mentions

Connect the account

In Integrations, choose LinkedIn and approve access.

App setup (self-hosted)

  1. In the LinkedIn Developer Portal, open your app's Auth tab and add the redirect URL https://social-publish-kappa.vercel.app/api/integrations/linkedin/callback (override with LINKEDIN_REDIRECT_URI).
  2. On the Products tab, add Sign In with LinkedIn using OpenID Connect and Share on LinkedIn. Both are self-serve.
  3. Set LINKEDIN_CLIENT_ID and LINKEDIN_CLIENT_SECRET.

Scopes requested by default: openid, profile, w_member_social.

FlagAddsEnables
LINKEDIN_ORG_SCOPES=truew_organization_social, r_organization_social, rw_organization_adminPosting to Company Pages you administer, and Page post analytics
LINKEDIN_MEMBER_ANALYTICS_SCOPES=truer_member_postAnalyticsImpressions, clicks and saves on personal posts
LINKEDIN_API_VERSION=YYYYMM—Overrides the LinkedIn API version sent with each request

Only turn these flags on once LinkedIn has granted the matching product to the app behind LINKEDIN_CLIENT_ID. Requesting a scope the app doesn't have makes the whole consent screen fail with unauthorized_scope_error. Company Page posting needs the Community Management API product, which LinkedIn grants only after review and only to an app without other products, so it is usually a separate app. Members must reconnect after a flag is turned on.

LinkedIn access tokens last 60 days. Unless LinkedIn has issued your app refresh tokens, an expired token means the account must be reconnected.

Post types & media rules

RuleLimit
Text3,000 characters
ImagesUp to 20; JPG, PNG or GIF; up to 50 MB each
Video1, MP4 only, up to 500 MB
Images and videoCan't be combined
Document1 PDF, up to 100 MB (LinkedIn also limits it to 300 pages); no other media and no link
Document titleRequired: media[].title or options.documentTitle
Link postarticleUrl is only used when no media is attached
VisibilityCONNECTIONS is only available for personal profiles
MentionsUp to 20 Company Page mentions; each text must appear exactly in the post content

LinkedIn does not fetch the linked page for article posts, so set articleTitle (it defaults to the site name) and articleDescription yourself.

Options

OptionTypeRequiredDefaultDescription
visibilityPUBLIC \CONNECTIONSNo"PUBLIC"
disableResharebooleanNofalseDisable resharing
articleUrlstring (URL)NoLink URL. Creates a link (article) post. Ignored when images or a video are attached.
articleTitlestringNoLink title. Only used with a Link URL. LinkedIn does not fetch the page, so set the title yourself (defaults to the site name).
articleDescriptionstringNoLink description. Only used with a Link URL.
documentTitlestringNoDocument title. Title shown on the PDF card (required when posting a PDF)
mentionsobject[]NoMentions. Tag a company page. LinkedIn only supports mentioning company pages, not personal profiles. "Text to match" must appear exactly in your post content — it becomes the clickable @mention. Items: name, organization, text (max 20).
For mentions, organization accepts an organization URN (urn:li:organization:123), a numeric ID or a vanity name. The first occurrence of text in the post becomes the clickable mention; to mention the same text twice, repeat it in the post and add two mentions.

Examples

PDF document post

curl -X POST https://social-publish-api.onrender.com/v1/posts \
  -H "x-access-key: $RELAYCAST_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "content": "Our 2026 hiring playbook, free to download.",
    "media": [{
      "url": "https://cdn.example.com/hiring-playbook.pdf",
      "type": "document",
      "title": "Hiring Playbook 2026"
    }],
    "targets": [{
      "accountId": "3c8d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
      "options": { "visibility": "PUBLIC" }
    }],
    "publishNow": true
  }'
const res = await fetch("https://social-publish-api.onrender.com/v1/posts", {
  method: "POST",
  headers: {
    "x-access-key": process.env.RELAYCAST_API_KEY!,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    content: "Our 2026 hiring playbook, free to download.",
    media: [
      { url: "https://cdn.example.com/hiring-playbook.pdf", type: "document", title: "Hiring Playbook 2026" },
    ],
    targets: [{ accountId: "3c8d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f", options: { visibility: "PUBLIC" } }],
    publishNow: true,
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://social-publish-api.onrender.com/v1/posts",
    headers={"x-access-key": os.environ["RELAYCAST_API_KEY"]},
    json={
        "content": "Our 2026 hiring playbook, free to download.",
        "media": [{
            "url": "https://cdn.example.com/hiring-playbook.pdf",
            "type": "document",
            "title": "Hiring Playbook 2026",
        }],
        "targets": [{
            "accountId": "3c8d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "options": {"visibility": "PUBLIC"},
        }],
        "publishNow": True,
    },
)
data = res.json()["data"]

A document can only go to LinkedIn accounts. If the same post also targets other platforms, they fail validation; send the PDF in a separate post.

Article link with a Company Page mention

Request body
{
  "content": "Thanks to Microsoft for hosting our meetup. Recap on the blog.",
  "targets": [{
    "accountId": "3c8d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
    "options": {
      "articleUrl": "https://example.com/blog/meetup-recap",
      "articleTitle": "Meetup recap: October 2026",
      "articleDescription": "Talks, slides and photos from the evening.",
      "mentions": [{ "name": "Microsoft", "organization": "microsoft", "text": "Microsoft" }],
      "disableReshare": false
    }
  }],
  "scheduledFor": "2026-11-04T08:00:00Z"
}

Analytics & comments

  • Personal posts: likes and comments. Impressions, reshares, link clicks and saves need r_member_postAnalytics (LINKEDIN_MEMBER_ANALYTICS_SCOPES=true).
  • Company Page posts: impressions, clicks, likes, comments and shares through the Community Management API.

Comments and messaging are not supported for LinkedIn.

Limitations & common errors

ErrorCause
LinkedIn posts allow 3000 charactersText is too long.
LinkedIn posts can have images or one video, not bothMixed images and video.
LinkedIn document posts can't include images or videoA PDF was combined with other media.
LinkedIn document posts can't include a linkarticleUrl set on a document post.
Add a document titleNo media[].title or documentTitle for a PDF.
"…" must appear exactly in the post contentA mention's text isn't in the post.
Target fails: connections-only visibilityvisibility: "CONNECTIONS" on a Company Page account.
Target fails: only MP4 / JPG, PNG and GIFUnsupported media file type.
Target fails: duplicate post (HTTP 422)LinkedIn rejected identical content.
Consent screen shows unauthorized_scope_errorA LinkedIn flag is on without the product approved for the app.
Account becomes reconnect_requiredThe 60-day token expired, or a 403 points at a missing product/permission.

This page is also available as Markdown.