---
name: "LinkedIn API"
description: "Skill for LinkedIn API — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "social"
agents: ["claude-code", "codex", "gemini"]
tags: ["linkedin-api", "social", "auto-generated"]
---

# LinkedIn API

---
name: LinkedIn API
description: Use when integrating with LinkedIn's professional network API for authentication, profile data, company pages, content sharing, and lead generation workflows.
category: social
metadata:
  author: skynet
  version: 1.0.0
---

# LinkedIn API

## Overview
LinkedIn API provides access to professional profiles, company data, content sharing, and advertising capabilities. Choose the appropriate API version and scope based on your integration needs.

## Authentication Setup

### Register Application
```bash
# Navigate to LinkedIn Developer Portal
# https://www.linkedin.com/developers/apps

# Note your credentials
CLIENT_ID="your_client_id"
CLIENT_SECRET="your_client_secret"
REDIRECT_URI="https://yourapp.com/callback"
```

### OAuth 2.0 Flow
```bash
# Step 1: Authorization URL
AUTH_URL="https://www.linkedin.com/oauth/v2/authorization"
SCOPE="r_liteprofile r_emailaddress w_member_social"

curl -G "${AUTH_URL}" \
  -d "response_type=code" \
  -d "client_id=${CLIENT_ID}" \
  -d "redirect_uri=${REDIRECT_URI}" \
  -d "scope=${SCOPE}"

# Step 2: Exchange code for token
curl -X POST "https://www.linkedin.com/oauth/v2/accessToken" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=${AUTH_CODE}" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "redirect_uri=${REDIRECT_URI}"
```

## Profile Operations

### Get Current User Profile
```bash
ACCESS_TOKEN="your_access_token"

# Basic profile info
curl -X GET "https://api.linkedin.com/v2/people/~" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json"

# Profile with specific fields
curl -X GET "https://api.linkedin.com/v2/people/~:(id,firstName,lastName,profilePicture(displayImage~:playableStreams))" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

# Email address (requires r_emailaddress scope)
curl -X GET "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
```

### Get Company Profile
```bash
COMPANY_ID="12345"

# Company basic info
curl -X GET "https://api.linkedin.com/v2/companies/${COMPANY_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

# Company with specific fields
curl -X GET "https://api.linkedin.com/v2/companies/${COMPANY_ID}:(id,name,description,website,industries,locations)" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
```

## Content Sharing

### Share Text Post
```bash
# Create a simple text post
curl -X POST "https://api.linkedin.com/v2/ugcPosts" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "author": "urn:li:person:PERSON_ID",
    "lifecycleState": "PUBLISHED",
    "specificContent": {
      "com.linkedin.ugc.ShareContent": {
        "shareCommentary": {
          "text": "Hello LinkedIn! This is my first API post."
        },
        "shareMediaCategory": "NONE"
      }
    },
    "visibility": {
      "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
    }
  }'
```

### Share Link with Preview
```bash
curl -X POST "https://api.linkedin.com/v2/ugcPosts" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "author": "urn:li:person:PERSON_ID",
    "lifecycleState": "PUBLISHED",
    "specificContent": {
      "com.linkedin.ugc.ShareContent": {
        "shareCommentary": {
          "text": "Check out this amazing article!"
        },
        "shareMediaCategory": "ARTICLE",
        "media": [{
          "status": "READY",
          "description": {
            "text": "Article description"
          },
          "originalUrl": "https://example.com/article",
          "title": {
            "text": "Article Title"
          }
        }]
      }
    },
    "visibility": {
      "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
    }
  }'
```

## Company Page Management

### Post to Company Page
```bash
COMPANY_URN="urn:li:organization:COMPANY_ID"

curl -X POST "https://api.linkedin.com/v2/ugcPosts" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "author": "'${COMPANY_URN}'",
    "lifecycleState": "PUBLISHED",
    "specificContent": {
      "com.linkedin.ugc.ShareContent": {
        "shareCommentary": {
          "text": "Company update from our API!"
        },
        "shareMediaCategory": "NONE"
      }
    },
    "visibility": {
      "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
    }
  }'
```

### Get Company Updates
```bash
# Fetch company page posts
curl -X GET "https://api.linkedin.com/v2/ugcPosts?q=authors&authors=List(${COMPANY_URN})&count=10" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
```

## Analytics and Metrics

### Get Post Analytics
```bash
POST_ID="ugc_post_id"

# Social actions on post
curl -X GET "https://api.linkedin.com/v2/socialActions/${POST_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

# Post statistics
curl -X GET "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=${COMPANY_URN}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
```

## Lead Generation

### Get Lead Gen Forms
```bash
# List lead gen forms for account
ACCOUNT_ID="your_account_id"

curl -X GET "https://api.linkedin.com/v2/leadgenForms?q=account&account=${ACCOUNT_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

# Get form responses
FORM_ID="form_id"
curl -X GET "https://api.linkedin.com/v2/leadFormResponses?q=form&form=${FORM_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
```

## Decision Trees

### Choose API Version
```
Need to access LinkedIn data?
├─ Personal profile access → Use Profile API v2
├─ Company page management → Use Organizations API v2
├─ Content sharing → Use UGC Post API v2
├─ Advertising data → Use Marketing API v2
└─ Lead generation → Use Lead Gen Forms API v2
```

### Authentication Scope Selection
```
What data do you need?
├─ Basic profile → r_liteprofile
├─ Email address → r_emailaddress
├─ Post content → w_member_social
├─ Company pages → w_organization_social
└─ Advertising → r_ads, w_ads
```

## Environment Variables Setup

```bash
# Create .env file
cat > .env << EOF
LINKEDIN_CLIENT_ID=your_client_id
LINKEDIN_CLIENT_SECRET=your_client_secret
LINKEDIN_REDIRECT_URI=https://yourapp.com/callback
LINKEDIN_ACCESS_TOKEN=your_access_token
LINKEDIN_PERSON_ID=your_person_id
LINKEDIN_COMPANY_ID=your_company_id
EOF

# Load variables
source .env
```

## Common Workflows

### Complete Profile Integration
```bash
#!/bin/bash
# fetch_linkedin_profile.sh

ACCESS_TOKEN=$1
OUTPUT_FILE="profile_data.json"

echo "Fetching LinkedIn profile data..."

# Get basic profile
curl -s "https://api.linkedin.com/v2/people/~:(id,firstName,lastName,headline,summary)" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" > ${OUTPUT_FILE}

# Get profile picture
curl -s "https://api.linkedin.com/v2/people/~:(profilePicture(displayImage~:playableStreams))" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" | \
  jq '.profilePicture."displayImage~".elements[-1].identifiers[0].identifier' >> profile_pic_url.txt

# Get email
curl -s "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" | \
  jq '.elements[0]."handle~".emailAddress' >> email.txt

echo "Profile data saved to ${OUTPUT_FILE}"
```

## Troubleshooting

### Common Error Messages

**403 Forbidden - Insufficient privileges**
```bash
# Check your app permissions in LinkedIn Developer Console
# Ensure required scopes are approved
# For company content: verify admin access to company page
```

**401 Unauthorized - Invalid access token**
```bash
# Refresh your access token
curl -X POST "https://www.linkedin.com/oauth/v2/accessToken" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=${REFRESH_TOKEN}" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}"
```

**429 Too Many Requests - Rate limit exceeded**
```bash
# Check rate limit headers
curl -I "https://api.linkedin.com/v2/people/~" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"

# Look for: X-RateLimit-Remaining, X-RateLimit-Reset
# Implement exponential backoff
```

**400 Bad Request - Invalid URN format**
```bash
# Ensure URN format is correct
# Person URN: urn:li:person:PERSON_ID
# Company URN: urn:li:organization:COMPANY_ID
# Check ID format matches LinkedIn's requirements
```

### Debug API Responses
```bash
# Verbose curl output
curl -v -X GET "https://api.linkedin.com/v2/people/~" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  2>&1 | grep -E "(> |< |HTTP/)"

# Pretty print JSON response
curl -s "https://api.linkedin.com/v2/people/~" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.'
```

### Webhook Validation
```bash
# Validate webhook signatures (if using webhooks)
WEBHOOK_SECRET="your_webhook_secret"
SIGNATURE_HEADER="x-li-signature"

# Verify HMAC signature in your webhook handler
echo -n "${REQUEST_BODY}" | openssl dgst -sha1 -hmac "${WEBHOOK_SECRET}" -binary | base64
```
