# LinkedIn API Integration: Post for Your Users

Build a LinkedIn API integration into your product: Community Management API access, OAuth, Pages vs profiles, versioned headers, tokens, and posting.

Canonical page: https://www.tryadeli.com/blog/linkedin-api-integration
Last updated: 2026-10-29

By Nick Reyes, Co-founder and CTO, Adeli. Published 2026-10-29.

## The short answer

A LinkedIn API integration that posts for your users runs on LinkedIn's Community Management API. You get the product approved, connect each user with OAuth, find the Pages they administer, then publish through the Posts API with a LinkedIn-Version header. Tokens last 60 days. Adeli already holds Community Management API access, so your users connect LinkedIn through one social media API instead.

**A LinkedIn API integration that publishes for your users runs on LinkedIn's Community Management API**: get the product approved for your app, connect each user through OAuth, find the Pages they administer, and create posts through the Posts API with a versioned header. The request itself is short. Most integrations stall on access, token lifetimes, and monthly API versions.

This guide is for teams building a product where each customer connects their own LinkedIn account. For paid campaigns, see the [LinkedIn Ads API guide](https://www.tryadeli.com/blog/linkedin-ads-api).

## Does LinkedIn have an API?

**Yes. LinkedIn has several APIs, and the one for posting is the Community Management API.** It covers the Posts API, the Images API, Page lookups, and Page and member analytics. Other LinkedIn programs (Advertising, Lead Sync, Sign In with LinkedIn) are separate products with separate access.

| What your product does | LinkedIn product | Key scopes |
| --- | --- | --- |
| **Posts as a company Page** | Community Management API | `w_organization_social`, `rw_organization_admin` |
| **Posts as a member's personal profile** | Community Management API | `w_member_social` |
| **Reads Page analytics** | Community Management API | `rw_organization_admin`, `r_organization_social` |
| **Runs ad campaigns** | Advertising API | `rw_ads`, `r_ads_reporting` |

LinkedIn requires the [Community Management API](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/community-management-overview) to be the only product on its developer app, so a product that also needs ads or sign-in runs more than one LinkedIn app.

## How do you get LinkedIn API access?

**You get LinkedIn API access by requesting the Community Management API on a developer app tied to a verified LinkedIn Page.** LinkedIn [vets the request](https://learn.microsoft.com/en-us/linkedin/marketing/community-management-app-review) for a registered legal organization, a commercial use case, a verified business email, and a website on the organization's domain.

Approval starts you on **Development tier**, which LinkedIn's [access tiers page](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/marketing-tiers) limits for testing:

| | Development tier | Standard tier |
| --- | --- | --- |
| **Daily calls** | 500 per app, 100 per member | No such caps |
| **`BATCH_GET`** | Blocked | Available |
| **Social action webhooks** | Off | Available |
| **How to get it** | Default after vetting | A separate application with a screen recording |

The Standard tier application needs an approved use case, a privacy policy, and a recording of your product: the full OAuth flow, posting, and how you display engagement. **LinkedIn doesn't let you re-apply with the same app if Standard tier is rejected.** You'd start over with a new app on Development tier, so get the recording right the first time.

## What do you need before you start?

- **A LinkedIn developer app** with the Community Management API approved.
- **A LinkedIn Page** verified for the app, belonging to your company.
- **An HTTPS redirect URI** registered on the app's Auth tab.
- **The current API version** in `YYYYMM` form, from LinkedIn's [versioning page](https://learn.microsoft.com/en-us/linkedin/marketing/versioning).
- **A test member** who administers a test Page, so you can try both posting targets.

## Step 1: Connect each user with OAuth

**Each of your users signs in to LinkedIn and grants your app the posting scopes; your server exchanges the code for their token.** Send them to LinkedIn's authorization page:

```text
https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=<CLIENT_ID>&redirect_uri=<REDIRECT_URI>&state=<STATE>&scope=w_organization_social%20rw_organization_admin%20w_member_social
```

Check `state` on the callback, then exchange the code from your server, as LinkedIn's [authorization code flow](https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow) describes:

```bash
curl -X POST https://www.linkedin.com/oauth/v2/accessToken \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d grant_type=authorization_code \
  -d code=<CODE> \
  -d client_id=<CLIENT_ID> \
  -d client_secret=<CLIENT_SECRET> \
  -d redirect_uri=<REDIRECT_URI>
```

Store the token encrypted, against your user, with its expiry.

## Step 2: Pick the posting target: a Page or a personal profile

**A LinkedIn post has one author: either a member (`urn:li:person:…`) or an organization (`urn:li:organization:…`).** To find the Pages a member can post for, list their role assignments:

```bash
curl "https://api.linkedin.com/rest/organizationAcls?q=roleAssignee&state=APPROVED" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Linkedin-Version: 202610" \
  -H "X-Restli-Protocol-Version: 2.0.0"
```

Keep the Pages where the member's role is `ADMINISTRATOR`, `CONTENT_ADMIN`, or `DIRECT_SPONSORED_CONTENT_POSTER`. Then let your user choose. A member with no eligible Page can still post as themselves with `w_member_social`.

Save the chosen author URN with the connection. On Development tier, each Page is a separate lookup because `BATCH_GET` is blocked, so cache the result instead of calling on every page load.

## Step 3: Publish through the Posts API

**Create a post with `POST /rest/posts`, the author URN, and the `Linkedin-Version` header.** This text post follows LinkedIn's [Posts API reference](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api):

```bash
curl -X POST https://api.linkedin.com/rest/posts \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Linkedin-Version: 202610" \
  -H "X-Restli-Protocol-Version: 2.0.0" \
  -H "Content-Type: application/json" \
  -d '{
    "author": "urn:li:organization:<ORG_ID>",
    "commentary": "We just shipped a faster publishing workflow.",
    "visibility": "PUBLIC",
    "distribution": {
      "feedDistribution": "MAIN_FEED",
      "targetEntities": [],
      "thirdPartyDistributionChannels": []
    },
    "lifecycleState": "PUBLISHED",
    "isReshareDisabledByAuthor": false
  }'
```

A success is **HTTP `201`** with the new post's URN in the `x-restli-id` response header. For an image, first call `POST /rest/images?action=initializeUpload` with the author as `owner`, upload the bytes to the returned `uploadUrl`, then add the image URN to the post under `content.media.id`.

Two rules for post creation:

- **Don't use `/v2/ugcPosts`.** The Posts API replaced it.
- **Don't blindly retry post creation.** If the response is ambiguous, a retry can publish the same post twice.

## Step 4: Handle tokens and versions over time

**LinkedIn access tokens last 60 days, and API versions are supported for about a year, so a LinkedIn API integration needs ongoing upkeep.**

- **Tokens.** LinkedIn's [refresh token docs](https://learn.microsoft.com/en-us/linkedin/shared/authentication/programmatic-refresh-tokens) say programmatic refresh tokens go to approved partners only. They last a year, and refreshing doesn't extend that year. Without one, prompt the member to reconnect before day 60.
- **Versions.** Each `Linkedin-Version` is supported for roughly 12 months. A sunset version returns **HTTP `426`**, so pin a version, track LinkedIn's [recent changes](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/recent-changes), and move forward before the sunset date.
- **Rate limits.** A `429` means you've hit a daily limit. On Development tier that can come from any of your customers, because the 500-call budget is shared across the app.

## Is the LinkedIn API free?

**LinkedIn doesn't charge for the Community Management API, but the integration costs approval time and maintenance.**

| Cost | Who carries it when you go direct |
| --- | --- |
| **Vetting and the Standard tier application** | Your team, with a screen recording and no second try on the same app |
| **Token expiry every 60 days** | Your team and your users, unless you're an approved partner |
| **Monthly API versions** | Your team, migrating before each sunset |
| **Separate apps for ads and sign-in** | Your team, one approval each |
| **Debugging failed posts** | Your team, from LinkedIn's error responses |

## Is there a faster way to build a LinkedIn API integration?

**Adeli is a unified social media API that already holds LinkedIn Community Management API access**, so your product doesn't need its own LinkedIn application. Your users connect a personal profile or a Page they administer, and you publish with the same API key you use for every other network.

Start a connection for one of your users. Members who administer a Page pick the profile or Page on an Adeli-hosted chooser:

```bash
curl -X POST https://app.tryadeli.com/api/v1/profiles/<PROFILE_ID>/connect \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "platform": "linkedin", "redirectUrl": "https://yourapp.example/callback" }'
```

Then publish:

```bash
curl -X POST https://app.tryadeli.com/api/v1/posts \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "linkedin",
    "accountId": "<ACCOUNT_ID>",
    "commentary": "We just shipped a faster publishing workflow."
  }'
```

What Adeli handles for you:

- **API access.** Adeli holds the Community Management API approval and pins a verified LinkedIn API version, so LinkedIn's version changes are Adeli's work.
- **Targets.** Adeli finds the Pages a member can post for and lets them choose a Page or their personal profile.
- **Text and image posts.** Adeli checks the image's real format and size, runs LinkedIn's upload flow, and never retries a post in a way that could duplicate it.
- **Tokens.** Adeli stores each grant encrypted, rotates refresh tokens when LinkedIn issues them, and flags the account for reconnect when it can't.
- **Analytics.** Followers, impressions, reactions, comments, and shares for Pages and personal profiles, through the [analytics API](https://www.tryadeli.com/social-media-analytics-api).
- **Clear errors.** Every publish returns a per-platform status, and Adeli logs every call it makes to LinkedIn, with the status, latency, and LinkedIn's error code. When a post fails, a person at hello@tryadeli.com can tell you why.

The same key publishes to Instagram, Facebook, TikTok, YouTube, X, and Bluesky through [Adeli's posting API](https://www.tryadeli.com/social-media-posting-api). The [LinkedIn publish docs](https://www.tryadeli.com/docs/api/posts/publish-linkedin) list every field.

## Frequently asked questions

### Does LinkedIn have an API for posting?

Yes. LinkedIn's Posts API, part of the Community Management API, creates posts on LinkedIn Pages and on members' personal profiles. Your app needs the w_organization_social scope to post as a Page and w_member_social to post as a member, both granted by the member through OAuth.

### Is the LinkedIn API free?

LinkedIn doesn't charge a fee for the Community Management API. Access is the gate instead: LinkedIn vets your app for Development tier, and production volume needs a separate Standard tier application with a screen recording of your product.

### Can I post to a LinkedIn company page with the API?

Yes. A LinkedIn member who is an administrator or content admin of a Page can authorize your app with w_organization_social, and your app posts with the Page's organization URN as the author. Use the organizationAcls endpoint to find which Pages the member can post for.

### How long does a LinkedIn access token last?

A LinkedIn access token lasts 60 days by default. Programmatic refresh tokens, which last a year, are only issued to approved partners. Without one, the member has to authorize your app again when the access token expires.

## Related Adeli pages

- [Social Media Posting & Scheduling API](https://www.tryadeli.com/social-media-posting-api.md): Adeli's social media posting and scheduling API publishes to Instagram, TikTok, YouTube, Facebook, X, and Bluesky in one request, now or at a set time. Free to start.
- [Social Media Analytics API](https://www.tryadeli.com/social-media-analytics-api.md): Adeli's analytics API: Instagram, TikTok, Facebook Page, and YouTube insights endpoints, plus per-post engagement on every post an account has made.
- [Social Media API for Vertical SaaS Platforms](https://www.tryadeli.com/use-cases/vertical-saas.md): Give your small-business customers posting, scheduling, analytics, inbox, and Meta ads inside your vertical SaaS, through one API.
- [All posts on the Adeli blog](https://www.tryadeli.com/blog.md)

## About the author

Nick Reyes is the CTO behind Adeli and builds its API, its platform integrations, and the docs. He is a product engineer with 10 years of experience at Phantom, Airbnb, and Google.
