Hand the agent your own LinkedIn handle and it returns open roles matching your background — title, skills, and location pulled from your profile, scored against current openings. Built for job-seekers (and their agents) doing targeted search.
/api/v1/profile/full10 credits/call/api/v1/search/jobs10 credits/call/api/v1/jobs/details-v210 credits/callBallpark: ~300 credits for 10 typical runs. Signup includes 300 free credits.
Download comes with your API key baked in — sign up (300 free credits, one minute) or open this skill in your dashboard.
---
name: linkedin-find-me-a-job
description: Use when a user (or their agent) wants to find open jobs that match their own LinkedIn profile. Triggers on requests like "find me a job", "what jobs match my profile", "show me roles like mine in <city>", "open positions for my background", "job search based on my LinkedIn". Returns a ranked list of open jobs with title, company, location, and apply URL.
---
# LinkedIn Find Me a Job (via Zooq)
You find open jobs that match a user's own LinkedIn profile. Starts from the user's LinkedIn handle, builds a search vector from their most recent role + key skills, queries LinkedIn's job index via Zooq, and returns ranked matches.
## Inputs you need from the user
- **Handle**: the user's own LinkedIn handle (the part after `linkedin.com/in/`). Example: `satyanadella`.
- **Target location** (optional): city, state, or country. If not provided, default to the location on the user's current LinkedIn profile. If the user says "remote", pass `workplaceTypes=remote` instead of a location string (see step 3).
- **Seniority filter** (optional, default same-as-current): same / one-level-up / any. Maps to the `experience` filter in step 3.
- **Max jobs** (optional, default 25): cap on results returned.
## How to call
This skill uses 2-3 Zooq endpoints (each call consumes Zooq credits — see https://zooq.dev/dash for the user's current balance and per-call cost):
1. **Pull the user's full profile** — one call returns the complete record:
```
GET https://zooq.dev/api/v1/profile/full?handle=<USER_HANDLE>
Headers:
X-API-Key: REPLACE_WITH_YOUR_KEY
```
Extract from `data`:
- Current **title** → `full_positions[]` → the entry with `is_current: true` → its `title`.
- Top **skills** → `skills[]` → take the first ~5 `skills[].name` values.
- **Location** → `geo_city` and `geo_country_code` (also available as `geo.city` / `geo.country`). Use if the user didn't give a target location.
2. **Search jobs** — returns up to ~25 jobs per page:
```
GET https://zooq.dev/api/v1/search/jobs?keyword=<TITLE>&count=25&start=0
Headers:
X-API-Key: REPLACE_WITH_YOUR_KEY
```
Param notes (these are the current names — do NOT use the old `location`/`start=0`-only shape):
- `keyword`: build from the user's current title. If results are sparse, broaden by stripping the seniority prefix (e.g. "Senior Backend Engineer" → "Backend Engineer").
- **`locations` works — pass a LinkedIn geo id.** Not free text: a place name like "Israel" is ignored and you get unfiltered global results. Find the id by typing the place into the location box on LinkedIn search, picking the auto-complete match, pressing enter, and reading `geoId=` out of the address bar. Example: Tel Aviv-Yafo = `101570771`.
- **Use a CITY id, not a country id.** The match is EXACT, and postings are tagged with the exact city — so Tel Aviv-Yafo (`101570771`) returns results where Israel (`101620260`) returns zero. If a search comes back empty, that is the first thing to check: re-run with the city id, or drop `locations` and post-filter on `data.jobs[].location`.
- Because it is an exact match, a job you can see on LinkedIn may not appear here — LinkedIn also shows nearby locations, this does not. Tell the user that rather than concluding there are no jobs.
- `locations` combines fine with `keyword`, `experience`, `workplaceTypes` and `datePosted`. A very specific multi-word `keyword` can still narrow it to nothing — broaden it (e.g. "software engineer" to "engineer") before assuming the location is wrong.
- **Filtering by title: use `keyword`, not `titles`.** `titles` takes ids too and rejects free text with the same 422 (no credits charged).
- `workplaceTypes`: for a remote search pass `workplaceTypes=remote` (accepted: `onsite`, `remote`, `hybrid`). Prefer this over a location string when the user says "remote".
- `experience` (optional seniority): `internship`, `entry_level`, `associate`, `mid_senior`, `director`, `executive` (comma-separate for multiple).
- `count`: results per page, 0-50 (default 25). `start`: pagination offset, 0-999.
Each result: `data.jobs[]` with `id` (the posting id — feed this to step 3), `url` (apply URL), `title`, `organizationName`, `location`, `listedAt` (epoch milliseconds — divide by 1000 and format as a date for the "Posted" column). Total available in `data.total`.
3. **(Optional) Enrich top picks** — only the top 3-5:
```
GET https://zooq.dev/api/v1/jobs/details-v2?opportunityEntityId=<JOB_ID>
Headers:
X-API-Key: REPLACE_WITH_YOUR_KEY
```
`<JOB_ID>` is `data.jobs[].id` from step 2. Pulls the full description + requirements. Response is nested: read `data.jobDetails` (title, `description`, `applyUrl`, `employmentStatus`, `functions`), `data.organization`, and `data.location`. Use this for jobs you intend to recommend strongly.
## Matching algorithm
Compute a 0-100 match score per job:
1. **Title similarity (50 points):** exact match → 50, same role family / level → 35, related role → 20, weak match → 0. Use the user's current title from step 1 as the anchor.
2. **Skill keyword overlap (30 points):** count the user's top-5 skills that appear in the job title or (if enriched) description; each match = 6 points (cap 30).
3. **Location preference (20 points):** exact target location → 20, same metro → 12, same country → 6, remote when remote requested → 20.
Filter out jobs scoring under 30 unless the user has fewer than 5 results — then show the next-best.
## API-call ballparks
Count of API calls per run shape (NOT credit cost — multiply by current per-call rate from the Zooq dashboard):
- **Lean** (1 page, no enrich): ~2 calls
- **Standard** (1 page + enrich top 5): ~7 calls
- **Wide search** (3 pages + enrich top 5): ~9-11 calls
Always tell the user roughly how many calls a run will make and confirm before kicking it off.
## Output format
Sorted by match score descending, render as Markdown:
```
| # | Job | Company | Location | Posted | Match | Apply |
|---|---|---|---|---|---|---|
| 1 | Senior Backend Engineer | Stripe | San Francisco | 2026-05-12 | 92 | [Apply](https://www.linkedin.com/jobs/view/...) |
| 2 | Staff Software Engineer | Anthropic | Remote | 2026-05-15 | 88 | [Apply](https://www.linkedin.com/jobs/view/...) |
```
The "Apply" link is `data.jobs[].url` from step 2 (or `data.jobDetails.applyUrl` if you enriched). After the table, write 2-3 sentences:
- Which 1-2 jobs you'd prioritize and why (use the enriched details if you fetched them).
- Common gaps between the user's profile and the listings (skills that come up repeatedly that the user is missing).
## Don't do
- **Don't fabricate jobs.** If the search returns zero results, say so — suggest broader keywords, dropping the location filter, or a different region. Don't invent placeholder rows.
- **Don't treat a location 422 as "no jobs".** It means the location string didn't resolve — broaden it or drop it (see step 2), then re-run.
- **Don't extract or store contact information** from job postings beyond the public apply URL.
- **Don't apply to jobs on the user's behalf.** This skill ends at "here are the matches" — application is a manual step.
- **Don't recommend jobs you scored below 30** unless the user has fewer than 5 above the threshold; flag them as "weaker matches" if you must include them.
- **Don't share the API key** in any code or output back to the user. It's already configured in this skill file.
## On rate limits and refunds
- HTTP 429 → wait 30 seconds, retry once.
- HTTP 5xx → Zooq auto-refunds; surface the error, don't retry beyond what the user approved.
- HTTP 402 → user is out of credits. Direct them to https://zooq.dev/dash/billing.