LinkedIn Open Profile Status Scraper
Pricing
from $3.50 / 1,000 profile checkeds
LinkedIn Open Profile Status Scraper
Check which LinkedIn members accept free InMail from non-connections (Open Profile) and who publicly shows the #OpenToWork badge. Pass profile URLs or vanity names; get honest true/false/null verdicts per member with confidence and reason. Charged per profile checked plus platform usage.
Pricing
from $3.50 / 1,000 profile checkeds
Rating
1.0
(1)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
24
Total users
7
Monthly active users
13 hours
Issues response
7 days ago
Last modified
Categories
Share
What is LinkedIn Open Profile Status Scraper?
LinkedIn Open Profile Status Scraper checks a list of LinkedIn person profiles and returns one dataset row per member with two separate signals: openProfile (the member accepts free InMail from people outside their network) and openToWork (the member publicly shows the #OpenToWork badge). Each signal comes with a true, false or null verdict plus a confidence level and a plain-language reason. Sales teams, recruiters, lead-enrichment pipelines and AI agents use it to decide who they can message directly before they spend InMail credits or connection requests.
Why two signals instead of one
Many tools treat the #OpenToWork badge as "Open Profile". They are different settings that answer different questions:
| Field | Question it answers | Typical use |
|---|---|---|
openProfile | Can a non-connection send this member a free InMail? | Outbound sales and recruiter outreach |
openToWork | Does the member publicly show the #OpenToWork badge? | Candidate sourcing and job-seeker signals |
Every verdict ships with ...Confidence (high, medium, low, unknown) and ...Reason, so your filters can weigh a confident false differently from an honest null.
Best fit for this Actor
- Designed for bounded lists of LinkedIn person profiles you already have: a prospect list, a candidate shortlist or a CRM export.
- Best fit for a contactability column before outreach: keep
openProfile: truerows for a direct-message sequence, route the rest to connection requests. - Works with full profile URLs and bare vanity names in the same list.
- When you still need the profile list itself, start with LinkedIn People Search Scraper, then pass the profile URLs into
profileshere. - When you want an email address for members who stay closed to free InMail, continue with LinkedIn Email Finder for that subset.
Example workflow: from a lead list to a prioritized outreach list
A sales development rep starts with 80 decision-makers exported from a CRM. She pastes the profile URLs into profiles, keeps includeProfileBasics on so each row carries the name and headline, and sets maxProfiles to 80 to cap spend. The dataset returns one row per person. She filters openProfile = true with high confidence into a free-InMail sequence, sends the false rows to a connection-request cadence, and keeps openToWork = true rows aside for the recruiting team. She then schedules the same list monthly to compare how settings change over time and exports each result to CSV for the CRM.
Input
{"profiles": ["https://www.linkedin.com/in/reidhoffman","satyanadella","https://linkedin.com/in/adamgrant/"],"maxProfiles": 100,"includeProfileBasics": true,"includeRawData": false}
| Field | Type | What it controls |
|---|---|---|
profiles | array of strings | Required. Full LinkedIn person profile URLs or vanity names such as satyanadella. |
maxProfiles | integer | Cap on profiles checked in this run, 1 to 1000. Default 100. |
liAtCookie | string (secret) | Optional li_at value from your own LinkedIn session for an authenticated Open Profile check. Paste the value only. |
includeProfileBasics | boolean | Attach public name and headline. Default true, with no extra charge. |
includeRawData | boolean | Attach a compact rawData payload for custom parsing. Default false. |
Output
One dataset row per profile you submit.
| Field | What it contains |
|---|---|
inputUrl, profileUrl, vanityName | The value you sent and the normalized profile URL and vanity name |
name, headline | Public name and headline text (with includeProfileBasics) |
openProfile | true, false or null for the free-InMail (Open Profile) setting |
openProfileConfidence, openProfileReason | How sure the verdict is and how it was reached |
openToWork | true, false or null for the public #OpenToWork badge |
openToWorkConfidence, openToWorkReason | How sure the verdict is and how it was reached |
source, scrapeMethod | Which collection path produced the row, for provenance |
scrapedAt | Collection time in ISO 8601 |
{"inputUrl": "https://www.linkedin.com/in/reidhoffman","profileUrl": "https://www.linkedin.com/in/reidhoffman","vanityName": "reidhoffman","name": "Reid Hoffman - Co-Founder, LinkedIn, Manas AI & Inflection AI.","headline": "Co-Founder, LinkedIn, Manas AI & Inflection AI. Founding Team, PayPal. Author of Superagency.","openProfile": false,"openProfileConfidence": "high","openProfileReason": "Determined by a dedicated Open Profile status checker.","openToWork": false,"openToWorkConfidence": "medium","openToWorkReason": "No public #OpenToWork badge signal found in a rendered profile view.","source": "owned","scrapeMethod": "owned-render","scrapedAt": "2026-10-01T19:53:32.682Z"}
Reading the three states: true and false are definitive answers. null means the signal stayed unknown for that profile, and the matching ...Reason field says why. Each run also writes OUTPUT and RUN_SUMMARY records to the default key-value store with the run outcome and per-source counts.
Pricing
This Actor uses Pay per event plus Apify platform usage. The events are:
- Actor Start, charged once when the run starts.
- Profile checked, charged for each profile row where
openProfileoropenToWorkresolves totrueorfalse. Rows where both staynullremain in the dataset for transparency and are not billed.
Worked example: a list of 50 profiles where 46 resolve at least one signal costs one Actor Start event plus 46 Profile checked events, plus the compute used by the run. Set maxProfiles to cap the batch, and check the live Pricing tab on this page for current event prices.
API example
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~linkedin-open-profile-status-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"profiles": ["https://www.linkedin.com/in/reidhoffman", "satyanadella"], "maxProfiles": 10}'
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("khadinakbar/linkedin-open-profile-status-scraper").call(run_input={"profiles": ["https://www.linkedin.com/in/reidhoffman", "satyanadella"], "maxProfiles": 10})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row.get("openProfile") is True:print(row["profileUrl"], row["openProfileConfidence"])
Use it with AI agents (MCP)
Connect the Actor to Claude, ChatGPT, Cursor or another MCP client through Apify MCP, then ask:
Check these 20 LinkedIn profiles for Open Profile and #OpenToWork status. Return a table of profile URL, openProfile, openToWork and both confidence levels, and list the members I can InMail for free.
What the agent gets back: one row per profile with both verdicts, confidence and reason, read from the run's dataset with get-dataset-items. The agent can quote profileUrl and scrapedAt as provenance and read OUTPUT for the run outcome. Cost scales with resolved profiles, so a scoped maxProfiles keeps agent-driven spend predictable.
Best results
| Starting situation | Helpful action | Expected outcome |
|---|---|---|
| A CRM export of profile URLs | Paste URLs directly; trailing slashes and linkedin.com without www are fine | Clean, normalized profileUrl per row |
| You want a definitive Open Profile answer on more rows | Add your own li_at value in liAtCookie | More openProfile rows resolve with an authenticated view |
| A large list | Split into batches of a few hundred and schedule them | Predictable runs and spend |
| A downstream outreach filter | Filter on verdict and confidence together, such as openProfile = true with high confidence | Higher-quality direct-message lists |
| Leaner rows for a database | Set includeProfileBasics to false | Status-only records |
Builder's note
I built this after noticing how often the #OpenToWork badge gets sold as "Open Profile", even though one is about job seeking and the other is about who may message you. I designed every row to carry both signals side by side, each with its own confidence and reason, so a downstream filter or an AI agent can decide how much weight to give a verdict. Billing follows resolved verdicts, which keeps an unknown row informative without making it a charge.
FAQ
Do I need a LinkedIn account?
The Actor works from public profile data and a dedicated status check. Adding your own li_at value is optional and helps resolve more openProfile verdicts with an authenticated view.
Can I check company pages?
This Actor is designed for person profiles. For organizations, use LinkedIn Company Profile Scraper instead.
What does null mean?
The signal stayed unknown for that profile. The ...Reason field explains how the check ended, and the row is kept in the dataset free of charge.
Responsible use
This Actor reads publicly visible LinkedIn profile signals for profiles you supply. Profile data is personal data under laws such as the GDPR and CCPA, so collect and use it with a lawful basis, honor opt-outs, and respect LinkedIn's terms. LinkedIn is a trademark of its owner, and this independent Actor is not affiliated with or endorsed by LinkedIn. For questions, open a ticket in the Issues tab.