npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@redonvn/linkedin-sdk

v1.2.0

Published

Complete LinkedIn SDK for Consumer, Marketing, Sales, Talent, Learning, and Compliance APIs

Readme

LinkedIn SDK v1.0.0 🚀

NPM Version TypeScript NestJS Node.js License: MIT API Coverage Downloads

The most comprehensive and production-ready LinkedIn API SDK for TypeScript/JavaScript

A complete, enterprise-grade TypeScript SDK for LinkedIn APIs, built with NestJS and featuring full support for all major LinkedIn API products:

  • 🏢 Consumer API - Profile, Sharing, Authentication
  • 📈 Marketing API - Ads, Campaigns, Analytics, Company Pages
  • 💼 Sales Navigator API - Analytics, CRM Validation, Lead Search
  • 🎯 Talent Solutions API - Job Posting, Applications Management
  • 📚 LinkedIn Learning API - Content Management
  • 🔒 Compliance API - Activity Monitoring & Data Export

🚀 Features

  • Complete TypeScript Support - Full type definitions and IntelliSense
  • OAuth 2.0 Authentication - Secure token management
  • NestJS Integration - Ready-to-use REST API server
  • Docker Support - Containerized deployment ready
  • Comprehensive Testing - Unit and integration tests
  • Error Handling - Robust error management and logging
  • Swagger Documentation - Auto-generated API docs
  • Webhook Utilities - Challenge validation and signature verification
  • Environment Configuration - Flexible setup options

📦 Installation

Using npm

npm install @redonvn/linkedin-sdk

Using yarn

yarn add @redonvn/linkedin-sdk

Using pnpm

pnpm add @redonvn/linkedin-sdk

Clone Repository

git clone https://github.com/phamtung86/linkedin-sdk.git
cd linkedin-sdk
npm install

🔐 Authentication & Setup

Step 1: LinkedIn App Setup

Before using the SDK, you need to create a LinkedIn App:

  1. Create LinkedIn App:

    • Go to LinkedIn Developer Portal
    • Click "Create app"
    • Fill in required information:
      • App name: Your application name
      • LinkedIn Page: Associate with company page (required)
      • Privacy policy URL: Your privacy policy
      • App logo: Upload your logo
  2. Verify Your App:

    • Phone number verification required
    • Email confirmation
  3. Configure Authentication:

    • Go to "Auth" tab
    • Add Authorized redirect URLs:
      http://localhost:3000/auth/callback
      https://yourdomain.com/auth/callback
  4. Request Permissions:

    • Default Tier (No review needed): profile, email, openid
    • Standard Tier (Basic review): w_member_social, r_ads, rw_ads, w_organization_social
    • Development Tier (Partner review): Advanced Marketing APIs

Step 2: OAuth 2.0 Flow Implementation

Complete OAuth Flow Example:

import express from 'express';
import { createLinkedInSDK } from '@redonvn/linkedin-sdk';

const app = express();
const linkedin = createLinkedInSDK({
  clientId: process.env.LINKEDIN_CLIENT_ID!,
  clientSecret: process.env.LINKEDIN_CLIENT_SECRET!,
  redirectUri: process.env.LINKEDIN_REDIRECT_URI!
});

// Step 1: Redirect to LinkedIn for authorization
app.get('/auth/linkedin', (req, res) => {
  const scopes = ['profile', 'email', 'w_member_social', 'w_organization_social'];
  const authUrl = linkedin.consumer.getAuthUrl(scopes);
  res.redirect(authUrl);
});

// Step 2: Handle callback and exchange code for token
app.get('/auth/callback', async (req, res) => {
  try {
    const { code } = req.query;
    
    // Exchange authorization code for access token
    const tokenResponse = await linkedin.consumer.getAccessToken(code as string);
    
    // Store token securely (session, database, etc.)
    req.session.linkedinToken = tokenResponse;
    
    // Set token for subsequent API calls
    linkedin.setAccessToken(tokenResponse.access_token);
    
    res.redirect('/dashboard');
  } catch (error) {
    console.error('Authentication failed:', error);
    res.status(500).send('Authentication failed');
  }
});

// Step 3: Use authenticated APIs
app.get('/profile', async (req, res) => {
  try {
    const token = req.session.linkedinToken;
    if (!token) {
      return res.redirect('/auth/linkedin');
    }
    
    linkedin.setAccessToken(token.access_token);
    const profile = await linkedin.consumer.getProfile();
    
    res.json(profile);
  } catch (error) {
    console.error('Get profile failed:', error);
    res.status(500).json({ error: 'Failed to get profile' });
  }
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

⚡ Quick Start

Option A: Use as NPM Library (Recommended)

import { createLinkedInSDK, LinkedInConfig } from '@redonvn/linkedin-sdk';

// Initialize SDK
const config: LinkedInConfig = {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  redirectUri: 'http://localhost:3000/callback'
};

const linkedin = createLinkedInSDK(config);

// OAuth Flow
const authUrl = linkedin.consumer.getAuthUrl(['profile', 'email']);
// ... redirect user, get code from callback ...

const token = await linkedin.consumer.getAccessToken(code);
linkedin.setAccessToken(token.access_token);

// Use APIs
const profile = await linkedin.consumer.getProfile();
const email = await linkedin.consumer.getEmail();

// Share content
await linkedin.consumer.shareContent({
  text: 'Hello LinkedIn! 🚀',
  url: 'https://example.com'
});

Option B: Use as NestJS Server

# Clone repository
git clone https://github.com/phamtung86/linkedin-sdk.git
cd linkedin-sdk

# Install dependencies
npm install

# Configure environment
cp .env.example .env
# Edit .env with your LinkedIn app credentials

# Build and start
npm run build
npm run start:prod

# Or start in development mode
npm run dev

# Visit API documentation
# http://localhost:3000/docs

🔧 Configuration

Environment Variables

Create a .env file in your project root:

# LinkedIn API Configuration
LINKEDIN_CLIENT_ID=your_linkedin_client_id
LINKEDIN_CLIENT_SECRET=your_linkedin_client_secret
LINKEDIN_REDIRECT_URI=http://localhost:3000/api/v1/linkedin/auth/callback

# API Configuration (Optional - defaults provided)
LINKEDIN_BASE_URL=https://api.linkedin.com/v2
LINKEDIN_AUTH_URL=https://www.linkedin.com/oauth/v2/authorization
LINKEDIN_TOKEN_URL=https://www.linkedin.com/oauth/v2/accessToken

# Server Configuration
PORT=3000
NODE_ENV=development
LOG_LEVEL=debug

Programmatic Configuration

import { LinkedInConfig } from 'linkedin-sdk-v3';

const config: LinkedInConfig = {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  redirectUri: 'http://localhost:3000/callback',
  baseUrl: 'https://api.linkedin.com/v2', // Optional
  authUrl: 'https://www.linkedin.com/oauth/v2/authorization', // Optional
  tokenUrl: 'https://www.linkedin.com/oauth/v2/accessToken' // Optional
};

📚 API Reference

Consumer API

Authentication

// Generate authorization URL
const authUrl = linkedin.consumer.getAuthUrl(['profile', 'email'], 'optional-state');

// Exchange authorization code for access token
const token = await linkedin.consumer.getAccessToken(code);

// Refresh expired token
const newToken = await linkedin.consumer.refreshAccessToken(refreshToken);

Profile & Content

// Get basic profile
const profile = await linkedin.consumer.getProfile();

// Get email address
const email = await linkedin.consumer.getEmail();

// Share content
const shareResult = await linkedin.consumer.shareContent({
  text: 'Hello LinkedIn!',
  url: 'https://example.com', // Optional
  imageUrn: 'urn:li:image:12345' // Optional
});

Marketing API

// Get ad accounts
const accounts = await linkedin.marketing.getAdAccounts();

// Create campaign
const campaign = await linkedin.marketing.createCampaign({
  name: 'My Campaign',
  account: 'urn:li:sponsoredAccount:12345'
  // ... other campaign data
});

// Get analytics
const analytics = await linkedin.marketing.getAnalytics({
  campaigns: ['urn:li:sponsoredCampaign:12345'],
  dateRange: {
    start: '2023-01-01',
    end: '2023-01-31'
  }
});

🏢 Company Page Management

Organic Content Posting (Free)

// Create organic post for company page
const organicPost = await linkedin.marketing.createOrganicPost({
  author: 'urn:li:organization:123456789', // Your company page ID
  lifecycleState: 'PUBLISHED',
  specificContent: {
    'com.linkedin.ugc.ShareContent': {
      shareCommentary: { 
        text: '🚀 Exciting company news! We just launched our new feature.' 
      },
      shareMediaCategory: 'NONE'
    }
  },
  visibility: { 
    'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' 
  }
}, token);

// Create post with image
const imagePost = await linkedin.marketing.createOrganicPost({
  author: 'urn:li:organization:123456789',
  lifecycleState: 'PUBLISHED',
  specificContent: {
    'com.linkedin.ugc.ShareContent': {
      shareCommentary: { 
        text: 'Check out our latest product showcase! 📸' 
      },
      shareMediaCategory: 'IMAGE',
      media: [{
        status: 'READY',
        media: imageUrn, // From uploadImage()
        title: { text: 'Product Showcase' },
        description: { text: 'Our latest innovation' }
      }]
    }
  },
  visibility: { 
    'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC' 
  }
}, token);

Page Analytics & Management

// Get company page information
const companyPage = await linkedin.marketing.getCompanyPage('123456789', token);

// Get page followers count
const followers = await linkedin.marketing.getPageFollowers('123456789', token);

// Get all organic posts
const posts = await linkedin.marketing.getOrganicPosts(
  'urn:li:organization:123456789', 
  token
);

// Upload media for posts
const fs = require('fs');
const imageBuffer = fs.readFileSync('company-announcement.jpg');
const uploadResult = await linkedin.marketing.uploadImage(imageBuffer, token);
const imageUrn = uploadResult.image;

Community Management

// Get comments on a post
const comments = await linkedin.marketing.getComments(postId, token);

// Reply to comments
for (const comment of comments) {
  if (comment.text.includes('@yourcompany')) {
    await linkedin.marketing.replyToComment(comment.id, {
      text: `Thank you for your interest, ${comment.author.name}! We'll be in touch soon.`
    }, token);
  }
}

// Get mentions and interactions
const interactions = await linkedin.marketing.getCommunityInteractions({
  pageId: 'urn:li:organization:123456789',
  dateRange: { start: '2024-01-01', end: '2024-01-31' }
}, token);

Sales Navigator API

// Get analytics
const salesAnalytics = await linkedin.sales.getAnalytics();

// Get display data
const displayData = await linkedin.sales.getDisplayData();

// Validate CRM data
const validation = await linkedin.sales.validateCrmData({
  contacts: [
    { email: '[email protected]', firstName: 'John', lastName: 'Doe' }
  ]
});

// Get profiles
const profiles = await linkedin.sales.getProfiles({
  keywords: 'software engineer',
  location: 'San Francisco'
});

Talent Solutions API

// Post a job
const job = await linkedin.talent.postJob({
  title: 'Software Engineer',
  company: 'urn:li:organization:12345',
  location: 'San Francisco, CA',
  description: 'We are looking for...'
});

// Submit job application
const application = await linkedin.talent.submitApply({
  job: 'urn:li:job:12345',
  applicant: 'urn:li:person:67890'
});

Compliance API

// Get compliance activities
const activities = await linkedin.compliance.getActivities();

Learning API

// Request access (displays information)
linkedin.learning.requestAccess();
// Note: LinkedIn Learning API requires manual approval

🌐 REST API Endpoints

When running as a server, the following endpoints are available:

Health Check

GET /api/v1/linkedin/test/health

Authentication

GET  /api/v1/linkedin/auth/authorization-url?scopes=profile,email
POST /api/v1/linkedin/auth/token
POST /api/v1/linkedin/auth/refresh

Consumer API

GET  /api/v1/linkedin/profile/basic
GET  /api/v1/linkedin/profile/email
POST /api/v1/linkedin/share

Marketing API

GET  /api/v1/linkedin/marketing/ad-accounts
POST /api/v1/linkedin/marketing/campaigns
GET  /api/v1/linkedin/marketing/analytics
POST /api/v1/linkedin/marketing/organic-posts
GET  /api/v1/linkedin/marketing/company-page/:id
GET  /api/v1/linkedin/marketing/page-followers/:id

Company Page Management

POST /api/v1/linkedin/marketing/organic-posts
GET  /api/v1/linkedin/marketing/organic-posts/:authorUrn
POST /api/v1/linkedin/marketing/upload-image
POST /api/v1/linkedin/marketing/upload-video
GET  /api/v1/linkedin/comments/:postId
POST /api/v1/linkedin/comments/:commentId/reply

Sales API

GET  /api/v1/linkedin/sales/analytics
GET  /api/v1/linkedin/sales/display-data
POST /api/v1/linkedin/sales/validate-crm
GET  /api/v1/linkedin/sales/profiles

Talent API

POST /api/v1/linkedin/talent/jobs
POST /api/v1/linkedin/talent/apply

Learning API

GET /api/v1/linkedin/learning/request-access

Compliance API

GET /api/v1/linkedin/compliance/activities

🐳 Docker Deployment

Development

docker-compose --profile dev up linkedin-sdk-dev

Production

docker-compose up linkedin-sdk

Custom Build

docker build -t linkedin-sdk .
docker run -p 3000:3000 --env-file .env linkedin-sdk

🧪 Testing

Run All Tests

npm test

Run Tests with Coverage

npm run test:cov

Run Tests in Watch Mode

npm run test:watch

Run E2E Tests

npm run test:e2e

🔐 Security

Webhook Signature Verification

import { verifyWebhookSignature } from 'linkedin-sdk-v3';

// Verify webhook signature
const isValid = verifyWebhookSignature(
  rawBodyString,
  request.headers['x-li-signature'],
  clientSecret
);

if (!isValid) {
  throw new Error('Invalid webhook signature');
}

Challenge Response for Webhook Setup

import { computeChallengeResponse } from 'linkedin-sdk-v3';

const response = computeChallengeResponse(challengeCode, clientSecret);

📖 LinkedIn API Permissions

Different endpoints require different permissions. Make sure to request the appropriate scopes:

Consumer API

  • profile - Basic profile information
  • email - Email address
  • w_member_social - Share content

Marketing API

  • r_ads - Read ad accounts and campaigns
  • rw_ads - Create and modify campaigns
  • r_ads_reporting - Access reporting data

Sales Navigator API

  • r_sales_nav_analytics - Sales analytics
  • r_sales_nav_display - Display data
  • r_sales_nav_validation - CRM validation
  • r_sales_nav_profiles - Profile access

Talent Solutions API

Requires participation in LinkedIn's partner programs.

Learning API

Requires manual approval from LinkedIn.

Compliance API

  • r_compliance - Compliance activities

🚨 Error Handling

The SDK provides comprehensive error handling:

import { LinkedInApiError } from 'linkedin-sdk-v3';

try {
  const profile = await linkedin.consumer.getProfile();
} catch (error) {
  if (error instanceof LinkedInApiError) {
    console.error('LinkedIn API Error:', error.message);
    console.error('Status:', error.status);
    console.error('Service Error Code:', error.serviceErrorCode);
  } else {
    console.error('Unexpected error:', error);
  }
}

📝 Examples

Complete OAuth Flow

import express from 'express';
import { createLinkedInSDK } from 'linkedin-sdk-v3';

const app = express();
const linkedin = createLinkedInSDK({
  clientId: process.env.LINKEDIN_CLIENT_ID!,
  clientSecret: process.env.LINKEDIN_CLIENT_SECRET!,
  redirectUri: 'http://localhost:3000/callback'
});

// Start OAuth flow
app.get('/auth', (req, res) => {
  const authUrl = linkedin.consumer.getAuthUrl(['profile', 'email']);
  res.redirect(authUrl);
});

// Handle callback
app.get('/callback', async (req, res) => {
  try {
    const { code } = req.query;
    const token = await linkedin.consumer.getAccessToken(code as string);
    
    // Store token securely (session, database, etc.)
    req.session.linkedinToken = token;
    
    res.redirect('/profile');
  } catch (error) {
    res.status(500).send('Authentication failed');
  }
});

// Get profile
app.get('/profile', async (req, res) => {
  try {
    const profile = await linkedin.consumer.getProfile();
    res.json(profile);
  } catch (error) {
    res.status(500).send('Failed to get profile');
  }
});

app.listen(3000);

Batch Operations

// Get multiple marketing metrics
const promises = [
  linkedin.marketing.getAdAccounts(),
  linkedin.marketing.getAnalytics({ dateRange: { start: '2023-01-01', end: '2023-01-31' } })
];

const [accounts, analytics] = await Promise.all(promises);

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a pull request

Development Setup

git clone https://github.com/your-username/linkedin-sdk-v3.git
cd linkedin-sdk-v3
npm install
cp .env.example .env
# Add your LinkedIn app credentials to .env
npm run dev

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

📞 Support

🔗 Related Resources


Made with ❤️ by Redon

LinkedIn SDK v3.0.0 - Empowering developers with comprehensive LinkedIn API integration