Skip to main content
LinkedIn supports text, image, carousel, and video posts to your personal profile and/or organization (company) pages.

Connect

curl -X POST "https://backend.postsiva.com/unified/oauth/url" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: psk_live_YOUR_KEY" \
  -d '{"platform": ["linkedin"]}'
Complete OAuth at the returned auth_url.

Post types

TypeEndpointNotes
TextPOST /unified/post/textUp to 3,000 characters
ImagePOST /unified/post/imageSingle image
CarouselPOST /unified/post/carousel2–20 images
VideoPOST /unified/post/videoOptional thumbnail generation

Personal vs organization pages

LinkedIn destinations are controlled with linkedin.linkedin_page_ids and linkedin.post_to_personal:
Scenariolinkedin_page_idspost_to_personalResult
Personal onlyomit or []Posts to your profile
One org page["108813535"]omittedPosts to that org only
Personal + orgs["108813535"]trueProfile + org page
Multiple orgs["108813535", "109408332"]falseAll listed orgs only
Get org page IDs from GET /unified/user-profiles/ or list pages in the Postsiva app under Settings → Integrations → LinkedIn.

Example: personal + two org pages

curl -X POST "https://backend.postsiva.com/unified/post/text" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: psk_live_YOUR_KEY" \
  -d '{
    "platforms": ["linkedin"],
    "default_text": "Company update from Postsiva API.",
    "linkedin": {
      "linkedin_page_ids": ["108813535", "109408332"],
      "post_to_personal": true
    }
  }'

Per-page text and images

Use maps keyed by page/org ID when each destination needs different copy or media:
{
  "platforms": ["linkedin"],
  "default_text": "Fallback caption for pages not in the map.",
  "linkedin": {
    "linkedin_page_ids": ["108813535", "109408332"],
    "post_to_personal": false,
    "linkedin_page_texts": {
      "108813535": "Custom copy for Acme Corp page.",
      "109408332": "Different copy for Beta Inc page."
    },
    "linkedin_page_images": {
      "108813535": "media-uuid-for-acme-image"
    }
  }
}

Character limit

LinkedIn text (profile and org posts) is capped at 3,000 characters. Exceeding the limit returns 422:
{
  "detail": "Max text character limit for linkedin is 3000. Received 3200 characters in linkedin_text/default_text."
}
See Character limits.

Visibility

Set visibility to PUBLIC (default) or CONNECTIONS for profile posts:
{
  "platforms": ["linkedin"],
  "default_text": "Connections-only update.",
  "visibility": "CONNECTIONS"
}

Reading posts (Apify refresh)

GET /unified/posts?platforms=linkedin returns cached posts by default.
ParameterBehavior
refresh_posts=false (default)Returns stored/cached posts — fast, no extra cost
refresh_posts=trueRe-fetches personal profile posts via Apify
Apify refresh is expensive. For LinkedIn personal profiles only, use refresh_posts=true when the user explicitly asks to sync live posts — not for routine listing. When refresh is enabled for personal LinkedIn, limit is capped at 2.
Organization posts (linkedin_organization_ids query param) are not subject to the personal Apify cap.

Video extras

FieldPurpose
linkedin.thumbnail_image_idCustom video thumbnail (workspace media ID)
linkedin.generate_thumbnail_from_contentAuto-generate thumbnail from post text

Common errors

ErrorCauseFix
NOT_CONNECTEDLinkedIn not linked to workspaceConnect via OAuth
422 text limitCaption over 3,000 charsTrim text
403 scopeAPI key lacks LinkedIn in scopeUse scoped or full key
See Postsiva errors.