LinkedIn API & OAuth

LinkedIn unauthorized_scope_error: Why a Granted Product Is Not a Granted Scope

Your app shows the product as approved in the Developer Portal. You send the scope LinkedIn documents for it. The member never even reaches a consent screen — LinkedIn rejects the authorization request outright. This is almost never a bug in your OAuth client. It is LinkedIn telling you that the scope you asked for is not attached to your application.

What the error is actually saying

The failure happens at https://www.linkedin.com/oauth/v2/authorization, before any authorization code exists. LinkedIn’s own error table for that endpoint describes it plainly: an invalid scope means the permissions passed in the request are invalid, and the resolution is to ensure the permissions sent in the scope parameter are assigned to the developer application in the LinkedIn Developer Portal.

That single sentence carries the whole problem. LinkedIn is not validating your scope string against a global list of scopes that exist. It is validating it against the much shorter list of scopes your specific app has been granted. A scope can be perfectly real, fully documented, and used by thousands of other integrations, and still be rejected for you.

What developers assume

“The scope is in the documentation, so I can request it. If the member consents, I get access.”

What LinkedIn actually does

The scopes available to your app depend on which Products or Partner Programs your app has access to. The Auth tab shows the current scopes available. Anything outside that set fails before the member is ever asked.

Products grant scopes. Scopes are not requested directly.

This is the structural detail that trips up teams coming from Google or Meta. On LinkedIn you do not apply for a scope. You apply for a Product under the Products tab of your app, and if that Product is granted, the scopes bundled with it appear on your Auth tab. The scope string in your authorization URL is downstream of a decision LinkedIn already made about your application.

Which means there are two entirely different failure modes that produce the same symptom:

  • The Product was never added to the app — the scope was never in play.
  • The Product was added, but it is a Product that requires review, and it is still sitting in a requested-not-approved state that the portal displays ambiguously.

The full map of which Products exist, which need a verified Company Page, and which need business vetting is set out in our guide to LinkedIn API access, Products and the approval gates.

The self-service list is far shorter than most people expect

LinkedIn documents exactly one category available to all developers without special approval: Open Permissions. Everything else — Marketing, Sales, Talent, Learning — requires an approved application or partner status.

ProductPermissionWhat it grants
Sign in with LinkedIn using OpenID ConnectprofileMember Auth: the authenticated member’s name, headline and photo.
Sign in with LinkedIn using OpenID ConnectemailMember Auth: the authenticated member’s primary email address.
Share on LinkedInw_member_socialMember Auth: post, comment and like on behalf of an authenticated member.

If the scope in your failing request is not on that table and you have not been through an approval process, the error is not a mystery — it is the expected outcome. The Compliance permissions r_compliance and w_compliance are the sharpest example: LinkedIn still lists them in the documentation, marked closed, for reference only. They cannot be requested at all.

The deprecated-scope trap

A large share of these errors are not access problems — they are code that predates LinkedIn’s move to OpenID Connect. r_liteprofile and r_emailaddress were the standard sign-in pair for years. They are no longer what a new app is granted, and the replacement set is openid, profile and email.

The trap is that the old scope names still appear in an enormous volume of tutorials, Stack Overflow answers, and OAuth library defaults that were written before the change. An integration copied from any of them fails on the very first authorization request, and the error points at the scope rather than at the library. The migration itself, and the ID token validation that comes with it, is covered in Sign In with LinkedIn (OpenID Connect): setup, scopes, and why apps get stuck.

The consequence nobody plans for: changing scopes breaks existing users

Once you do get the right Product approved and correct your scope string, there is a second cost that is easy to miss. LinkedIn is explicit on two points. If the scope permissions change in your app, your users must re-authenticate so they have explicitly granted every permission being requested. And if you request a different scope than the previously granted scope, all the previous access tokens are invalidated.

For a live product with an existing user base, that is not a config change — it is a re-consent campaign. Every connected account has to walk back through the authorization flow, and any background job holding a token stops working the moment the new scope set goes out. Teams that discover this after shipping tend to discover it through support tickets. The wider token lifecycle picture, including why programmatic refresh is a partner privilege rather than a default, is in LinkedIn API access tokens expire in 60 days.

There is also no partial path out. LinkedIn states that when multiple scopes are requested, the member must consent to all of them and cannot select individual scopes. You cannot ship a broad scope list and let users trim it down — the request either succeeds whole or fails whole.

How this is actually diagnosed

  1. Separate the two questions

    “Does this scope exist?” and “Does my app have it?” are different questions with different answers. Almost every wasted debugging hour on this error comes from conflating them and rewriting working OAuth code.

  2. Read the Auth tab as the source of truth

    Not the documentation, not the Products tab, not a partner email. The scopes your app can actually send are the ones listed there, and any difference between that list and your authorization URL is the failure.

  3. Establish which Product carries the scope you need

    This is the step that determines whether you have a five-minute fix or a multi-week approval path, and it is where the architecture of the integration is really decided.

  4. Audit the scope string for legacy names

    Including the ones your OAuth library inserts by default without being asked. Framework-level LinkedIn providers have historically shipped the deprecated pair.

  5. Plan the re-consent before changing anything

    Because the token invalidation is not reversible and existing users will not fix themselves.

Where these projects go wrong

  • Treating an added-but-unapproved Product as granted access, then debugging the OAuth client for days.
  • Requesting a wide scope list “to be safe” — which makes the whole request fail if any single scope is unassigned, and pushes the app toward a heavier review than the use case needs.
  • Copying a scope string from a tutorial written before the OpenID Connect migration.
  • Building the product roadmap around a scope that belongs to a closed or partner-only programme, and only discovering the gate after the feature is sold.
  • Shipping a scope change to production without a re-consent plan, invalidating every existing token at once.
  • Assuming a rejected Product application can simply be re-submitted on the same app, when several LinkedIn programmes treat the decision as final for that application.
  • Confusing this authorization-stage error with a runtime 403, which is a different problem with a different cause.

Why the fix is usually an access strategy, not a code change

When the scope genuinely is unassigned, no amount of OAuth engineering will change the outcome. What changes it is the application you put in front of LinkedIn: which Product you request, whether your Company Page and app verification are in order, whether the use case you describe matches the permissions you are asking for, and whether the integration is scoped to what LinkedIn actually approves rather than what the product team hoped for. Getting that wrong is expensive on LinkedIn specifically, because several of its programmes do not offer a clean second attempt on the same developer application.

An honest note on outcomes. Whether LinkedIn grants a Product or admits an app to a partner programme is LinkedIn’s decision alone. Nothing here is promised or assured on your behalf. What preparation changes is the number of cycles — an application where the requested Product, the declared use case, the app verification and the scope list all describe the same integration tends to resolve in far fewer rounds than one assembled reactively after a rejection. Our work is technical implementation support, review preparation, and policy-aligned guidance.

Every mechanic above is taken from LinkedIn’s official developer documentation on Microsoft Learn — the Authorization Code Flow (3-legged OAuth) page and the Getting Access to LinkedIn APIs page — verified current in August 2026. LinkedIn changes Products, permissions and programme availability without notice; verify against the official pages before building around them.