Skip to content
linkedin

v0.1.0

The first public release of linkedin: the full command surface, JSON-LD-first parsing, the guest job endpoints, a polite client, and the distribution artifacts.

The first public release. linkedin is a single pure-Go binary that turns public LinkedIn pages into structured records: fetch a member profile, a company page, or a job posting, search the jobs board, and save records to a local store. It talks to www.linkedin.com over plain HTTPS with no API key, so there is nothing to sign up for and nothing to pay for.

What you get

  • Fetch profiles and companies. profile reads public member profiles from the Person JSON-LD, with --posts and --articles for the member's recent posts and long-form articles. company reads company pages from the Organization JSON-LD plus the about panel: industry, size band, type, founding year, specialties, headquarters, follower count, and the funding round count with a Crunchbase link to the latest round. --posts collects recent company posts, --locations lists every office (with the primary one marking the headquarters), and --affiliated lists the related affiliated and showcase pages. --save upserts records into the store.
  • Read and search jobs. job fetches a single posting in full (title, company, location, applicant count, posting date, full description, and criteria), and jobs searches the board through the anonymous guest endpoint with filters for location, posting age, remote mode, experience, and job type. --hydrate follows each search stub to a full record.
  • Best-effort posts. post reads public posts and articles when it can, taking the real title from the JSON-LD and carrying the published and modified dates and the reaction and comment counts.
  • Classify and build URLs. id turns a slug, path, or URL into a (kind, id) pair without fetching, and url builds a canonical LinkedIn URL from a kind and an id.
  • Store and cache. db (path, count, query) inspects the local SQLite store, and cache (path, info, clear) manages the on-disk page cache.

JSON-LD-first parsing

linkedin reads the JSON-LD block a page ships for search engines first, because it is the cleanest source: schema.org Person on profiles, Organization on company pages, and DiscussionForumPosting for posts. When a page does not carry a field, it falls back to HTML selectors, so a record has real fields either way.

The guest job endpoints

Job search and detail use LinkedIn's guest endpoints (/jobs-guest/jobs/api/seeMoreJobPostings/search and /jobs-guest/jobs/api/jobPosting/<id>), which serve anonymous visitors. jobs paginates in pages of 25 until -n results or the endpoint runs dry. This is the reliable path for job data.

Honest about the wall

LinkedIn serves some surfaces to anonymous visitors and walls the rest behind a sign-in wall. Profile, company, and job pages return 200 and work reliably (the client sends no Referer, which avoids LinkedIn's HTTP 999 bot block), jobs search works through the guest endpoint, and single public posts and articles generally return data best effort. School pages stay walled (HTTP 999), the activity and /posts/ subpages redirect to a login, and people and company search require sign-in. When a page is walled, linkedin exits cleanly with code 5 and the hint suggests --cookies to lend a signed-in session. See troubleshooting.

The polite client

Responses are cached on disk, gzipped and content-addressed, so a repeat run does not re-fetch unchanged pages. linkedin is polite by default: a two second delay between requests and two workers. It backs off and retries on 429 and 5xx.

Output formats

Records render as a table on a terminal and JSONL when piped, with json, csv, tsv, url, and raw available too, plus --fields to narrow columns and --template for a custom line shape. Exit codes are stable, so scripts can branch on the outcome.

Install

go install github.com/tamnd/linkedin-cli/cmd/linkedin@latest

Prebuilt archives for Linux, macOS, Windows, and FreeBSD, plus Linux packages (deb, rpm, apk), SBOMs, and cosign-signed checksums, are on the release page. There is also a Homebrew cask and a Scoop entry:

brew install --cask tamnd/tap/linkedin

The multi-arch container image is on GHCR:

docker run --rm ghcr.io/tamnd/linkedin:0.1.0 company microsoft

The binary is pure Go (CGO_ENABLED=0) with no runtime dependencies.