Get your dream built 10x faster

How to integrate LinkedIn with OpenClaw

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

How to integrate LinkedIn with OpenClaw

 

Direct answer

 

Integrate LinkedIn with OpenClaw by implementing a standard OAuth 2.0 flow for user or organization authentication, storing tokens securely outside the agent runtime, implementing the LinkedIn REST calls (e.g., GET /v2/me, POST /v2/ugcPosts) inside a ClawHub-installed skill, and keeping any long-running or stateful components (token refresh, scheduled posting, webhook receivers) in external services that the skill calls or that call the skill via a well-authenticated API. Ensure you request the exact LinkedIn scopes you need (profile, email, w_member_social, w_organization_social), verify redirect URIs, validate and log HTTP responses, and design the skill so it only runs short-lived API calls — persist credentials and schedules in an external secrets store and database.

 

Overview — what must be explicit and where things run

 
  • OAuth and credentials — Register a LinkedIn app in LinkedIn Developer Portal. Configure a redirect URI and capture Client ID and Client Secret there. Provide that redirect URI to your skill configuration (via ClawHub or your secret manager) so OAuth exchanges can complete.
  • Where code runs — The OpenClaw skill (installed/configured through ClawHub) makes API calls at runtime (e.g., fetch profile, post content). Any long-lived services (webhooks, schedulers, databases, refresh token processors) must live outside the agent runtime (self-hosted or managed) and call the skill or the OpenClaw runtime if you need the agent to act on a schedule or webhook.
  • Secrets and tokens — Store client_id, client_secret and access/refresh tokens in a secrets store (ClawHub secrets if available, or a secure external vault). Never hard-code secrets into skill source code.
  • Permissions and scopes — Request only the LinkedIn scopes required (for example: r_liteprofile, r_emailaddress, w_member_social, w_organization_social). Posting as an organization requires additional admin rights on that LinkedIn organization.
  • Debugging approach — If something fails: check skill invocation logs, inspect HTTP status codes and error bodies from LinkedIn, confirm redirect URI and OAuth parameters, validate token scopes and expiration, and verify that the author URN (person or organization) has posting privileges.

 

Step-by-step integration plan (practical)

 
  • Create and configure a LinkedIn app
    • Use LinkedIn Developer Portal to register an application and set a redirect URI that your OAuth flow will use.
    • Record the Client ID and Client Secret. These go into your secret store.
  • Decide which OAuth flow you need
    • For interactive user auth, use the Authorization Code flow so you can act on behalf of a user (GET authorization URL → user consent → exchange code for token).
    • If you need organization posting, confirm the authenticated user is an admin of the organization and request w_organization_social.
  • Wire the OAuth flow to your skill
    • Expose an OAuth callback endpoint in an external web service (the skill runtime is not the place for public callback endpoints unless ClawHub explicitly provides managed callbacks).
    • After the user completes consent, your external callback exchanges the code for an access token and stores tokens securely (DB + secrets store).
    • The skill uses stored tokens when invoked to call LinkedIn APIs.
  • Implement API calls inside the skill
    • At runtime the skill performs short-lived HTTP requests to the LinkedIn API (GET /v2/me to find the author URN; POST /v2/ugcPosts to create posts).
    • Include required headers: Authorization: Bearer <access\_token> and X-Restli-Protocol-Version: 2.0.0 (for some POST endpoints).
  • Design for persistence and scheduling
    • Store tokens, refresh tokens (if LinkedIn provides them), and posting schedules in an external DB.
    • Use an external scheduler (cron, cloud scheduler, or job queue) to trigger posts; when triggered, the scheduler calls your service which then invokes the OpenClaw skill or directly calls LinkedIn if appropriate.
  • Logging, validation, and monitoring
    • Log full HTTP responses (status codes, JSON error objects) for failures, but never log client\_secret or tokens in plaintext.
    • Track token expiry and handle token refresh or reauthorization flows externally.

 

Concrete REST examples (working) — authorization, profile, post

 
  • Step 1 — Direct user to LinkedIn authorization URL
    https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=r_liteprofile%20r_emailaddress%20w_member\_social
  • Step 2 — Exchange authorization code for access token (curl)
    curl -X POST https://www.linkedin.com/oauth/v2/accessToken \\
    -d grant_type=authorization_code \\
    -d code=AUTHORIZATION\_CODE \\
    -d redirect_uri=YOUR_REDIRECT\_URI \\
    -d client_id=YOUR_CLIENT\_ID \\
    -d client_secret=YOUR_CLIENT\_SECRET
  • Step 3 — Get authenticated member URN
    curl -H "Authorization: Bearer ACCESS\_TOKEN" \\
    "https://api.linkedin.com/v2/me"
    • The response contains the member id; form the author URN as urn:li:person:<id>.
  • Step 4 — Create a simple text post using ugcPosts
    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-integrated skill"
          },
          "shareMediaCategory": "NONE"
        }
      },
      "visibility": {
        "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
      }
    }'
    • For organization posts, use an organization author URN like urn:li:organization:ORG\_ID and ensure the authenticated user has admin permissions plus the appropriate scope.

 

Example Node fetch code snippets

 
  • Exchange code for token (server-side)
    const fetch = require('node-fetch');
    const params = new URLSearchParams();
    params.append('grant_type', 'authorization_code');
    params.append('code', code); // code from redirect
    params.append('redirect_uri', REDIRECT_URI);
    params.append('client_id', CLIENT_ID);
    params.append('client_secret', CLIENT_SECRET);
    
    

    const res = await fetch('https://www.linkedin.com/oauth/v2/accessToken', {
    method: 'POST',
    body: params
    });
    const tokenBody = await res.json(); // contains access_token and expires_in

  • Post a share
    const postRes = await fetch('https://api.linkedin.com/v2/ugcPosts', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${ACCESS_TOKEN}`,
        'X-Restli-Protocol-Version': '2.0.0',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        author: `urn:li:person:${PERSON_ID}`,
        lifecycleState: 'PUBLISHED',
        specificContent: {
          'com.linkedin.ugc.ShareContent': {
            shareCommentary: { text: 'Posting via OpenClaw skill' },
            shareMediaCategory: 'NONE'
          }
        },
        visibility: { 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' }
      })
    });
    const postBody = await postRes.json(); // inspect for success or error

 

Design notes and best practices specific to OpenClaw constraints

 
  • Keep skill logic short and stateless — Make the skill perform only the API call and return results. Persist tokens and schedules externally.
  • Externalize OAuth callbacks — Provide a real HTTPS callback endpoint that completes the OAuth exchange and stores tokens. The skill should not be the primary host for public web callbacks unless your deployment explicitly supports it.
  • Token lifecycle — Treat tokens as first-class secrets: track expiry, refresh or reauthorize externally, and update the stored token so the next skill invocation uses a valid token.
  • Permissions and admin flow — For organization posting require an admin to authorize the app. Validate membership and required admin role before attempting org posts.
  • Logging and retry strategy — Log full API responses (without secrets). Implement idempotency or retries for transient 5xx errors; handle 4xx errors by surfacing the correct user action (re-auth, missing scope, revoked app).
  • Security — Validate redirect URIs, use HTTPS everywhere, rotate secrets, and do not echo client\_secret or refresh tokens to logs.

 

Common failure modes and how to debug

 
  • Invalid redirect\_uri or mismatch — LinkedIn will return an error during the authorization code exchange. Confirm redirect URI exactly matches what LinkedIn has registered and what you used when initiating auth.
  • Missing scope or insufficient permissions — LinkedIn returns 403 or specific error messages. Re-check requested scopes and the app settings and whether the user granted those scopes.
  • Expired token — Inspect expires\_in from token response. If LinkedIn provides refresh tokens, handle refresh externally; otherwise prompt user to re-authenticate.
  • Author URN not allowed to post — If posting as an organization, ensure the authenticated user is an admin of that organization and that you are using the correct organization URN.
  • Skill not invoked or no outbound network — Confirm the skill was called (ClawHub logs) and that the environment allows outbound HTTPS to api.linkedin.com.
  • API rate limits — Check headers or LinkedIn error response indicating rate limits; implement backoff and monitoring.

Book Your Free 30‑Minute Migration Call

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.

Book a Free Consultation

Troubleshooting LinkedIn and OpenClaw Integration

1

invalid_redirect_uri - LinkedIn OAuth error

Direct answer: The LinkedIn invalid_redirect_uri means the redirect_uri parameter in your OAuth request does not exactly match a Redirect URL registered in your LinkedIn app. Fix by making the URL identical (scheme, host, path, port, trailing slash and percent‑encoding) in both your app settings and the value your OpenClaw skill/agent sends; ensure the skill's env var or ClawHub OAuth redirect setting is correct.

 

Quick checks

 
  • Exact match between registered Redirect URL and request.
  • Use the same http vs https, port, path, trailing slash.
  • Confirm env var used by the skill (REDIRECT_URI) is correct in runtime.
  • Verify URL encoding and any proxy (ingress) rewriting.

 

Express example

  ```js // Exchange code for token app.get('/auth/linkedin/callback', async (req,res) => { const {code,state} = req.query; // Validate state matches stored value const params = new URLSearchParams({ grant_type: 'authorization_code', code, redirect_uri: process.env.LINKEDIN_REDIRECT_URI, client_id: process.env.LINKEDIN_CLIENT_ID, client_secret: process.env.LINKEDIN_CLIENT_SECRET }); const r = await fetch('https://www.linkedin.com/oauth/v2/accessToken', {method:'POST', body: params}); const json = await r.json(); res.json(json); }); ```

2

LinkedIn Webhook verification failing - OpenClaw

 

Troubleshoot LinkedIn webhook verification failing (OpenClaw)

 

Short answer: most failures are connectivity, signature mismatch, or missing app secret in the agent/skill environment. Ensure your webhook URL is publicly reachable (HTTPS), Log raw headers/body, verify LinkedIn’s signature (HMAC-SHA256 using your app secret) before accepting, and configure the same secret as an env var in ClawHub/OpenClaw so the skill can validate requests.

  • Checks: public HTTPS endpoint (ngrok for dev), correct app secret in OpenClaw env, inspect raw request headers (X-LI-Signature), compare HMAC-SHA256(body, secret), return 200 quickly.
  • Debug tips: log raw body, header; use replay curl; watch OpenClaw runtime logs and skill permissions.
// Node/Express example: verify X-LI-Signature
const crypto = require('crypto');
app.post('/webhook', express.raw({type:'application/json'}), (req,res)=>{
  // compute HMAC-SHA256
  const sig = 'sha256=' + crypto.createHmac('sha256', process.env.LINKEDIN_SECRET).update(req.body).digest('hex');
  if (crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.headers['x-li-signature']||''))) {
    // valid
    res.sendStatus(200);
  } else {
    res.sendStatus(401);
  }
});

3

LinkedIn API 429 handling - OpenClaw Sync Jobs

Handle LinkedIn 429s by: honor Retry-After, apply exponential backoff with jitter, record per-credential rate state outside the OpenClaw runtime (Redis or DB), use a circuit-breaker to pause sync jobs and reschedule via your external queue, and make syncs idempotent and incremental so retries are safe.

 

Practical steps

 
  • Respect Retry-After and headers; if missing, use exponential backoff + jitter.
  • Store cooldown (e.g., Redis TTL) per token/org so other agents honor limits.
  • Circuit-breaker to stop noisy jobs and surface metrics/logs from skills.
// simple pattern
async function callLinkedIn(url, token, org) {
  for(let i=0;i<5;i++){
    const res = await fetch(url,{headers:{Authorization:`Bearer ${token}`}});
    if(res.status!==429) return res;
    const ra = res.headers.get('retry-after');
    const wait = ra?parseInt(ra,10)*1000: Math.min(60000, (2**i)*1000);
    await redis.set(`linkedin:cooldown:${org}`,1,'EX',Math.ceil(wait/1000));
    await new Promise(r=>setTimeout(r, wait + Math.random()*500));
  }
  throw new Error('rate limited');
}

4

Mapping Organization Pages to OpenClaw Accounts & rw_organization_admin permission

Direct answer: Use an explicit external mapping (database or key‑value store) that links each organization page ID to an OpenClaw account ID, and only allow changes when the executing agent/skill presents a token containing the rw_organization_admin permission. Validate scopes server-side, persist mappings outside the agent runtime, and keep credentials in env vars or a secrets store.

 

Implementation notes

 

Practical pattern:

  • Store mapping in a durable DB keyed by page ID.
  • Validate permission by checking token scopes before writes.
  • Run mutations from a hosted service (not ephemeral agent) for reliability.
// Express webhook: check token scopes and update mapping
const jwt = require('jsonwebtoken')
// req.body.pageId, req.body.accountId
const token = process.env.OPENCLAW_TOKEN
const claims = jwt.decode(token) // // validate signature in real code
if (!claims.scopes || !claims.scopes.includes('rw_organization_admin')) throw new Error('missing permission')
await db.upsertMapping(req.body.pageId, req.body.accountId)
Book a Free Consultation

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

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.