RelayAPI

LinkedIn API

Schedule and automate LinkedIn posts with RelayAPI — text, images, videos, document carousels, first comments, and company pages.

Quick Reference

PropertyValue
Platform keylinkedin
Auth methodOAuth 2.0
Character limit3,000
Images per post20
Videos per post1
Documents per post1 (PDF, PPT, PPTX, DOC, DOCX)
Image formatsJPEG, PNG, GIF
Image max size10 MB
Video formatsMP4
Video max size500 MB
Video max duration10 min (personal), 30 min (company page)
Post typesText, Image, Multi-image, Video, Document/Carousel
SchedulingYes
AnalyticsYes (impressions, reach, likes, comments, shares, clicks, views)

Client optionsTypeScript · Python REST/OpenAPI · Go · Java · REST API

Before You Start

LinkedIn actively suppresses posts with external links — expect a 40-50% reach drop. Always put links in a first_comment instead of the main content. LinkedIn has very strict duplicate detection — even minor rephrasing may not be enough to avoid a 422 error. You cannot mix media types (images + videos, or images + documents) in the same post. GIFs are converted to video and count against the 1-video-per-post limit.

Quick Start

Post to LinkedIn:

import Relay from '@relayapi/sdk';

const client = new Relay();
const post = await client.posts.create({
  content: 'I spent 3 years building the wrong product.\n\nHere is what I learned about validating ideas before writing code...',
  targets: ['linkedin'],
  scheduled_at: 'now',
});

console.log(post.id); // post_abc123

Content Types

Text-Only Post

Text posts have the highest organic reach on LinkedIn. First ~210 characters are visible before the "see more" fold, so front-load your hook.

const post = await client.posts.create({
  content: 'I spent 3 years building the wrong product.\n\nHere is what I learned about validating ideas before writing code...',
  targets: ['linkedin'],
  scheduled_at: 'now',
});

Single Image Post

const post = await client.posts.create({
  content: 'Our new office setup!',
  targets: ['linkedin'],
  media: [
    { url: 'https://cdn.example.com/office.jpg', type: 'image' },
  ],
  scheduled_at: 'now',
});

Multi-Image Post (Up to 20)

LinkedIn supports up to 20 images per post. Cannot include videos or documents alongside images.

const post = await client.posts.create({
  content: 'Highlights from our team retreat!',
  targets: ['linkedin'],
  media: [
    { url: 'https://cdn.example.com/photo1.jpg', type: 'image' },
    { url: 'https://cdn.example.com/photo2.jpg', type: 'image' },
    { url: 'https://cdn.example.com/photo3.jpg', type: 'image' },
  ],
  scheduled_at: 'now',
});

Video Post

const post = await client.posts.create({
  content: 'Watch our latest product demo',
  targets: ['linkedin'],
  media: [
    { url: 'https://cdn.example.com/demo.mp4', type: 'video' },
  ],
  scheduled_at: 'now',
});

Document/Carousel Post (PDF)

LinkedIn uniquely supports document uploads that display as swipeable carousels. Upload a PDF, PPT, PPTX, DOC, or DOCX file. Max 100 MB, up to 300 pages.

const post = await client.posts.create({
  content: 'Download our 2024 Industry Report',
  targets: ['linkedin'],
  media: [
    { url: 'https://cdn.example.com/report.pdf', type: 'document' },
  ],
  scheduled_at: 'now',
  target_options: {
    linkedin: {
      document_title: '2024 Industry Report',
    },
  },
});

Document carousels are one of the highest-engagement post formats on LinkedIn. Each page of the PDF becomes a swipeable slide.

Post with First Comment (Put Links Here!)

LinkedIn actively suppresses posts containing external URLs — expect a 40-50% reach drop. Put links in the first comment instead.

const post = await client.posts.create({
  content: 'We just published our guide to API design patterns.\n\nLink in the first comment.',
  targets: ['linkedin'],
  scheduled_at: 'now',
  target_options: {
    linkedin: {
      first_comment: 'Read the full guide here: https://example.com/api-guide',
    },
  },
});

Putting links in the main content field causes a significant reach penalty on LinkedIn. Always use first_comment for external URLs.

Company Page Post

Post to a company page instead of a personal profile by targeting the RelayAPI account created when that organization was selected during the LinkedIn connection flow. The connected member or organization URN is authoritative for every post; a post cannot use an option to redirect that OAuth token to another company.

const post = await client.posts.create({
  content: 'Update from our organization!',
  targets: ['acc_linkedin_company'],
  scheduled_at: 'now',
});

Media Requirements

Images

PropertyRequirement
Max per post20
FormatsJPEG, PNG, GIF
Max file size8 MB per image
Recommended1200 x 627 px (1.91:1)
Min dimensions552 x 276 px

Videos

PropertyRequirement
Max per post1
FormatsMP4
Max file size500 MB
Max duration10 min (personal profile), 30 min (company page)
Recommended1920 x 1080, H.264, AAC 192kbps, 30fps

Documents

PropertyRequirement
Max per post1
FormatsPDF, PPT, PPTX, DOC, DOCX
Max file size100 MB
Max pages300

target_options Fields

All fields go inside target_options.linkedin on your post request.

FieldTypeDescription
contentstringOverride content for LinkedIn specifically
mediaobject[]Override media for LinkedIn specifically
first_commentstringAuto-posted first comment. Put links here to avoid reach suppression.
document_titlestringTitle displayed on PDF/document carousel posts
disable_link_previewbooleanSuppress URL preview card in the post (default: false)
organization_urnstringDeprecated identity assertion only. If supplied, it must exactly match the connected member/organization URN; it never retargets the post.

Common Errors

ErrorCauseFix
Content is a duplicate (422)Identical or very similar content posted recentlyModify text meaningfully. LinkedIn's duplicate detection is very strict.
Preflight checks failedRate limiting or validation issueSpace posts further apart.
Publishing failed max retriesAll retry attempts failedTemporary issue — retry manually after a few minutes.
Token expiredOAuth token expiredReconnect the account via the dashboard or Connect API.
Cannot mix media typesImages + videos or images + documents in same postUse only one media type per post. GIFs count as video.
ORGANIZATION_URN_MISMATCHDeprecated organization_urn does not equal the connector-selected identityTarget the correct connected account and remove the compatibility field; RelayAPI rejects the mismatch before provider I/O.

Known Quirks

  • Link suppression — posts with external URLs get 40-50% less reach. Always put links in first_comment.
  • Very strict duplicate detection — even minor rephrasing may not bypass the 422 duplicate error.
  • Cannot mix media types — images + videos or images + documents in the same post will fail.
  • GIFs are converted to video and count against the 1-video-per-post limit.
  • First ~210 characters visible before the "see more" fold. Front-load your hook.
  • Company pages get 30-minute video limit, personal profiles get 10 minutes.
  • Document carousels are the highest-engagement format but require a PDF, PPT, or DOC file.

Automations

LinkedIn automation uses the Versioned REST API (YYYYMM format) — version pinned in api-versions.ts.

The r_member_social scope is currently closed to new apps per Microsoft docs. Only approved Community Management API apps can use the triggers and send nodes below.

Triggers

TypeFires on
linkedin_commentComment on your share
linkedin_mention@-mention
linkedin_reactionReaction added to your share

Send nodes

Base: https://api.linkedin.com/rest with LinkedIn-Version + X-Restli-Protocol-Version: 2.0.0 headers.

NodeEndpointRequired fields
linkedin_reply_to_commentPOST /socialActions/{urn}/commentstext, share_urn
linkedin_react_to_postPOST /reactions?actor={memberUrn}reaction (default LIKE), share_urn

Found something wrong? Help us improve this page.

On this page