LinkedIn Open Profile Status Scraper
Pricing
Pay per event + usage
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
Pay per event + usage
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
6
Total users
5
Monthly active users
2 days ago
Last modified
Categories
Share
Check which LinkedIn members are genuinely open to receiving messages from people outside their network (the Open Profile / free-InMail setting) and, separately, which ones publicly display the #OpenToWork badge. Every profile input produces one dataset record carrying two independent booleans, so no buyer ever mistakes one signal for the other.
| Field | Meaning | Resolvable without login? |
|---|---|---|
openProfile | Member accepts free InMail from non-connections (true / false / null = unknown) | For a definitive answer, yes — supply a li_at cookie; otherwise returns null |
openToWork | Public #OpenToWork badge on the profile (true / false / null) | Yes — read from the public profile page |
Most "open profile" checkers on the Store read the public #OpenToWork badge and call it "Open Profile." Those are different signals. This actor keeps them apart and reports each one honestly, including when the answer is genuinely unknown.
Best fit
Choose this actor when you need a per-person contactability verdict for sales outreach, recruiting, B2B lead enrichment, or AI-agent lead triage. It is designed for the person profile only and pairs cleanly with the linkedin-company-profile-scraper: start with the company actor to research accounts, then feed this actor the decision-makers' profile URLs to see who you can reach directly.
It also works as a focused standalone workflow on its own, with no companion actor required: pass vanity names or full URLs, get back a structured contactability + job-seeker verdict for each.
| Good for | Example |
|---|---|
| Sales outreach | Prioritize the prospects who can receive your message without a connection request or InMail credit |
| Recruiting | Find candidates open to recruiter messages and actively job-seeking |
| Lead enrichment | Add a contactable / openToWork column to your list before import into outreach software |
| AI-agent triage | A clean, structured per-profile verdict your agent can filter on |
Use this when
- You need a per-person contactability verdict (free-InMail
openProfile) and/or job-seeker flag (openToWork) for a bounded list of LinkedIn person profiles. - You are enriching a known lead/candidate list before outreach and want an honest
true/false/nullper record, withconfidenceandreasonyou can audit. - You have (or can obtain) your own
li_atcookie and need a definitive free-InMail answer.
When not to use this actor
- You need company / organization data — use linkedin-company-profile-scraper instead; this actor is person-only.
- You are crawling public LinkedIn search/feed surfaces at scale — this actor only resolves explicitly supplied person URLs or vanity names and is not a search engine.
- You need a definite true/false with no unknowns —
nullis an honest, expected outcome (see Boundaries below), and is documented behavior. - Your target data sits beyond what you are authorized to access, or at a scale beyond your rights — LinkedIn restricts bulk automated access.
Workflow: from lead list to outreach list
A realistic run looks like this. A sales team starts with a raw lead list of profile URLs, runs this actor to score each person's contactability and job-seeker flag, then exports the marked-up CSV from the dataset, and feeds that file into their outreach sequence. Details on the reviewer side use includeProfileBasics to keep name and headline alongside the boolean verdicts, and maxProfiles keeps the batch (and the bill) predictable.
Input
{"profiles": ["https://www.linkedin.com/in/elonmusk","satya-nadella","https://www.linkedin.com/in/tim-cook"],"maxProfiles": 100,"liAtCookie": "","includeProfileBasics": true,"includeRawData": false}
| Field | Type | Notes |
|---|---|---|
profiles | string array | Full profile URLs or bare vanity names. Required. |
maxProfiles | integer | 1–1000, default 100. Caps your spend. |
liAtCookie | string (secret) | Your own LinkedIn session cookie. Recommended for a definitive openProfile (free-InMail) answer. Without it, openProfile stays null and only the public signals are returned. |
includeProfileBasics | boolean | Attach name + headline. Default true. |
includeRawData | boolean | Attach compact raw source for debugging. Default false. |
Output
One dataset record per profile. Example:
{"profileUrl": "https://www.linkedin.com/in/elonmusk","vanityName": "elonmusk","name": "Elon Musk","headline": "CEO of X and SpaceX","openProfile": null,"openProfileConfidence": "unknown","openProfileReason": "Unauthenticated view - supply an li_at cookie for free-InMail (Open Profile) status.","openToWork": false,"openToWorkConfidence": "medium","openToWorkReason": "No public #OpenToWork badge signal found in a rendered profile view.","source": "owned","scrapeMethod": "owned-render","scrapedAt": "<run timestamp>"}
The default key-value store also receives RUN_SUMMARY and OUTPUT.
Reading the three states.
trueandfalseare definitive.nullis honest "unknown": foropenProfileit usually means the run had noli_atcookie (an unauthenticated view does not reveal message permissions), and foropenToWorkit means the profile page did not fully render. Each value ships with aconfidenceand areasonso downstream logic can decide how much weight to give it.
Pricing — Pay per event + platform usage
Charged per profile checked (each record saved to the dataset):
| Event | Price |
|---|---|
| Actor start | $0.00005 (once per run) |
| Profile checked | $0.0035 |
You also pay platform usage (compute + proxy) on top of the per-event charges.
Billing unit: one profile-checked event = one dataset record persisted = $0.0035, regardless of how that profile resolved (owned render, provider, or honest null — the charge covers the check itself, and the verdict may honestly be null).
Worked examples for a bounded run:
- 100 profiles → 100 records: 100 × $0.0035 = $0.35 in events (+ the one-time $0.00005 start event) plus platform usage.
- 500 profiles → 500 records (a typical monthly batch): 500 × $0.0035 = $1.75 in events plus platform usage.
Set maxProfiles (capped at 1,000) to keep the bill predictable, and check the live Pricing tab on the Actor page for the current platform-usage rates.
API example (curl)
curl "https://api.apify.com/v2/acts/khadinakbar~linkedin-open-profile-status-scraper/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"profiles": ["https://www.linkedin.com/in/satya-nadella", "tim-cook"],"maxProfiles": 50}'
Then read the run's default dataset for results — the Output tab provides ready-made export URLs. Each record keeps its source URL (provenance), confidence, and collection timestamp for audit trails.
AI agent / MCP prompt
To check LinkedIn contactability, for each
profilesentry returnopenProfile(accepts free InMail from non-connections; requires theli_atcookie to resolve, otherwisenull) andopenToWork(public #OpenToWork badge). Read the returned booleans from the default dataset, respect the per-recordconfidenceand provenancesource URL, and note the $0.0035 per-record cost plus platform usage before running at scale. Filter results onopenProfile=trueto prioritize outbound messages. Scope the run withmaxProfiles; the dataset holds one record per profile with no pagination needed.
Best results & practical guidance
- Provide a valid
li_atcookie from your own account. This is the single biggest accuracy lever — it turnsopenProfilefromnullinto a definitivetrue/false. - Pass vanity names alongside full URLs; both work.
- Keep batches moderate (dozens to a few hundred) and schedule recurring runs at low frequency for LinkedIn-heavy workloads.
- Treat
openToWork=falseas "badge not shown" and confirm directly — a job-seeker may hide the badge while still being open to outreach. - Validate output against the per-record
confidenceandreasonbefore feeding it into automated decisioning.
Boundaries, troubleshooting, and recovery
Honest scope of what this actor returns:
- Top-tier celebrity profiles sit behind LinkedIn's login wall. High-traffic profiles require an authenticated visitor, and managed providers return the same outcome — those records come back as honest
null/ unresolved. Everyday public profiles render directly and return realopenToWorkverdicts. openProfileneeds yourli_atcookie. An unauthenticated view never reveals message permissions, so without a cookie this field isnullby design. Supply a validli_atcookie from your own account to turn it intotrue/false.- Public renders are best-effort per profile. The actor renders through residential sessions and retries with fresh exits; when LinkedIn still challenges a specific profile, the record reports a truthful
nullinstead of guessing. - Recovery path: if a batch returns mostly
null, (1) add a validli_atcookie, (2) reduce batch size / setmaxProfiles, (3) retry after a cooldown, and (4) check theRUN_SUMMARYin the key-value store forunresolved/providerDetermined/privatelyDeterminedcounts before treating the run as complete.
Provenance & verification
Every run writes a RUN_SUMMARY (outcome, per-source counts, cost) to the key-value store, and each dataset record carries its source, scrapeMethod, confidence, reason, and collection timestamp. Release verification — validator output, canary run IDs, and per-build acceptance evidence — is maintained in the actor's audit log (release-evidence.json) rather than in this README, so public copy stays current while evidence stays precise. Re-verify against a fresh run before relying on results for a live campaign.
Builder's note
I built this actor after comparing store checkers that read the public #OpenToWork badge and label that person "Open Profile." I found that the genuine Open Profile signal — whether a member accepts free InMail from outside their network — only appears in an authenticated view; LinkedIn's Sales Navigator payload calls it openLink. So I designed this actor to return both signals as separate, honest three-state fields with a confidence and a reason on every value, and to charge only per profile record saved. Where the owned render is unavailable, it falls back to ScrapeCreators / SociaVault managed providers.
Responsible use: LinkedIn restricts bulk automated access. Use this tool for data you are authorized to access, at a scale you have rights to, and in line with LinkedIn's terms and applicable law.