Skip to main content

Minimal CLI for publishing LinkedIn text posts with the Posts API

Project description

lkdn

Small CLI for supported LinkedIn API workflows.

Scope

This project is intentionally narrow:

  • publish a text post as a member or organization
  • publish an image post as a member or organization
  • publish a video post as a member or organization
  • read employment data from official LinkedIn profile APIs when your app tier and scopes allow it
  • use the current LinkedIn Posts API
  • stay easy to read and easy to fork

It does not try to automate OAuth in a fragile way. You bring your own access token and author URN. It does not scrape LinkedIn pages or rely on undocumented web endpoints.

Install

uv sync

PyPI distribution: lkdn

Command aliases:

  • licli
  • lkdn
  • linkedin

Usage

Set the required environment variables:

export LINKEDIN_ACCESS_TOKEN="..."
export LINKEDIN_AUTHOR_URN="urn:li:person:YOUR_ID"
export LINKEDIN_API_VERSION="YYYYMM"

Then publish a post:

uv run licli post "Hello from the new Posts API"

Publish a post with an image:

uv run licli post \
  --image /absolute/path/to/banner.png \
  --alt-text "Bitdevs BSB event banner" \
  "Hello from the new Posts API"

Publish a post with a video:

uv run licli post \
  --video /absolute/path/to/clip.mp4 \
  --video-title "Linus on abstraction" \
  "Hello from the new Posts API"

You can also pass values as flags:

uv run licli post \
  --access-token "..." \
  --author "urn:li:person:YOUR_ID" \
  --api-version "YYYYMM" \
  "Shipping a tiny CLI."

Read employment data through official profile APIs:

uv run licli profile employment-history

Use the Verified on LinkedIn identityMe endpoint instead:

uv run licli profile employment-history --source identity-me

Limit output to a different lookback window:

uv run licli profile employment-history --years 3

Docs

LinkedIn requirements

According to the official LinkedIn docs, posting on behalf of a member requires:

  • OAuth 2.0 member authentication
  • the w_member_social scope
  • a valid Linkedin-Version header in YYYYMM format

For image posts, this project uses LinkedIn's Images API to initialize an upload, uploads the binary to the returned uploadUrl, and then creates the post with the returned urn:li:image:....

For video posts, this project uses LinkedIn's Videos API to initialize the upload, uploads each instructed part, finalizes the upload, waits for the asset to become AVAILABLE, and then creates the post with the returned urn:li:video:....

For employment data, the official API surface is constrained:

  • GET /rest/identityMe can return only the member's current position, and only on the Plus tier with the r_primary_current_experience scope.
  • positions on the Profile API are part of the older r_fullprofile permission set, and LinkedIn documents that access to r_fullprofile is closed.
  • This means profile employment-history is only useful if your app already has the required restricted profile access; otherwise LinkedIn will return limited data or a permission error.

Official docs:

Development

Run tests:

uv run pytest

Run lint:

uv run ruff check

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lkdn-0.1.1.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lkdn-0.1.1-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file lkdn-0.1.1.tar.gz.

File metadata

  • Download URL: lkdn-0.1.1.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lkdn-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cfbac6a6c789f96212514ad1c88190db7c6913c0419e1933cc7a9dd43571eaa5
MD5 3d04cbae8d6a5809e83aec220ac584bf
BLAKE2b-256 136c618169f0bc349bbd6194b1d6c343e3c68c95880ed2de27dea15eaa0607a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for lkdn-0.1.1.tar.gz:

Publisher: release.yml on brenorb/linkedin-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lkdn-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: lkdn-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lkdn-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8e810cdee42a331e8bfb5b80e830b78429aef9203570caa78e2b1bf881320224
MD5 7e180cef1fa6f87b30b6606b1d0cfd1f
BLAKE2b-256 38d2bdc7c2b1a72e7e643a79e35446d02c2e1ed64384a03f260b265ce15ff86d

See more details on using hashes here.

Provenance

The following attestation bundles were made for lkdn-0.1.1-py3-none-any.whl:

Publisher: release.yml on brenorb/linkedin-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page