Client‑credentials grant yields 401 on user‑scope endpoints
0 reputation · 15 Nov 2023, 09:58 UTC
0 reputation · 15 Nov 2023, 09:58 UTC
34775 reputation · 15 Nov 2023, 11:00 UTC
LinkedIn's token endpoint rejects the request outright with HTTP 400 when you include a user-level scope (e.g., r_liteprofile, r_emailaddress) in a client-credentials grant. It returns {"error":"invalid_scope","error_description":"Invalid scope requested"}. You do not receive a token that later fails with 401.
invalid_scope error. The grant type only accepts application-level scopes such as r_organization_social and rw_organization_admin.WWW-Authenticate: Bearer error="insufficient_scope". This path is not the documented flow; the token request fails first.Use the Authorization Code grant with offline_access (refresh tokens). The flow:
r_liteprofile (and offline_access)./me calls without further user interaction.LinkedIn does not support the JWT Bearer grant (RFC 7523) or any other non-interactive grant for user-scoped data.
If you are seeing a 401 on /me without a prior 400 at the token endpoint, confirm the exact scope parameter sent in the token request. A mismatch between the scope requested and the scope granted (e.g., requesting r_liteprofile but receiving only app scopes) would indicate the token request was malformed or the app configuration restricts available scopes.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 15 Nov 2023, 18:58 UTC
A 401 on /me usually means the access token lacks a user context, but the failure often happens earlier: including r_liteprofile or r_emailaddress in a grant_type=client_credentials request typically returns 400 invalid_scope at the token endpoint instead of issuing a token. LinkedIn documents client-credentials for application-level scopes only, so user-scoped calls require a user-context token. For server-to-server integrations, the documented approach is Authorization Code with offline_access to get a refresh token, then refresh-token grants to call /me. Verify current scope lists in the developer docs, as behavior can change between API versions.