We build custom applications 5x faster and cheaper 🚀
Book a Free Consultation
Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.
Direct answer: Build a LinkedIn integration as a standard OAuth 2.0 + REST connector: register a LinkedIn app to get client_id/secret and the right scopes (w_member_social for user posts, w_organization_social + rw_organization\_admin for organization posts), implement the OAuth Authorization Code flow to obtain access tokens, store tokens securely outside the agent (secrets/DB), implement backend endpoints (authorization callback, optional webhook receiver, token refresh/re-auth), and implement a ClawHub-installed OpenClaw skill that calls LinkedIn’s REST APIs (e.g., /v2/me, /v2/ugcPosts) with Bearer tokens. Keep stateful pieces (token storage, schedulers, webhook receivers) outside the agent runtime; configure the skill in ClawHub with secrets and environment variables so the skill code can call LinkedIn’s API authenticated. Debug by inspecting LinkedIn JSON responses, HTTP status codes and headers, token expiry/scopes, and your service logs.
w_member_social. For organization posting you will need w_organization_social and the account must have org admin privileges (and typically rw_organization_admin to manage org permissions). Add r\_liteprofile if you need the member urn.
https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=w_member_social%20r_liteprofile&state=RANDOM
code. Exchange this code for an access token by POSTing to LinkedIn’s token endpoint (server-side):
curl -X POST "https://www.linkedin.com/oauth/v2/accessToken" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=YOUR_REDIRECT_URI&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
curl -H "Authorization: Bearer ACCESS\_TOKEN" \ https://api.linkedin.com/v2/meThis returns JSON including the member URN (format:
urn:li:person:{id}).curl -X POST "https://api.linkedin.com/v2/ugcPosts" \\
-H "Authorization: Bearer ACCESS\_TOKEN" \\
-H "X-Restli-Protocol-Version: 2.0.0" \\
-H "Content-Type: application/json" \\
-d '{
"author":"urn:li:person:PERSON\_ID",
"lifecycleState":"PUBLISHED",
"specificContent":{
"com.linkedin.ugc.ShareContent":{
"shareCommentary":{"text":"Hello from OpenClaw integration"},
"shareMediaCategory":"NONE"
}
},
"visibility":{"com.linkedin.ugc.MemberNetworkVisibility":"CONNECTIONS"}
}'
"author":"urn:li:organization:ORG\_ID" and ensure you have the organization scopes and admin status.
w_member_social gives posting capability — don’t over-request read/write org scopes unless necessary.
https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=w_member_social%20r_liteprofile&state=RANDOM
curl -X POST "https://www.linkedin.com/oauth/v2/accessToken" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=YOUR_REDIRECT_URI&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
curl -H "Authorization: Bearer ACCESS\_TOKEN" \\ https://api.linkedin.com/v2/me
curl -X POST "https://api.linkedin.com/v2/ugcPosts" \\
-H "Authorization: Bearer ACCESS\_TOKEN" \\
-H "X-Restli-Protocol-Version: 2.0.0" \\
-H "Content-Type: application/json" \\
-d '{
"author":"urn:li:person:PERSON\_ID",
"lifecycleState":"PUBLISHED",
"specificContent":{
"com.linkedin.ugc.ShareContent":{
"shareCommentary":{"text":"Hello from an OpenClaw skill"},
"shareMediaCategory":"NONE"
}
},
"visibility":{"com.linkedin.ugc.MemberNetworkVisibility":"CONNECTIONS"}
}'
Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.
1
Short answer: A LinkedIn OAuth2 refresh fails because the refresh token, client credentials, endpoint, or scopes are wrong, the token was revoked/expired, or your code mis-parses the response — fix by verifying the exact error, confirming client_id/secret and token endpoint, securely persisting the refresh token, and retrying with correct parameters.
// Node.js fetch example
const res = await fetch(process.env.TOKEN_URL, {
method:'POST',
headers:{'Content-Type':'application/x-www-form-urlencoded'},
body:new URLSearchParams({
grant_type:'refresh_token',
client_id:process.env.CLIENT_ID,
client_secret:process.env.CLIENT_SECRET,
refresh_token:process.env.REFRESH_TOKEN
})
});
const body = await res.json(); // log body for errors
2
Direct answer: Request LinkedIn scopes you need (commonly r_liteprofile, r_emailaddress, and w_member_social for posting), register an exact redirect URI in the LinkedIn app that points to your OpenClaw agent callback (HTTPS, exact path and query), and put CLIENT_ID and CLIENT_SECRET in the OpenClaw Secret Store as environment variables referenced by your skill. Validate state and store refresh/access tokens outside the runtime.
// build auth URL inside skill (Node)
const url = `https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${process.env.LINKEDIN_CLIENT_ID}&redirect_uri=${encodeURIComponent(process.env.LINKEDIN_REDIRECT)}&scope=r_liteprofile%20r_emailaddress%20w_member_social&state=${state}`
// exchange code using CLIENT_SECRET from env
3
Direct answer: Incomplete LinkedIn company lists usually come from not iterating the API's pagination (start/count or cursor) or lacking required permissions; fix by reading the response's paging object and repeatedly requesting until no more elements, handling rate limits and auth.
4
Verify by computing an HMAC-SHA256 over the raw request body using your LinkedIn webhook secret (store it as an environment variable), then compare that digest to the signature header LinkedIn sends using a constant-time comparison; also validate any timestamp to prevent replay attacks.
Steps
// Node.js Express example; req.rawBody must contain raw bytes
const crypto = require('crypto');
const secret = process.env.LINKEDIN_WEBHOOK_SECRET;
function verify(req){
const sig = req.headers['x-li-signature']; // replace with exact header per docs
const h = crypto.createHmac('sha256', secret).update(req.rawBody).digest('base64');
return crypto.timingSafeEqual(Buffer.from(h), Buffer.from(sig));
}
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â