LinkedIn API Setup Guide
This document covers the setup process for LinkedIn API integration, including common issues encountered.
Prerequisites
- LinkedIn Developer account
- A LinkedIn app with posting permissions
Creating a LinkedIn App
- Go to LinkedIn Developer Portal
- Click “Create app”
- Fill in the required information:
- App name
- LinkedIn Page (you can use your personal profile page)
- App logo (optional)
- Click “Create app”
Required Products & Scopes
Step 1: Add Required Products
In your app settings, go to the Products tab and add:
- “Share on LinkedIn” - For posting content
- “Sign In with LinkedIn using OpenID Connect” - For retrieving your member ID
Step 2: Configure OAuth Scopes
After adding the products, verify you have these scopes in the Auth tab:
- ✅
openid- Required for OpenID Connect - ✅
profile- Required to get your numeric member ID - ✅
w_member_social- Required for posting content
Getting Your Credentials
1. Get OAuth Access Token
- In your app, go to the Auth tab
- Scroll to OAuth 2.0 tools
- Click “Create token” or “Generate token”
- IMPORTANT: Make sure all three scopes are checked:
openidprofilew_member_social
- Copy the access token
Note: Access tokens expire after 60 days. You’ll need to regenerate periodically.
2. Get Your Member ID
Run the helper script with your new access token:
cd scripts
source venv/bin/activate
python get_author_id.py YOUR_ACCESS_TOKEN
Or use curl:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
https://api.linkedin.com/v2/userinfo
The response will include your sub field, which is your numeric member ID:
{
"sub": "123456789",
"name": "Your Name",
"email": "your@email.com"
}
Your author ID will be: urn:li:member:123456789
Common Issues
Issue 1: 403 Error on /v2/userinfo
Error: "Not enough permissions to access: userinfo.GET.NO_VERSION"
Cause: Your access token doesn’t have the openid and profile scopes.
Solution:
- Add the “Sign In with LinkedIn using OpenID Connect” product to your app
- Generate a NEW access token with
openid,profile, andw_member_socialscopes - The old token won’t automatically get new scopes - you must regenerate
Issue 2: 422 Error on Posting
Error: "urn:li:person:XXX" does not match urn:li:member:\\d+
Cause: Wrong URN format. LinkedIn’s posting API requires:
- ✅
urn:li:member:123456(numeric ID) - ❌
urn:li:person:ACoAAAERPDo...(alphanumeric profile ID)
Solution: Use the get_author_id.py script with a token that has profile scope to get the correct numeric ID.
Issue 3: Alphanumeric vs Numeric IDs
LinkedIn has multiple ID formats:
- Profile URN:
urn:li:fsd_profile:ACoAAAERPDo...(from web interface) - Person URN:
urn:li:person:ACoAAAERPDo...(from Voyager API) - Member URN:
urn:li:member:123456(from REST API - this is what you need)
Only the numeric member URN works with the posting API.
Issue 4: Scope Authorization Delays
Symptom: Just added OpenID Connect product but still getting 403 errors
Solution: Wait a few minutes for LinkedIn to process the authorization on their backend. If it persists beyond 10 minutes, try:
- Regenerating your access token
- Logging out and back into LinkedIn Developer Portal
- Checking that the products show as “Active” in your app settings
Setting Up GitHub Actions
Once you have your credentials:
- Go to your GitHub repository
- Navigate to: Settings → Secrets and variables → Actions
- Click “New repository secret”
- Add two secrets:
- Name:
LINKEDIN_ACCESS_TOKEN, Value: Your OAuth token - Name:
LINKEDIN_AUTHOR_ID, Value:urn:li:member:YOUR_NUMERIC_ID
- Name:
The GitHub Action will use these secrets to post to LinkedIn automatically when you push to main.
Testing Your Setup
Test that everything works:
cd scripts
source venv/bin/activate
# Test getting your author ID
python get_author_id.py YOUR_ACCESS_TOKEN
# Test posting (this will create a real post!)
python linkedin_post.py ../_posts/your-post.md
Access Token Expiration
LinkedIn access tokens expire after 60 days. When your token expires:
- Go to LinkedIn Developer Portal
- Navigate to your app → Auth tab
- Generate a new token with the same scopes
- Update your
.envfile (local) and GitHub Secrets (for Actions)
Security Notes
- Never commit your
.envfile (already in.gitignore) - Never share your access token publicly
- Rotate tokens if accidentally exposed
- Use GitHub Secrets for CI/CD - never hardcode credentials