---
name: career-now-job-hunt
description: >-
  Run an end-to-end tech job hunt using the career.now API: read the user's CV,
  search 280k+ fresh tech jobs with rich filters, pull full job details
  (including the external apply URL), rank matches against the user's profile,
  and hand back a shortlist with direct apply links. Use whenever the user wants
  to find, filter, compare, or apply to tech jobs.
license: MIT
---

# career.now job hunt

career.now is a live database of 280k+ fresh tech jobs aggregated from 600+ job
boards. This skill teaches you to search it, read full job details, match roles
to the user's own CV, and produce a ranked, apply-ready shortlist.

**The API is read-only.** You do not submit applications through it — each job
includes the external `url` on the original board, and that is where the user
(or you, if they ask) applies.

## Setup

You need a free API key. If `CAREERNOW_API_KEY` is not already in your
environment:

1. Ask the user to generate one at **https://career.now/byoa** (free, no card; the paid
   tier only raises rate limits).
2. Ask them to paste it back to you, **or** — preferably — to set it as the
   `CAREERNOW_API_KEY` environment variable themselves so you never handle the
   raw secret.
3. Treat the key as a secret: store it only in the environment or your MCP
   config, never echo it back, log it, or write it into files the user shares.

There are two ways to call the API — prefer MCP if it is installed.

### Option A — MCP (preferred)

If the `career-now` MCP server is connected, use its tools directly:

| Tool | Purpose |
| --- | --- |
| `search_jobs` | Search jobs with filters. Returns cards with a `token` + apply `url`. |
| `get_job` | Full detail for one job by `token` (responsibilities, skills, benefits, `url`). |
| `list_boards` | All indexed boards with live counts. |
| `get_profile` | The key owner's CV (markdown) + parsed profile. |
| `check_quota` | Current tier (free/paid) and remaining daily quota. |

Install (one-time, for the user):

```bash
claude mcp add career-now --env CAREERNOW_API_KEY=YOUR_KEY -- npx -y @careernow/mcp
```

### Option B — Raw REST

Every endpoint is JSON over HTTPS, authenticated with a bearer token:

```bash
curl "https://career.now/api/v1/jobs/search?q=rust&remote_type=remote&has_salary=true" \
  -H "Authorization: Bearer $CAREERNOW_API_KEY"
```

## Workflow

Follow this loop for a job hunt. Do not dump raw JSON at the user — synthesize.

1. **Know the candidate.** The user's CV is usually a file on their own machine —
   ask for the path and read it directly. (`get_profile` / `GET /api/v1/me` also
   returns any CV + parsed profile they've uploaded to career.now, but a local
   file is often more current.) Use the CV to pick search terms, seniority, and
   to judge fit later. If you can't find a CV, ask what they're looking for.
2. **Search.** Call `search_jobs` (REST: `GET /api/v1/jobs/search`) with tight
   filters drawn from the profile. Start specific; broaden only if results are
   thin. Each result has a `token`, a one-line `description_preview`, and the
   external apply `url`.
3. **Read the best candidates.** For the top ~3–8 results, call `get_job` (REST:
   `GET /api/v1/jobs/{token}`) to get the full description, responsibilities,
   required skills, and benefits. Never recommend a job from the preview alone.
4. **Rank against the CV.** Compare required skills and seniority to the user's
   actual experience. Flag strong matches, gaps, and dealbreakers honestly.
5. **Hand back a shortlist.** Present a ranked list: title, company, location /
   remote, salary if listed, a one-line "why it fits", and the apply `url`.

## Endpoint reference (REST)

All paths are under `https://career.now/api/v1` and require
`Authorization: Bearer $CAREERNOW_API_KEY`.

### `GET /jobs/search`

Query params (all optional except a query signal):

- `q` — free-text query, e.g. `senior rust backend` (min 2 chars unless `tags` given; max 200).
- `tags` — comma-separated tags AND-ed into the query.
- `remote_type` — comma-separated, e.g. `remote,hybrid`.
- `seniority` — comma-separated, e.g. `senior,lead`.
- `country` — comma-separated ISO codes, e.g. `US,DE`.
- `board` — comma-separated board keys (see `/boards`).
- `has_salary` — `true` to only return jobs with a listed salary.
- `sort` — `newest` (default), `relevant`, or `salary`.
- `page` — 1–3 (pagination is capped at 3 pages × 25 results).

Returns `{ results[], total, facets, page, page_size }`. Each result:
`{ token, title, company, location, remote_type, seniority, salary_raw, posted_at, url, board, description_preview, skills, score }`.

#### Worked search examples

These all return real, substantial result sets against the live index (counts
shift daily but the shape holds). Copy and adapt — don't invent filter values
the data doesn't have.

```bash
# Remote Rust roles that list a salary, highest-paying first
curl "https://career.now/api/v1/jobs/search?q=rust&remote_type=remote&has_salary=true&sort=salary" \
  -H "Authorization: Bearer $CAREERNOW_API_KEY"

# Senior React engineers (any location)
curl "https://career.now/api/v1/jobs/search?q=react&seniority=senior" \
  -H "Authorization: Bearer $CAREERNOW_API_KEY"

# Data-engineering roles in the US
curl "https://career.now/api/v1/jobs/search?q=data%20engineer&country=US" \
  -H "Authorization: Bearer $CAREERNOW_API_KEY"

# Backend roles in Germany, remote or hybrid, ranked by relevance
curl "https://career.now/api/v1/jobs/search?q=backend&country=DE&remote_type=remote,hybrid&sort=relevant" \
  -H "Authorization: Bearer $CAREERNOW_API_KEY"

# Broad sweep — Python, newest first (default sort) — when you want volume to filter yourself
curl "https://career.now/api/v1/jobs/search?q=python" \
  -H "Authorization: Bearer $CAREERNOW_API_KEY"
```

The MCP equivalents pass the same fields as arguments, e.g.
`search_jobs({ q: "rust", remote_type: "remote", has_salary: true, sort: "salary" })`.

**Filter values that exist in the data:**

- `remote_type`: `remote`, `hybrid`, `onsite` (most jobs; `unknown` also appears).
- `seniority`: `junior`, `mid`, `senior`, `lead`, `principal`.
- `country`: ISO codes — best-populated are `US`, `DE`, `IN`, `GB`, `FR`, `CA`, `BR`.
- `sort`: `newest` (default), `relevant`, `salary`.

Check the `facets` in any response to see which filter values actually have
counts before narrowing further.

### `GET /jobs/{token}`

Full detail for one job. `token` comes from a search result. Returns the rich
job object including the external apply `url`. 404 if the token is invalid or
the job is no longer fresh.

### `GET /boards`

`{ boards: [{ board, count }] }` — every indexed board with its live job count.

### `GET /me`

`{ email, cv_markdown, profile }` — the key owner's own data, read-only.

### `GET /me/quota`

`{ tier, quota: [{ endpoint, limit, used, remaining }] }`. Unmetered — safe to
call any time to check headroom.

## Rate limits

Limits are per endpoint per rolling 24h. Free tier: search 50, job 200, boards
30, me 50. Paid tier raises these ~20×. A `429` response (REST) or a "Rate
limit reached" error (MCP) means you've hit the cap — back off, tell the user,
and if there's a `Retry-After` hint, respect it. Don't hammer search to brute
through pages; refine the query instead.

## Good practice

- Search narrow, then widen — burning quota on broad queries is wasteful.
- Always `get_job` before recommending; previews omit dealbreakers.
- Be honest about fit. A short, accurate shortlist beats a long padded one.
- Surface the apply `url` for every recommendation so the user can act.
- The data is read-only and external — never claim you submitted an application
  unless the user explicitly drove an apply flow on the original board.
