Now out of stealth: the missing link between AI agents and LinkedIn data.
All skills

Profile Scraper

extraction

Given one or more LinkedIn usernames, fetch full profile data — experience, education, skills, location, headline.

Endpoints it uses

  • /api/v1/profile/full10 credits/call

Ballpark: ~100 credits for 10 typical runs. Signup includes 300 free credits.

Run this skill

Download comes with your API key baked in — sign up (300 free credits, one minute) or open this skill in your dashboard.

What's inside (full preview)

---
name: linkedin-profile-scraper
description: Use when the user wants to extract full LinkedIn profile data (headline, positions, education, location) for one or more specific people they know by LinkedIn handle. Skill triggers on requests like "scrape this profile", "get full info on these people", "bulk profile pull".
---

# LinkedIn Profile Scraper (via Zooq)

You scrape full LinkedIn profile data via the Zooq API. Use this skill when the user provides one or more LinkedIn handles and wants the complete public profile.

## Inputs you need from the user

- **Handles**: one or more LinkedIn handles (the part after `linkedin.com/in/`). Don't accept full URLs; ask the user to strip them down to handles. Example: `satyanadella`, not `https://linkedin.com/in/satyanadella`.
- Alternatively, if the user already has a stable Zooq profile id (`prsn_...`), you can pass that instead of a handle — it never changes even if the person renames their profile.

## How to call

For each person, make a GET request. Pass **either** `handle=` **or** `id=` (not both):

```
GET https://zooq.dev/api/v1/profile/full?handle=<HANDLE>
Headers:
  X-API-Key: REPLACE_WITH_YOUR_KEY
```

By stable id instead:

```
GET https://zooq.dev/api/v1/profile/full?id=<prsn_...>
Headers:
  X-API-Key: REPLACE_WITH_YOUR_KEY
```

This call consumes Zooq credits. The user's current balance and per-call cost are visible at https://zooq.dev/dash. If you get HTTP 402, the user is out of credits — tell them to top up.

## Response shape

One call returns the complete profile record. Real fields (trimmed):

```json
{
  "success": true,
  "statusCode": 200,
  "message": "Profile retrieved successfully",
  "errors": null,
  "data": {
    "id": "prsn_pgvv42ri57uei",
    "url": "https://linkedin.com/in/satyanadella",
    "handle": "satyanadella",
    "first_name": "Satya",
    "last_name": "Nadella",
    "headline": "Chairman and CEO at Microsoft",
    "summary": "As chairman and CEO of Microsoft, I define my mission...",
    "is_creator": true,
    "is_premium": true,
    "is_influencer": true,
    "is_open_to_work": false,
    "is_hiring": false,
    "follower_count": 12087152,
    "connections_count": 831,
    "languages": [],
    "geo": { "city": "Redmond, Washington", "full": "Redmond, Washington, United States", "country": "United States", "countryCode": "us" },
    "geo_city": "Redmond, Washington",
    "geo_country": "United States",
    "geo_country_code": "us",
    "full_positions": [
      { "is_current": true, "title": "Chairman and CEO", "location": "...", "organization_name": "Microsoft", "organization_id": "org_jb3e59e3q21b8", "organization_slug": "microsoft", "organization_url": "https://www.linkedin.com/company/microsoft/", "organization_industry": "Computer Software", "organization_headcount_range": "10,001+ employees", "start": { "year": 2014, "month": 2 }, "end": null }
    ],
    "education": [
      { "institution_id": "inst_a8tl7ot52lsge", "school_name": "Manipal Institute of Technology, Manipal", "url": "...", "start": {}, "end": {} }
    ]
  }
}
```

Field notes:
- There is no `fullName` field — compose the display name from `first_name` + `last_name`.
- The bio lives in `summary` (not `about`).
- Work history is `full_positions[]`; each entry carries `title`, `organization_name`, `organization_slug`, `organization_industry`, and `start`/`end` objects shaped `{ year, month }` (`end` is `null` for the current role).
- `education[]` entries carry `school_name` and `institution_id`. Some profiles omit degree/field.
- Location is available both as the nested `geo` object and flattened `geo_city` / `geo_country` / `geo_country_code`.

On failure, `success` is `false`, `data` is `null`, and `message` carries the reason (e.g. `"Profile not found"` with `statusCode: 404` for a handle that doesn't exist). Do not retry beyond 2 attempts (the Zooq proxy already retries upstream once).

## Behavior

1. Confirm with the user how many profiles they want scraped and that they have enough credits — they can check their balance at https://zooq.dev/dash.
2. Call the endpoint per handle, sequentially. Don't fire all in parallel without asking — bulk usage burns credits fast.
3. Return a clean structured summary, NOT a raw JSON dump. Group by profile, highlight the headline + current role (first `full_positions` entry where `is_current` is true) + location.
4. If a user requests it as CSV, format the `full_positions`/`education` arrays as joined strings.

## Don't do

- Don't claim a profile exists if the API returned `success: false`. Surface the `message`.
- Don't infer fields the API didn't return. Email and phone are not exposed by this API — don't promise them.
- Don't store API keys in code you write back to the user. The key is already configured for you in this skill file.