KalovioArticles › For developers

What Is w_member_social, and How Do You Get It?

w_member_social is the LinkedIn OAuth permission that lets an app create and manage posts on behalf of the member who signed in. It comes from the “Share on LinkedIn” product, which is free and self-serve — you request it in the Developer portal, then list the scope in your authorisation URL. No partner approval is needed.

If you are building anything that publishes to LinkedIn, w_member_social is the one string you cannot avoid. It is a scope — the named permission an app asks for during OAuth, so the member can see exactly what they are agreeing to before they approve it. This page is the reference: what the scope covers, where it comes from, how to request it, and the two failures that catch almost everyone.

What does w_member_social actually let you do?

The name decodes cleanly once you know the pattern LinkedIn uses. The w_ prefix means write. member means the individual person who signed in, as opposed to a company page. social means social actions — posts and the things attached to them.

So w_member_social grants an app permission to create and manage posts on behalf of the signed-in member. In practice that covers publishing a text post, publishing a post with an image, sharing an article link with your own commentary, and deleting a post the app created.

Two limits are worth stating up front, because they surprise people who assume “social” means everything social:

  • It is a write permission, not a read permission. It does not let you pull down the member’s existing feed or their post history. That is a separate scope, and a closed one — more on that below.
  • It is member-scoped, not organisation-scoped. Posting as a company page is a different capability under a different, partner-gated product. w_member_social posts as the person.

It also grants no access at all to messages, connections, or account settings. LinkedIn enforces that boundary at its own end, so a token issued for this scope simply cannot reach those endpoints, regardless of what the app tries.

Which LinkedIn product gives you w_member_social?

Scopes are not requested individually. On LinkedIn you add a product to your app, and the product carries a set of scopes with it. For posting, the product is called Share on LinkedIn.

Share on LinkedIn is one of the self-serve products. That means:

  • It is free. There is no fee, no minimum spend, and no sales conversation.
  • It does not require Marketing Developer Platform partner status or any application review committee.
  • You add it yourself from your app’s Products tab, and it is normally available within a short time of requesting it.

Almost every real posting integration pairs it with a second self-serve product, Sign In with LinkedIn using OpenID Connect, which supplies the identity scopes openid, profile and email. You need identity because a post has to be attributed to a specific member URN (LinkedIn’s internal id format for a person, looking like urn:li:person:XXXX), and identity is where you get that id. The two products together are the standard free stack for a posting tool.

How do you request w_member_social in the Developer portal?

The sequence is short. Assuming you already have a LinkedIn developer app:

  • Associate a company page. LinkedIn requires every developer app to be linked to a LinkedIn Page, and you must be able to verify that link. This is the step that stalls people who have no page yet — create one first.
  • Open the Products tab on your app and request Share on LinkedIn. Request Sign In with LinkedIn using OpenID Connect at the same time if you need the member’s identity, which you almost certainly do.
  • Check the Auth tab. Once the product is granted, w_member_social appears in your app’s list of OAuth 2.0 scopes. If it is not listed there, the product has not been granted yet and nothing downstream will work.
  • Add your redirect URL on the same Auth tab. It must match, exactly and character for character, the redirect_uri you send in the authorisation request.

The scope list on the Auth tab is the source of truth. Before you debug a single line of code, look at it. If w_member_social is not on that list, your app cannot request it, and the authorisation URL will fail or silently drop the scope rather than granting it.

How do you add w_member_social to your OAuth authorisation URL?

LinkedIn uses the standard authorization code flow, sometimes called three-legged OAuth because three parties are involved: your app, the member, and LinkedIn. You send the member to LinkedIn’s authorisation page with your scopes listed, they approve, LinkedIn sends back a code, and you exchange that code for an access token.

The scope goes in the scope query parameter of the authorisation URL, alongside the identity scopes, URL-encoded and separated by spaces:

  • Authorisation endpoint: https://www.linkedin.com/oauth/v2/authorization
  • Parameters: response_type=code, your client_id, your redirect_uri, a random state value you generate and later verify, and scope=openid%20profile%20email%20w_member_social
  • Token endpoint: https://www.linkedin.com/oauth/v2/accessToken, where you exchange the returned code for the access token

The state parameter is not optional in practice. It is your defence against cross-site request forgery on the callback, and you should sign it or store it so you can confirm the callback you receive is the one you started.

Once you hold the token, posting happens at POST /v2/ugcPosts for text, single-image and article-share posts. LinkedIn’s newer versioned gateway, /rest/posts with a LinkedIn-Version header, handles multi-image and document posts. Both authenticate with the same bearer token.

Do not assume the versioned gateway is open to you. LinkedIn’s documentation says w_member_social is sufficient for multi-image and document posts, but that newer interface can still be product-gated for a self-serve app, and the symptom is a 403 rather than an explanation. Build the feature, handle the 403 with a readable message, and test it on your own real account before promising it to anyone.

Why does sign-in work but posting return an error?

This is the single most common failure, and it is confusing because the symptom points away from the cause. The member signed in successfully. You have their name, their email, their member URN. Everything looks connected. Then the first post attempt is rejected with a permissions error — typically an HTTP 403, meaning “authenticated, but not allowed” — rather than a sign-in error.

What happened is that the identity scopes were granted and w_member_social was not. That can occur for several reasons:

  • The Share on LinkedIn product had not been granted when the member consented, so LinkedIn dropped the scope from the request.
  • The member connected before you added the scope, and their token predates it. Existing tokens are not upgraded retroactively.
  • The member declined that specific permission on the consent screen.
  • The token has since expired. LinkedIn member tokens last around 60 days, and self-serve apps do not get a refresh token, so a working integration quietly stops working after two months.

How to detect it: the token response from LinkedIn includes a scope field listing what was actually granted. Read it and compare it against what you asked for, at the moment you store the token. Do not assume you got what you requested. Storing the granted scope list next to the token lets you answer “can this user post?” without making a failing API call to find out.

How to fix it: re-consent. Send the member back through the authorisation URL with the full scope list. There is no way to add a scope to an existing token; a new grant issues a new token. A well-built tool detects the missing scope and hands the user a one-click reconnect link instead of showing a raw API error. Kalovio does exactly this with its reconnect_linkedin tool, and the same pattern is worth copying in anything you build.

What is the difference between w_member_social and r_member_social?

This asymmetry catches developers who reason by symmetry: if w_ is write and it is free, surely r_ is read and it is also free. It is not.

 w_member_socialr_member_social
What it doesCreate and manage posts as the memberRead the member’s posts and social activity
AvailabilitySelf-serve, freeClosed permission
ProductShare on LinkedInNot offered self-serve
How you get itAdd the product in the portalYou generally cannot — it is not on the self-serve menu

The practical consequence is a genuine one-way street: an app built on self-serve LinkedIn access can write posts but cannot read them. It cannot analyse the member’s past posts to learn their writing style, cannot fetch engagement figures, and cannot show a feed. If a tool claims to read your full LinkedIn history, it is either a partner with elevated access or it is not using the API at all.

This is also why an honest posting tool tracks what it published itself. Kalovio can list and delete posts it created, and can learn a voice profile from posts made through Kalovio — but nothing from before you connected, because r_member_social is simply not available. Engagement analytics sit behind the Community Management API, which requires a registered legal company and app review.

Why do scopes come back comma-separated?

A small, real gotcha that will bite you if you parse strictly. The OAuth 2.0 specification says scope values are space-delimited, and that is how you send them in the authorisation URL. But LinkedIn responses do not always come back that way — in some responses the granted scopes arrive comma-separated, sometimes with a space after the comma.

If your code splits the returned scope string on a single space, it will read the whole list as one malformed scope, decide w_member_social was not granted, and send a perfectly healthy user through a pointless reconnect. Split on a character class that accepts both — any run of whitespace or commas — and filter out empty entries. It is two characters of regular expression and it removes an entire class of phantom bug.

Is posting through w_member_social within LinkedIn’s rules?

The honest position. LinkedIn’s API Terms of Use, section 3.1(26), restricts using the APIs “to automate posting on the LinkedIn Services”, and there is no written exception for member-approved posting. Anyone telling you a posting tool carries no risk whatsoever is overstating the position. The defensible framing is narrower: the permission is open and self-serve, the member grants it through LinkedIn’s own consent screen, the member approves the exact text of every post before it goes out, nothing is scraped, and access can be revoked from LinkedIn settings at any time. Judge that for your own use.

The distinction that matters is between a token granted through w_member_social and a copied session cookie driving a headless browser. The first is sanctioned, scoped, listed in the member’s settings, and revocable. The second is none of those things, and the tools that use it tend to carry account-restriction warnings in their own documentation.

The short version

Request the Share on LinkedIn product, confirm w_member_social appears on your app’s Auth tab, include it in the scope parameter alongside the identity scopes, read the granted scope list off the token response rather than assuming, parse that list on commas as well as spaces, and build a reconnect path for the day the 60-day token lapses. Do that and the write side of LinkedIn is genuinely straightforward. The read side, you do not get.

Questions people ask

Is w_member_social free, or do I need a paid LinkedIn partnership?

It is free. w_member_social comes from the Share on LinkedIn product, which is self-serve — you add it from your app's Products tab in the LinkedIn Developer portal with no fee and no partner review. The gate is having a verified LinkedIn Page associated with your app, not money.

Why does my LinkedIn post return a 403 when sign-in worked fine?

Almost always because the identity scopes were granted but w_member_social was not. Check the scope field on the token response to see what LinkedIn actually granted. Common causes: the Share on LinkedIn product was not yet approved when the user consented, the token predates you adding the scope, the user declined it, or the token has passed its roughly 60-day life. The fix is to send the user through the authorisation URL again.

Can I add w_member_social to a token I already have?

No. Scopes are fixed at the moment the token is issued. To gain a scope you must run the authorisation flow again and get a new token. There is no upgrade path for an existing grant, which is why any production integration needs a reconnect flow rather than just an error message.

What is the difference between w_member_social and r_member_social?

w_member_social writes posts as the member and is freely self-serve. r_member_social reads the member's posts and social activity, and is a closed permission that is not offered on the self-serve menu. So a self-serve app can publish to LinkedIn but cannot read the member's existing posts, engagement, or feed.

How long does a w_member_social access token last?

LinkedIn member access tokens last around 60 days. Self-serve apps are not issued a refresh token — that requires Marketing Developer Platform partner status — so when the token lapses the user has to sign in again. Plan for this: store the expiry, detect the failure cleanly, and give the user a reconnect link rather than a raw API error.

Can w_member_social post to a LinkedIn company page?

No. The scope is member-scoped, so it posts as the individual person who signed in. Posting as an organisation is a separate capability under LinkedIn's Community Management API, which is partner-gated and requires a registered legal company plus app review.

Sources

Try Kalovio free

Run your LinkedIn from a chat with Claude or ChatGPT. Add this as a custom connector — free while in beta, and you approve every post before it goes live.

https://kalovio.com/mcpHow to connect

Read next