linkedin-cli

May 25, 2026 · View on GitHub

AI-agent-friendly CLI for LinkedIn automation via Linked API.

Give your AI agent full LinkedIn capabilities: send messages, fetch profiles, search people and companies, manage connections, create posts, react, comment – all through simple CLI commands with structured JSON output. Built for OpenClaw, Claude Code, Cursor, Codex, and any AI agent that can execute shell commands.

Under the hood, Linked API runs a dedicated cloud browser instance for each connected LinkedIn account. When your agent runs a command, the CLI sends the request to Linked API's infrastructure, where an isolated browser with a residential IP performs the action on LinkedIn – simulating human-like mouse movements, keyboard input, and natural browsing patterns. No local browsers, no proxies, no Selenium, no infrastructure to manage. Learn more about safety.

Install

npm install -g @linkedapi/linkedin-cli

Quick Start

# 1. Save your tokens (get them at app.linkedapi.io)
linkedin setup

# 2. Fetch a profile
linkedin person fetch https://www.linkedin.com/in/vprudnikoff --json

# 3. Search for people
linkedin person search --term "revops engineer" --current-companies "Linked API" --json

# 4. Send a message
linkedin message send https://www.linkedin.com/in/vprudnikoff "Hey, loved your latest post!"

Authentication

Initial setup

linkedin setup

The CLI will ask for your Linked API Token and Identification Token. Get them at app.linkedapi.io.

For non-interactive environments (CI, scripts):

linkedin setup --linked-api-token=xxx --identification-token=yyy
FlagDescription
--linked-api-tokenLinked API Token (skips prompt)
--identification-tokenIdentification Token (skips prompt)

Multiple accounts

Run linkedin setup again with different tokens to add more accounts. The last added account becomes active.

# List all accounts (* marks active)
linkedin account list

# Switch active account
linkedin account switch "Vlad"

# Update tokens for active account (e.g. after regenerating tokens on the dashboard)
linkedin account update

# Update tokens for a specific account
linkedin account update "Vlad"

# Non-interactive token update
linkedin account update --linked-api-token=xxx --identification-token=yyy

# Rename a saved account
linkedin account rename "Vlad" --name "My Work Account"

# Use a specific account for one command
linkedin person fetch https://www.linkedin.com/in/... --account "Vlad"

# Remove active account (auto-switches to next)
linkedin reset

# Remove all accounts
linkedin reset --all

Global Flags

Every command supports these flags:

FlagDescription
--jsonStructured JSON output to stdout
--fields name,url,...Select specific fields in output
--quiet / -qSuppress stderr progress
--no-colorDisable colors
--account "Name"Use a specific account for this command

Command Reference

People

person fetch

Fetch a LinkedIn person profile with optional additional data sections.

linkedin person fetch <url> [flags]
ArgRequiredDescription
urlyesLinkedIn profile URL
FlagTypeDescription
--experiencebooleanInclude work experience
--educationbooleanInclude education history
--skillsbooleanInclude skills
--languagesbooleanInclude languages
--postsbooleanInclude recent posts
--commentsbooleanInclude recent comments
--reactionsbooleanInclude recent reactions
--posts-limitintegerMax posts to retrieve (requires --posts)
--posts-sincestringPosts since ISO timestamp (requires --posts)
--comments-limitintegerMax comments to retrieve (requires --comments)
--comments-sincestringComments since ISO timestamp (requires --comments)
--reactions-limitintegerMax reactions to retrieve (requires --reactions)
--reactions-sincestringReactions since ISO timestamp (requires --reactions)
# Basic profile info
linkedin person fetch https://www.linkedin.com/in/vprudnikoff

# Full profile with experience and education
linkedin person fetch https://www.linkedin.com/in/vprudnikoff --experience --education --json

# Profile with recent posts (last 5)
linkedin person fetch https://www.linkedin.com/in/vprudnikoff --posts --posts-limit 5

# Everything
linkedin person fetch https://www.linkedin.com/in/vprudnikoff \
  --experience --education --skills --languages \
  --posts --comments --reactions --json

Search for people on LinkedIn with filters.

linkedin person search [flags]
FlagTypeDescription
--termstringSearch keyword or phrase
--limitintegerMax results to return
--first-namestringFilter by first name
--last-namestringFilter by last name
--positionstringFilter by job position
--locationsstringComma-separated locations
--industriesstringComma-separated industries
--current-companiesstringComma-separated current company names
--previous-companiesstringComma-separated previous company names
--schoolsstringComma-separated school names
linkedin person search --term "revops engineer" --locations "San Francisco"
linkedin person search --current-companies "Linked API" --position "Engineer" --json
linkedin person search --schools "MIT" --industries "Software Development" --limit 20 --json

Companies

company fetch

Fetch a LinkedIn company profile with optional employees, decision makers, and posts.

linkedin company fetch <url> [flags]
ArgRequiredDescription
urlyesLinkedIn company URL
FlagTypeDescription
--employeesbooleanInclude employee data
--dmsbooleanInclude decision makers
--postsbooleanInclude company posts
--employees-limitintegerMax employees to retrieve (requires --employees)
--employees-first-namestringFilter employees by first name (requires --employees)
--employees-last-namestringFilter employees by last name (requires --employees)
--employees-positionstringFilter employees by position (requires --employees)
--employees-locationsstringFilter employees by locations, comma-separated (requires --employees)
--employees-industriesstringFilter employees by industries, comma-separated (requires --employees)
--employees-schoolsstringFilter employees by schools, comma-separated (requires --employees)
--dms-limitintegerMax decision makers to retrieve (requires --dms)
--posts-limitintegerMax posts to retrieve (requires --posts)
--posts-sincestringPosts since ISO timestamp (requires --posts)
# Basic company info
linkedin company fetch https://www.linkedin.com/company/flutterwtf

# Company with employees and decision makers
linkedin company fetch https://www.linkedin.com/company/flutterwtf --employees --dms --json

# Filter employees by position and location
linkedin company fetch https://www.linkedin.com/company/flutterwtf \
  --employees --employees-position "Engineer" --employees-locations "United States"

# Company posts from last month
linkedin company fetch https://www.linkedin.com/company/flutterwtf \
  --posts --posts-since 2024-12-01T00:00:00Z --json

Search for companies on LinkedIn with filters.

linkedin company search [flags]
FlagTypeDescription
--termstringSearch keyword or phrase
--limitintegerMax results to return
--sizesstringCompany sizes, comma-separated (1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+)
--locationsstringComma-separated locations
--industriesstringComma-separated industries
linkedin company search --term "fintech" --sizes "11-50,51-200" --json
linkedin company search --industries "Software Development" --locations "Berlin" --json

Messages

message send

Send a message to a LinkedIn connection.

linkedin message send <person-url> <text>
ArgRequiredDescription
person-urlyesLinkedIn profile URL of the recipient
textyesMessage text (up to 1900 characters)
linkedin message send https://www.linkedin.com/in/vprudnikoff "Hey, loved your latest post!"

message get

Get conversation messages with a LinkedIn person.

linkedin message get <person-url> [flags]
ArgRequiredDescription
person-urlyesLinkedIn profile URL
FlagTypeDescription
--sincestringOnly retrieve messages since this ISO timestamp
linkedin message get https://www.linkedin.com/in/vprudnikoff --json
linkedin message get https://www.linkedin.com/in/vprudnikoff --since 2024-01-15T10:30:00Z

Note: The first call for a conversation triggers a background sync, which may take longer. Subsequent calls use cached data and are faster.


Connections

connection status

Check connection status with a LinkedIn person.

linkedin connection status <url>
ArgRequiredDescription
urlyesLinkedIn profile URL
linkedin connection status https://www.linkedin.com/in/vprudnikoff

connection send

Send a connection request.

linkedin connection send <url> [flags]
ArgRequiredDescription
urlyesLinkedIn profile URL
FlagTypeDescription
--notestringPersonalized note to include with the request
--emailstringEmail address (required by some profiles to connect)
linkedin connection send https://www.linkedin.com/in/vprudnikoff
linkedin connection send https://www.linkedin.com/in/vprudnikoff --note "Love to connect!"
linkedin connection send https://www.linkedin.com/in/vprudnikoff --email vlad@example.com

connection list

List your LinkedIn connections with optional filters.

linkedin connection list [flags]
FlagTypeDescription
--limitintegerMax connections to return
--sincestringOnly connections made since this ISO timestamp
--first-namestringFilter by first name
--last-namestringFilter by last name
--positionstringFilter by job position
--locationsstringComma-separated locations
--industriesstringComma-separated industries
--current-companiesstringComma-separated current company names
--previous-companiesstringComma-separated previous company names
--schoolsstringComma-separated school names

Note: --since only works when no filter flags are used.

linkedin connection list --limit 50 --json
linkedin connection list --current-companies "Linked API" --position "Engineer" --json
linkedin connection list --since 2024-01-01T00:00:00Z --json

connection pending

List pending outgoing connection requests.

linkedin connection pending
linkedin connection pending --json

connection withdraw

Withdraw a pending connection request.

linkedin connection withdraw <url> [flags]
ArgRequiredDescription
urlyesLinkedIn profile URL
FlagTypeDefaultDescription
--unfollow / --no-unfollowbooleantrueAlso unfollow the person
linkedin connection withdraw https://www.linkedin.com/in/vprudnikoff
linkedin connection withdraw https://www.linkedin.com/in/vprudnikoff --no-unfollow

connection remove

Remove an existing connection.

linkedin connection remove <url>
ArgRequiredDescription
urlyesLinkedIn profile URL
linkedin connection remove https://www.linkedin.com/in/vprudnikoff

Posts

post fetch

Fetch a LinkedIn post with optional comments and reactions.

linkedin post fetch <url> [flags]
ArgRequiredDescription
urlyesLinkedIn post URL
FlagTypeDescription
--commentsbooleanInclude comments
--reactionsbooleanInclude reactions
--comments-limitintegerMax comments to retrieve (requires --comments)
--comments-sortstringSort order: mostRelevant or mostRecent (requires --comments)
--comments-repliesbooleanInclude replies to comments (requires --comments)
--reactions-limitintegerMax reactions to retrieve (requires --reactions)
linkedin post fetch https://www.linkedin.com/posts/vprudnikoff_activity-123

# With comments sorted by most recent, including replies
linkedin post fetch https://www.linkedin.com/posts/vprudnikoff_activity-123 \
  --comments --comments-sort mostRecent --comments-replies --json

# With reactions
linkedin post fetch https://www.linkedin.com/posts/vprudnikoff_activity-123 \
  --comments --reactions --json

post create

Create a LinkedIn post with optional media attachments.

linkedin post create <text> [flags]
ArgRequiredDescription
textyesPost text (up to 3000 characters)
FlagTypeDescription
--company-urlstringPost on behalf of a company page (requires admin access)
--attachmentsstringAttachments as url:type or url:type:name. Types: image, video, document. Can be specified multiple times.

Attachment limits: up to 9 images, or 1 video, or 1 document. Cannot mix types.

linkedin post create "Excited to share our latest update!"

# With an image
linkedin post create "Check this out" \
  --attachments "https://example.com/photo.jpg:image"

# With a document
linkedin post create "Our Q4 report" \
  --attachments "https://example.com/report.pdf:document:Q4 Report"

# Post as a company
linkedin post create "Company announcement" \
  --company-url https://www.linkedin.com/company/flutterwtf

post react

React to a LinkedIn post.

linkedin post react <url> --type <reaction> [flags]
ArgRequiredDescription
urlyesLinkedIn post URL
FlagTypeRequiredDescription
--typestringyesReaction type: like, love, support, celebrate, insightful, funny
--company-urlstringnoReact on behalf of a company page
linkedin post react https://www.linkedin.com/posts/vprudnikoff_activity-123 --type like
linkedin post react https://www.linkedin.com/posts/vprudnikoff_activity-123 --type celebrate \
  --company-url https://www.linkedin.com/company/flutterwtf

post comment

Comment on a LinkedIn post.

linkedin post comment <url> <text> [flags]
ArgRequiredDescription
urlyesLinkedIn post URL
textyesComment text (up to 1000 characters)
FlagTypeDescription
--company-urlstringComment on behalf of a company page
linkedin post comment https://www.linkedin.com/posts/vprudnikoff_activity-123 "Great insights!"
linkedin post comment https://www.linkedin.com/posts/vprudnikoff_activity-123 "Well said!" \
  --company-url https://www.linkedin.com/company/flutterwtf

Statistics

stats ssi

Retrieve your LinkedIn Social Selling Index.

linkedin stats ssi [flags]
linkedin stats ssi --json

stats performance

Retrieve your LinkedIn performance analytics (profile views, post impressions, search appearances).

linkedin stats performance [flags]
linkedin stats performance --json

stats usage

Retrieve Linked API usage statistics for a date range.

linkedin stats usage --start <timestamp> --end <timestamp> [flags]
FlagTypeRequiredDescription
--startstringyesStart date in ISO timestamp
--endstringyesEnd date in ISO timestamp
linkedin stats usage --start 2024-01-01T00:00:00Z --end 2024-01-31T00:00:00Z --json

Sales Navigator

Requires a LinkedIn Sales Navigator subscription.

Fetch a person profile via Sales Navigator.

linkedin navigator person fetch <hashed-url>
ArgRequiredDescription
hashed-urlyesHashed LinkedIn profile URL
linkedin navigator person fetch https://www.linkedin.com/in/ACwAAA...

Search for people via Sales Navigator with advanced filters.

linkedin navigator person search [flags]
FlagTypeDescription
--termstringSearch keyword or phrase
--limitintegerMax results to return
--first-namestringFilter by first name
--last-namestringFilter by last name
--positionstringFilter by job position
--locationsstringComma-separated locations
--industriesstringComma-separated industries
--current-companiesstringComma-separated current company names
--previous-companiesstringComma-separated previous company names
--schoolsstringComma-separated school names
--years-of-experiencestringComma-separated experience ranges: lessThanOne, oneToTwo, threeToFive, sixToTen, moreThanTen
linkedin navigator person search --term "VP Marketing" --locations "United States"
linkedin navigator person search --years-of-experience "moreThanTen" --position "CEO" --json

Fetch a company profile via Sales Navigator with optional employees and decision makers.

linkedin navigator company fetch <hashed-url> [flags]
ArgRequiredDescription
hashed-urlyesHashed LinkedIn company URL
FlagTypeDescription
--employeesbooleanInclude employee data
--dmsbooleanInclude decision makers
--employees-limitintegerMax employees to retrieve (requires --employees)
--employees-first-namestringFilter employees by first name (requires --employees)
--employees-last-namestringFilter employees by last name (requires --employees)
--employees-positionsstringFilter employees by positions, comma-separated (requires --employees)
--employees-locationsstringFilter employees by locations, comma-separated (requires --employees)
--employees-industriesstringFilter employees by industries, comma-separated (requires --employees)
--employees-schoolsstringFilter employees by schools, comma-separated (requires --employees)
--employees-years-of-experiencestringFilter employees by experience ranges, comma-separated (requires --employees)
--dms-limitintegerMax decision makers to retrieve (requires --dms)
linkedin navigator company fetch https://www.linkedin.com/sales/company/97ural --employees --dms
linkedin navigator company fetch https://www.linkedin.com/sales/company/97ural \
  --employees --employees-positions "Engineer,Designer" --employees-locations "Europe"

Search for companies via Sales Navigator with advanced filters including revenue.

linkedin navigator company search [flags]
FlagTypeDescription
--termstringSearch keyword or phrase
--limitintegerMax results to return
--sizesstringCompany sizes, comma-separated (1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+)
--locationsstringComma-separated locations
--industriesstringComma-separated industries
--revenue-minstringMin annual revenue in M USD: 0, 0.5, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000
--revenue-maxstringMax annual revenue in M USD: 0.5, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1000+
linkedin navigator company search --term "fintech" --sizes "11-50,51-200"
linkedin navigator company search --revenue-min 10 --revenue-max 100 --locations "United States" --json

Send a message via Sales Navigator (InMail).

linkedin navigator message send <person-url> <text> --subject <subject>
ArgRequiredDescription
person-urlyesLinkedIn profile URL of the recipient
textyesMessage text (up to 1900 characters)
FlagTypeRequiredDescription
--subjectstringyesMessage subject line (up to 80 characters)
linkedin navigator message send https://www.linkedin.com/in/vprudnikoff "Would love to chat about API integrations" --subject "Partnership Opportunity"

Get Sales Navigator conversation messages.

linkedin navigator message get <person-url> [flags]
ArgRequiredDescription
person-urlyesLinkedIn profile URL
FlagTypeDescription
--sincestringOnly retrieve messages since this ISO timestamp
linkedin navigator message get https://www.linkedin.com/in/vprudnikoff
linkedin navigator message get https://www.linkedin.com/in/vprudnikoff --since 2024-01-15T10:30:00Z

Custom Workflows

workflow run

Execute a custom workflow definition. Accepts JSON from a file or stdin.

linkedin workflow run [flags]
FlagTypeDescription
-f / --filestringPath to workflow JSON file
# From file
linkedin workflow run --file workflow.json

# From stdin
cat workflow.json | linkedin workflow run

# Inline
echo '{"actions":[...]}' | linkedin workflow run

See Building Workflows for the workflow JSON schema.

workflow status

Check status of a running workflow or wait for its completion. In-progress responses include status (pending or running) and message.

linkedin workflow status <id> [flags]
ArgRequiredDescription
idyesWorkflow ID
FlagTypeDescription
--waitbooleanBlock until the workflow completes
# Check current status
linkedin workflow status abc123

# Wait for completion
linkedin workflow status abc123 --wait --json

Account Management

account list

List all configured LinkedIn accounts.

linkedin account list

The active account is marked with *.

account update

Update tokens for a saved account. Useful when your tokens were regenerated on the dashboard and you need to refresh them in the CLI.

linkedin account update [name] [flags]
ArgRequiredDescription
namenoAccount name (case-insensitive substring match). Defaults to active account.
FlagTypeDescription
--linked-api-tokenstringNew Linked API Token (skips prompt)
--identification-tokenstringNew Identification Token (skips prompt)
# Update active account interactively
linkedin account update

# Update a specific account
linkedin account update "Vlad"

# Non-interactive (for scripts/CI)
linkedin account update --linked-api-token=xxx --identification-token=yyy

account switch

Switch the active LinkedIn account.

linkedin account switch <name>
ArgRequiredDescription
nameyesAccount name (case-insensitive substring match)
linkedin account switch "Vlad"

account rename

Rename a saved LinkedIn account.

linkedin account rename <name> --name <new-name>
ArgRequiredDescription
nameyesCurrent account name (case-insensitive substring match)
FlagTypeRequiredDescription
--namestringyesNew name for the account
linkedin account rename "Vlad" --name "My Work Account"

reset

Remove stored accounts and tokens.

linkedin reset [flags]
FlagTypeDescription
--allbooleanRemove all accounts (default: removes only active account)
# Remove active account (auto-switches to next)
linkedin reset

# Remove all accounts
linkedin reset --all

Output Format

JSON mode (--json or non-TTY stdout)

{"success": true, "data": {"name": "Vlad Prudnikov", "headline": "CEO at Linked API"}}
{"success": false, "error": {"type": "personNotFound", "message": "Person not found"}}

Human mode (TTY stdout)

Key-value pairs for objects, tables for arrays.

Exit Codes

CodeMeaning
0Success (check success field – action may have returned an error like "person not found")
1General/unexpected error
2Missing or invalid tokens
3Subscription/plan required
4LinkedIn account issue
5Invalid arguments
6Rate limited
7Network error
8Workflow timeout (workflowId returned for recovery)

Important Notes

  • Sequential execution. Linked API executes all workflows sequentially per account. You can send multiple requests, but they queue and run one at a time. This mirrors natural LinkedIn user behavior.
  • Not instant. Simple operations (fetch a profile) take ~10-20 seconds. Complex operations (search with filters) can take longer. This is because a real cloud browser navigates LinkedIn on your behalf.
  • Timestamps in UTC. All dates and times returned by the API are in UTC.
  • URL normalization. All LinkedIn URLs in responses are normalized to https://www.linkedin.com/... format without trailing slashes.
  • Null fields. Fields that are unavailable are returned as null or [], not omitted.
  • Action limits. Configurable per-account action limits on the platform prevent LinkedIn policy violations. When a limit is reached, you get a limitExceeded error.

See Core Concepts for more details.

For AI Agents

This CLI is designed for AI agent consumption:

  • --json flag gives structured output parseable with jq
  • Non-TTY stdout auto-switches to JSON
  • --quiet suppresses all stderr noise
  • --fields reduces output to only needed data
  • Exit code 0 always means "API call succeeded" – parse success field for action outcome
  • Non-zero exits = infrastructure errors (auth, network, etc.)

Example agent usage:

# Set up authentication
linkedin setup --linked-api-token=xxx --identification-token=yyy

# Fetch just name and headline
linkedin person fetch https://www.linkedin.com/in/vprudnikoff --json --fields name,headline -q

# Pipe to jq
linkedin person search --term "revops engineer" --json -q | jq '.data[].name'

This project is maintained by Linked API. The name "linkedin-cli" refers to the platform this tool is designed to work with, not to any affiliation or ownership.

Linked API is not affiliated, associated, authorized, endorsed by, or in any way officially connected with LinkedIn Corporation. "LinkedIn" is a registered trademark of LinkedIn Corporation.

License

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