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 --jsonThe one decision that matters
Oxygen has two LinkedIn surfaces, and picking the wrong one is the only real mistake here.
| What you want to read | Surface | Why |
|---|---|---|
| Anyone's public profile, company, posts, or engagers | scraper.* (this page) | Cookieless and account-safe. Costs credits. |
| Your own connections, followers, profile viewers, inbox threads | Connected account (linkedin.*) | Only your logged-in account can see these. |
| Sending — invites, DMs, comments, posts | Connected account, approval-gated | Writes 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
| Area | Operations |
|---|---|
| People and companies | scraper.linkedin_profile, scraper.linkedin_company |
| Sourcing and search | scraper.linkedin_lead_search (Sales-Navigator-grade filters), scraper.linkedin_profile_search, scraper.linkedin_company_search, scraper.linkedin_service_search, scraper.linkedin_geo_id_search |
| Content | scraper.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 |
| Jobs | scraper.linkedin_job, scraper.linkedin_job_search |
| Ads | scraper.linkedin_ad, scraper.linkedin_ad_search |
| Groups | scraper.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 --jsonThis 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.
| Scope | Use |
|---|---|
| One known profile, company, or post | oxygen tools run directly, as above |
| The same lookup across many rows | A 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 harvests | A 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> --jsonAlways 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:
oxygen tools get <tool_id> --json— the current per-request price.- Dry-run one representative request — the estimate for your actual input shape.
- 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.
Related
- Managed LinkedIn Scraper — the integration overview, with every operation listed
- Provider catalog — how operations, prices, and availability are exposed
- Columns — tool columns, run conditions, provenance
- Approvals — why live provider reads need an explicit cap
- LinkedIn research pack — the end-to-end recipe your agent can follow