Install
openclaw skills install @scavio-ai/scavio-linkedinPull LinkedIn person and company profiles, posts, contact info, company people and jobs, and search people, jobs, and posts as structured JSON. 14 endpoints for prospecting, recruiting, and market research.
openclaw skills install @scavio-ai/scavio-linkedinLook up LinkedIn people and companies, read their posts, pull public contact info, list a company's people and open jobs, get job and post details with comments, and search across people, jobs, and posts. All endpoints return structured JSON.
Use this skill when the user asks to:
Note: LinkedIn upstream can be slow and occasionally flaky. Set a client timeout of at least 60 seconds and be ready to retry.
Get a free API key at https://scavio.dev (50 free credits to get started, no card required):
export SCAVIO_API_KEY=sk_live_your_key
Every request is a POST with a JSON body and:
Authorization: Bearer $SCAVIO_API_KEY
Base URL: https://api.scavio.dev. All paths are under /api/v1/linkedin. Most endpoints cost 4 credits; the two company endpoints (/company and /company/posts) cost 1 credit.
| Endpoint | Credits | Description |
|---|---|---|
POST /api/v1/linkedin/person | 4 | Full profile for a member |
POST /api/v1/linkedin/person/about | 4 | About/overview metadata for a member |
POST /api/v1/linkedin/person/posts | 4 | A member's recent posts |
POST /api/v1/linkedin/person/contact | 4 | Public contact info for a member |
POST /api/v1/linkedin/company | 1 | Profile for a company |
POST /api/v1/linkedin/company/posts | 1 | A company's recent posts |
POST /api/v1/linkedin/company/people | 4 | People who work at a company |
POST /api/v1/linkedin/company/jobs | 4 | A company's open job listings |
POST /api/v1/linkedin/search/people | 4 | Search people by name, title, company, or school |
POST /api/v1/linkedin/search/jobs | 4 | Search jobs by keyword |
POST /api/v1/linkedin/search/posts | 4 | Search posts by keyword |
POST /api/v1/linkedin/job | 4 | Full details for a single job listing |
POST /api/v1/linkedin/post | 4 | Full details for a single post |
POST /api/v1/linkedin/post/comments | 4 | Comments on a post |
/linkedin/person with username (the vanity handle). The response includes a member urn./linkedin/person/about and /linkedin/person/posts accept either the urn or the username (username is resolved to a urn automatically). /linkedin/person/contact takes username./linkedin/company with company (a universal name / slug like microsoft, or a full LinkedIn company URL). Use /linkedin/company/posts for its posts./linkedin/company/people and /linkedin/company/jobs accept a numeric company_id, or a company slug/url that is resolved to a company_id automatically./linkedin/search/people (by search name plus optional title, company, school, location), /linkedin/search/jobs (search keyword), /linkedin/search/posts (search keyword)./linkedin/job with job_id, /linkedin/post with post_id, and /linkedin/post/comments with post_id.Paginated endpoints return next_cursor (or a page/has_more pair); pass cursor back for the next page.
/person)| Parameter | Type | Default | Description |
|---|---|---|---|
username | string | required | Public identifier (vanity handle), e.g. williamhgates |
include_experiences | bool | -- | Include work experience |
include_educations | bool | -- | Include education |
include_skills | bool | -- | Include skills |
include_certifications | bool | -- | Include certifications |
include_follower_and_connection | bool | -- | Include follower/connection counts |
/person/about) and person posts (/person/posts)| Parameter | Type | Default | Description |
|---|---|---|---|
urn | string | one of | Member urn |
username | string | one of | Public identifier; resolved to a urn if urn is omitted |
cursor | string | -- | (posts only) pagination cursor |
Provide urn or username.
/person/contact)username* — public identifier.
/company)company* — a company universal name (slug) or LinkedIn company URL.
/company/posts)| Parameter | Type | Default | Description |
|---|---|---|---|
company | string | required | Company slug or URL |
cursor | string | -- | Pagination cursor |
count | number | -- | Page size (1-100) |
/company/people) and company jobs (/company/jobs)| Parameter | Type | Default | Description |
|---|---|---|---|
company_id | string | one of | Numeric company id |
company | string | one of | Company slug/url; resolved to a company_id if company_id is omitted |
cursor | string | -- | Pagination cursor |
Provide company_id or company.
/search/people)| Parameter | Type | Default | Description |
|---|---|---|---|
search | string | one of | Name to search for |
title | string | -- | Job title filter |
company | string | -- | Company filter |
school | string | -- | School filter |
location | string | -- | A geo name or id filter |
cursor | string | -- | Page cursor (page number) |
Provide at least one of search, title, company, school.
/search/jobs)search* , plus optional cursor, date_posted, geocode, experience_level, remote, job_type.
/search/posts)search* , plus optional cursor, date_posted, sort_by, content_type.
/job)job_id* , include_skills (bool, optional).
/post)post_id* — a post id or activity urn.
/post/comments)| Parameter | Type | Default | Description |
|---|---|---|---|
post_id | string | required | Post id or activity urn |
cursor | string | -- | Pagination cursor |
sort_order | string | -- | relevance or recent |
post_type | string | -- | activity or ugc |
import os, requests
BASE = "https://api.scavio.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['SCAVIO_API_KEY']}"}
# 1. A person's profile (returns a urn)
person = requests.post(f"{BASE}/api/v1/linkedin/person", headers=HEADERS,
json={"username": "williamhgates"}).json()
urn = person["data"]["urn"]
# 2. Their recent posts (urn or username works)
posts = requests.post(f"{BASE}/api/v1/linkedin/person/posts", headers=HEADERS,
json={"urn": urn}).json()
# 3. Company profile (1 credit) then its open jobs
company = requests.post(f"{BASE}/api/v1/linkedin/company", headers=HEADERS,
json={"company": "microsoft"}).json()
jobs = requests.post(f"{BASE}/api/v1/linkedin/company/jobs", headers=HEADERS,
json={"company": "microsoft"}).json()
# 4. Search people by title + company
people = requests.post(f"{BASE}/api/v1/linkedin/search/people", headers=HEADERS,
json={"title": "data engineer", "company": "stripe"}).json()
Every response uses the envelope { data, response_time, credits_used, credits_remaining }. Key data fields per endpoint:
id, urn, public_identifier, first_name, last_name, full_name, headline, location, is_premium, is_open_to_work, is_hiring, avatar, about, experiences[], educations[], skills[], follower_count, connection_count.joined, contact_information, profile_photo.data[] (id, post_type, text, content{images,video,article,poll}, activity{num_likes,num_comments,num_shares}), next_cursor.data[] posts, next_cursor.people[] / data[] member items, next_cursor.jobs[] / data[] job items, next_cursor.page, total, has_more, data[] (id, urn, url, public_identifier, full_name, title, location, is_verified, is_premium, is_open_to_work, is_hiring, avatar).page, total, has_more, data[] job items.page, total, has_more, data[] (id, url, title, activity{num_likes,num_comments,num_shares}, created_at, author{name,description,url,avatar}).comments[] / data[] comment items, next_cursor.{
"data": {
"page": 1,
"total": 128,
"has_more": true,
"data": [
{
"id": "ACoAAA8BYqE",
"urn": "ACoAAA8BYqEBCGLg_vT_ca6mMEqkpp9nVffJ3hc",
"url": "https://www.linkedin.com/in/jane-dev/",
"public_identifier": "jane-dev",
"full_name": "Jane Dev",
"title": "Data Engineer at Stripe",
"location": "San Francisco Bay Area",
"is_verified": true,
"is_premium": false,
"is_open_to_work": false,
"is_hiring": false,
"avatar": "https://media.licdn.com/dms/image/..."
}
]
},
"credits_used": 4,
"credits_remaining": 996
}
/company and /company/posts cost 1 credit; every other LinkedIn endpoint costs 4 credits. Warn the user before paginating deeply./person returns the member urn — reuse it for /person/about and /person/posts to avoid re-resolving, though username also works./company/people and /company/jobs take a numeric company_id or a company slug/url that gets resolved automatically.400 means an invalid or missing parameter (e.g. no username/company_id) — fix and retry.401 means the API key is invalid or missing. Check SCAVIO_API_KEY.429 means rate or usage limit exceeded. Wait before retrying. See https://scavio.dev/docs/rate-limits.502 / 503 mean upstream is temporarily unavailable — LinkedIn upstream is flaky, so wait a few seconds and retry, up to a few times.SCAVIO_API_KEY is not set, prompt the user to export it before continuing.pip install langchain-scavio
from langchain_scavio import ScavioSearchTool
tool = ScavioSearchTool(engine="linkedin")