Errors & blockers

LinkedIn API 403 error: what it means

The most common causes of a 403 from the LinkedIn API, and how to tell a permissions problem from a rate-limit problem.

Quick answer

A LinkedIn API 403 means LinkedIn recognizes your token but has decided it is not allowed to do what you asked — unlike a 401, where the token itself is invalid or expired. It originates at one of three layers: the app lacks the required product (such as Share on LinkedIn), the token was issued without the required scope, or the member lacks the needed role on the target.

A 403 from the LinkedIn API means something different from a 401. Per LinkedIn's own error-handling documentation, a 401 says the token itself is invalid, empty, or expired — LinkedIn does not know who you are. A 403 says LinkedIn knows exactly who you are and has decided the token is not allowed to do what you just asked. That distinction changes the fix: a 401 usually means reconnect, a 403 usually means the request needs different permissions, a different app configuration, or a different member entirely.

PostGate handles OAuth, publishing and delivery evidence for every network through one API. Start free or read the docs.

01

Three layers where a 403 can originate

A 403 on the LinkedIn API generally comes from one of three places, and the fix is different at each:

  • Application layer — your app's Developer Portal configuration doesn't have access to the product the endpoint requires. Posting endpoints need the "Share on LinkedIn" product added to the app; without it, every request to those endpoints returns 403 regardless of the token.
  • Scope layer — the access token itself was issued without the scope the endpoint requires. This happens when the OAuth request that produced the token omitted a scope, or when the app configuration changed after the token was already issued and the member has not reconnected since.
  • Entity layer — the token and scopes are fine, but the specific member or Page the request targets doesn't have the role the action needs. Posting to a Company Page as a member without admin access on that Page is the most common version of this.
02

What order should you check them in?

Start at the application layer: confirm the Developer Portal shows the relevant product ("Share on LinkedIn" for member posting, the Community Management API for Company Page posting) as active on the app, not just requested. Then check the scope layer — decode the access token or check what scopes the original OAuth request actually included; a token minted before a scope was added to the app's request doesn't retroactively gain it. Only after both of those are confirmed correct does an entity-layer role problem become the likely cause.

03

What looks like a scope problem but isn’t?

Calling a deprecated endpoint — /v2/me instead of the current /v2/userinfo, or requesting an old scope name like r_basicprofile instead of its replacement — can also return 403, even with an otherwise correctly scoped token. This is worth ruling out separately from a genuine permission gap: check the endpoint and scope names against LinkedIn's current docs before assuming the app configuration is wrong.

04

How do you tell a 403 from a 429 in practice?

They're easy to conflate when you're only logging the status code. A 403 is deterministic — the identical request will fail again immediately, because the underlying cause is a permission gap, not volume. A 429 is transient — the identical request will typically succeed after LinkedIn's daily throttle window resets. If retrying the exact same request later succeeds without any change to scopes, app config, or the connected member, what you actually hit was a 429, not a 403. See LinkedIn API rate limits for how that throttle model works.

05

How does PostGate surface this?

PostGate maps a LinkedIn 403 to a structured, non-retryable error on the target rather than a generic failure, and distinguishes it from the retryable rate_limited state a 429 produces — see Errors & retries. Because PostGate requests openid profile w_member_social together on connect, the scope-layer cause above is already ruled out for personal-profile posting through PostGate; Company Page posting still needs the separate Community Management API tier described in LinkedIn Community Management API access.

Frequently asked questions

Why do I get a 403 when posting to a LinkedIn Company Page?

The most common cause is an entity-layer role problem: the token and scopes are fine, but the member the token belongs to does not have admin access on that specific Page. Company Page posting also requires the Community Management API product tier on the app, which is separate from the Share on LinkedIn product used for personal-profile posting.

Can calling a deprecated LinkedIn endpoint cause a 403?

Yes. Calling a deprecated endpoint — /v2/me instead of the current /v2/userinfo — or requesting an old scope name like r_basicprofile instead of its replacement can return 403 even with an otherwise correctly scoped token. Rule this out by checking endpoint and scope names against LinkedIn's current docs before assuming the app configuration or permissions are wrong.

How do I tell a LinkedIn 403 from a 429?

A 403 is deterministic: the identical request fails again immediately, because the cause is a permission gap, not volume. A 429 is transient: the identical request typically succeeds after LinkedIn's daily throttle window resets. If retrying the exact same request later succeeds without any change to scopes, app config, or the connected member, what you actually hit was a 429.

Does my LinkedIn token gain new scopes when I update the app configuration?

No. A token minted before a scope was added to the app's OAuth request does not retroactively gain that scope. If the app configuration changed after the token was issued, the member has to reconnect so a new token is issued with the updated scope set. Decode the token or check the original OAuth request to see what it actually includes.

Build it with PostGate

One API for every social platform your customers care about — sandboxed, documented, and ready today.

Start building Read the docs