OXYGENOxygen/ Docs
Providers

LinkedIn scraper

Read public LinkedIn data — profiles, companies, posts, engagers, jobs, ads — without connecting a LinkedIn account.

Oxygen ships a managed LinkedIn scraper. It reads public LinkedIn data through Oxygen's own infrastructure, so it needs no LinkedIn account, no cookie, and no browser extension — and it carries no risk to anyone's LinkedIn account. It is a paid provider read: you spend credits instead of account safety.

Every operation lives under the scraper. prefix in the provider catalog. Nothing to install or connect — if your workspace can spend credits, the scraper is already available.

oxygen tools search "public LinkedIn profile" --json
oxygen tools get scraper.linkedin_profile --json

The one decision that matters

Oxygen has two LinkedIn surfaces, and picking the wrong one is the only real mistake here.

What you want to readSurfaceWhy
Anyone's public profile, company, posts, or engagersscraper.* (this page)Cookieless and account-safe. Costs credits.
Your own connections, followers, profile viewers, inbox threadsConnected account (linkedin.*)Only your logged-in account can see these.
Sending — invites, DMs, comments, postsConnected account, approval-gatedWrites require an account. See Sequences.

The rule: third-party data goes through the scraper, always. Routing research through a connected account "because it's free" is exactly the behaviour that gets LinkedIn accounts restricted. Credits are the price of zero account risk.

What it can read

AreaOperations
People and companiesscraper.linkedin_profile, scraper.linkedin_company
Sourcing and searchscraper.linkedin_lead_search (Sales-Navigator-grade filters), scraper.linkedin_profile_search, scraper.linkedin_company_search, scraper.linkedin_service_search, scraper.linkedin_geo_id_search
Contentscraper.linkedin_profile_posts, scraper.linkedin_company_posts, scraper.linkedin_post, scraper.linkedin_post_search
Engagement (warm signals)scraper.linkedin_post_reactions, scraper.linkedin_post_comments, scraper.linkedin_comment_replies, scraper.linkedin_comment_reactions, scraper.linkedin_profile_reactions, scraper.linkedin_profile_comments
Jobsscraper.linkedin_job, scraper.linkedin_job_search
Adsscraper.linkedin_ad, scraper.linkedin_ad_search
Groupsscraper.linkedin_group, scraper.linkedin_group_search

linkedin_lead_search is the one people miss: company, title, seniority, industry, headcount, tenure, and "recently changed jobs" filters without a Sales Navigator seat. It also accepts a pasted Sales Navigator search URL. It is priced well above the other operations, so preview it before you lean on it.

The descriptor is always the authority — its input schema, when_to_use, output shape, pagination, and current price:

oxygen tools get scraper.linkedin_lead_search --json

This is a managed capability: Oxygen holds the upstream credential and bills you in credits. There is no BYOK option — you cannot supply your own scraping key for scraper.*.

Preview before you spend

Every operation has a free, page-bounded dry run. It returns a real price estimate for your exact request and proves no provider call happened (meta.provider_call: false).

# Free — estimates the live price, calls nothing.
oxygen tools run scraper.linkedin_post_reactions \
  --input-json '{"post":"https://www.linkedin.com/posts/example_activity-123","page":1}' \
  --mode dry_run --json

# Paid — only after you've read the estimate.
oxygen tools run scraper.linkedin_post_reactions \
  --input-json '{"post":"https://www.linkedin.com/posts/example_activity-123","page":1}' \
  --mode live --approved --max-credits <cap_from_the_dry_run> --json

--max-credits is a ceiling, not a charge — you pay for what actually runs, so over-reserving costs nothing and protects you from a pagination surprise.

One record vs. a whole table

Each call returns one page. Never try to drain a large post or search from a single synchronous call — fan it out through a run so pagination, retries, cost, and provenance stay inspectable.

ScopeUse
One known profile, company, or postoxygen tools run directly, as above
The same lookup across many rowsA tool column — one operation bound to one input column
All engagers on a post (reactors + commenters)oxygen engagement harvest --post <url> --source cookieless --max-credits N — a durable background harvest into a table
Multi-page or multi-source harvestsA workflow run

A tool column binds one operation to one input column:

oxygen columns add <table> --label "LI Profile" --kind tool --data-type jsonb \
  --definition-json '{"toolId":"scraper.linkedin_profile","inputMapping":{"url":{"type":"column","columnKey":"linkedin_url"}}}' --json

oxygen columns run <table> li_profile --limit 1 --json   # pilot one row, read the cell
oxygen columns run <table> li_profile --all --background --approved --max-credits <cap> --json

Always pilot with --limit 1 and inspect the cell before batching. Posts and engagement operations add a paid call per row, so scope them to a qualified shortlist rather than the whole table — see Columns for run conditions.

Cost

Scraper prices are runtime data that can change independently of any document, so this page deliberately quotes none. The authoritative sequence is always:

  1. oxygen tools get <tool_id> --json — the current per-request price.
  2. Dry-run one representative request — the estimate for your actual input shape.
  3. Multiply by eligible rows, add every selected column, and use that worst case as --max-credits.

Watch actual burn with oxygen billing usage --limit 20 --json. See Billing and Caps.

What it cannot do

  • Private data. No private profiles, no connection-gated fields, no one else's inbox.
  • Your own network. Connections, followers, and profile viewers are connected-account surfaces.
  • Writes. No invites, DMs, comments, or posts — the scraper only reads.
  • Guaranteed density. A person who rarely posts returns thin or empty results. That is the real answer, not a failure; re-running will not produce more.

If the scraper is unavailable, Oxygen surfaces the availability error rather than silently rerouting through another provider or spending a connected account's quota.

On this page