AI Workflow

LinkedIn API Permission Check and Posting Workflow Design

A record of checking LinkedIn API limits and shifting from automated reading to a user-approved posting workflow.

May 18, 2026

Goal

Before writing a new LinkedIn post, I wanted to read my previous posts through the API and match their tone. I assumed LinkedIn would work like GitHub: create an OAuth app, sign in, call an API, and read my own content.

The actual goal was simple: create a LinkedIn Developer app, authenticate my own account, fetch recent posts, analyze sentence length, bilingual phrasing, hashtag style, and then draft a new post in the same tone.

Because I already had a local MCP server called linkedin-posting-mcp, I tried to add a post-reading tool there instead of building a separate one-off script.

What I Implemented

  • `linkedin_get_my_posts` MCP tool.
  • `auth:url:signin` for a minimal `openid profile email` login test.
  • `auth:url` for `openid profile email w_member_social` posting-permission testing.
  • `auth:url:read` for testing whether `r_member_social` could enable existing-post reads.
  • `posts:me` for trying LinkedIn Posts API author finder calls against the authenticated member.
  • The intended API shape was `GET /rest/posts?author=urn:li:person:{member_id}&q=author`.

Setup Details That Caused Confusion

  • A LinkedIn Developer app requires a connected LinkedIn Page, so I created a personal technical-notes page named Yongtak Engineering Notes.
  • The first page-creation path led to a Showcase Page under `linkedin.com/showcase/`, which was wrong for this purpose because it expects a parent organization page.
  • The correct path was a normal Company Page under `linkedin.com/company/`, used only as the app owner page.
  • LinkedIn Developer app names cannot contain the word LinkedIn, so the app name had to change from Yongtak LinkedIn Workflow to something like Yongtak AI Workflow.
  • The app requires a valid logo. I prepared a separate 300x300 PNG because the logo appears in the OAuth consent screen even though it is not technically important to the API test.

PowerShell and OAuth Pitfalls

  • During testing, I avoided saving secrets in user environment variables and instead used the current PowerShell session with `Read-Host`.
  • The redirect URI was registered as `http://localhost:3000/callback`.
  • When no local callback server was listening, LinkedIn showed a confusing browser error after redirect. That did not necessarily mean OAuth had failed.
  • A tiny Node HTTP server was enough to capture the callback URL and print the authorization code.
  • For token exchange, only the value of `code` should be passed. Copying `code=` or the trailing `&state=...` causes token exchange failure.
  • If a Client Secret, authorization code, or access token appears in chat or logs, rotate it immediately in the LinkedIn Developer console.

Errors and Interpretation

  • `Missing LinkedIn config` meant the current PowerShell session did not contain the expected environment variables.
  • `Missing ) in method call` or `Unexpected token User` came from broken PowerShell `SetEnvironmentVariable()` syntax, usually a missing comma or quote issue.
  • `Bummer, something went wrong` usually meant the browser had been redirected to localhost without a server listening on the callback port.
  • `authorization code not found` meant the code was copied incorrectly, reused, or expired.
  • `ACCESS_DENIED: Not enough permissions to access: partnerApiPostsExternal.FINDER-author` meant OAuth login and token issuance worked, but the app did not have Posts Finder read permission.
  • `Please upload a valid app logo` meant the Developer app logo did not meet LinkedIn requirements.

Blocked Point

The main blocker was not JavaScript syntax, the localhost redirect, or token exchange. The blocker was API permission.

The app could authenticate and issue tokens, but `posts:me` returned `ACCESS_DENIED` for the Posts API author finder. Adding `r_member_social` to the requested scope did not change the result.

The official LinkedIn Marketing API FAQ describes `r_member_social` as a closed permission, and resource constraints currently limit access requests. That means a personal developer app should not expect to read existing member posts immediately.

Conclusion and Rule

  • OIDC login is possible.
  • Token issuance is possible.
  • A posting workflow can be built within approved scopes.
  • Reading existing personal posts is not available by default without restricted permission approval.
  • Do not use browser cookies, private APIs, scraping, or DM automation.
  • Use only official OAuth and documented APIs.
  • If existing-post tone matching is needed, ask the user for two or three sample posts and generate the draft from those samples.
  • Never leave Client Secret, authorization code, or access token in chat, repository files, or logs.
  • The core lesson: an API existing is different from the current app having permission to use the specific API operation.