---
name: jobherder-paid-search
description: Register for a Jobherder API key, pay for a full search (7 roles, about an hour) or a quick match (1 role, minutes, USDC only), submit a CV and preferences, poll for matches, and receive tailored PDFs by email.
---

# Jobherder paid search

Use this skill when a user wants Jobherder to run a paid job search via the Agent API.

**Searches are paid only. There are no free runs, no trial, and no free first search.** Every search consumes exactly one paid credit. Credits do not expire.

## Prerequisites

- User email (delivery + account; must match `cfg_email` on each search)
- CV file (pdf/docx/doc/txt, max 10MB)
- Preference answers (location, remote/hybrid, regions, seniority, industries)
- Payment for credits, by Stripe Checkout or x402 (no credits are granted at registration)

## Two products

| | Full search | Quick match |
|---|---|---|
| Endpoint | `POST /api/v1/searches` | `POST /api/v1/quick-searches` |
| You get | 7 matched roles | the single best current role |
| Per role | tailored CV + cover letter | tailored CV + cover letter |
| Typical time | about an hour | 3 to 8 minutes (up to 15 for a heavily searched profile) |
| Paid with | card or USDC | USDC only |

Choose the quick match when the user wants one good answer now, and the full
search when they want a shortlist. Status for both is read from
`GET /api/v1/searches?run_id=…`.

## Credit packs

| Pack | Buys | Credits | Price | x402 (USDC) | Notes |
|---|---|---|---|---|---|
| `pack1` | full search | 1 | EUR 9.99 | 11.50 | Single search |
| `pack3` | full search | 3 | EUR 24.99 | 28.75 | **Best value** (recommended default) |
| `quick1` | quick match | 1 | — | 2.50 | Agent-only; no card price |

Credits are per product: a quick credit cannot pay for a full search. Each
endpoint accepts only its own price, so paying 2.50 at `/api/v1/searches` is
refused rather than credited.

## Paying with x402

If you can sign x402 payments, skip Stripe: the 402 from `POST /api/v1/searches`
carries a challenge in the base64 `PAYMENT-REQUIRED` header (protocol v2) and in
the body under `accepts` (v1). Retry with `PAYMENT-SIGNATURE` (v2) or `X-PAYMENT`
(v1); credits are added once settlement confirms, and a receipt comes back in
`PAYMENT-RESPONSE`. Send the same header to `POST /api/v1/checkout` to top up
without starting a search. An API key is still required. x402 settles on Base
mainnet in USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`).

## MCP

The same service is available as MCP tools over Streamable HTTP at
`https://jobherder.com/mcp`: `get_pricing`, `register_agent`, `start_job_search`,
`quick_job_search`, `get_search_status`. Send the API key as a bearer token on
the connection.
Prefer this over raw HTTP if your client speaks MCP.

Payment works inside MCP too. With no credit, `start_job_search` and
`quick_job_search` return `isError: true` carrying the x402 `PaymentRequired`
object in `structuredContent` (resource `mcp://tool/<tool name>`, quoting only
that tool's price). Sign the EIP-3009 authorization and
retry the identical call with the payload in `_meta["x402/payment"]`; the search
starts on settlement and the receipt arrives in `_meta["x402/payment-response"]`.

## Procedure

1. Discover: `GET https://jobherder.com/.well-known/oauth-protected-resource` then `GET https://jobherder.com/.well-known/oauth-authorization-server` and read `agent_auth`.
2. Register: `POST https://jobherder.com/api/v1/register` with `{"email","name"}` — store `api_key` once. Returns **0 credits**. If the email is already a Jobherder web account, you get **409** with `owner_action_url` — ask the person to sign in, create a key on their dashboard, and paste it back to you.
3. Buy credits: `POST https://jobherder.com/api/v1/checkout` with `Authorization: Bearer <api_key>` and body `{"pack":"pack3"}` (default when body omitted) — open `checkout_url` for the human to pay. Promotion codes are not accepted.
4. Confirm credits: `GET https://jobherder.com/api/v1/checkout` until `credits_available > 0`, or `GET https://jobherder.com/api/v1/checkout/success?session_id=…` if the webhook is delayed.
5. Start search: `POST https://jobherder.com/api/v1/searches` as JSON `{"profile":…, "cv_json":…}` or as multipart `profile` + `cv` (`cfg_email` must match registration). See step 7 for the CV formats. Optional `Idempotency-Key` header prevents double-charging on retry. Returns **402** when balance is zero. For a quick match, post the identical body to `POST https://jobherder.com/api/v1/quick-searches` instead; steps 3 and 4 do not apply, since it is paid in USDC inline.
6. Poll: `GET https://jobherder.com/api/v1/searches?run_id=…` until `run.terminal` is true — read `matches` on success (each has `title`, `company`, `url`, `score`, `rank`, `source`, `match_reason`). `run.target_jobs` says how many that run delivers (7 or 1); do not assume. Only one search may run at a time; a second start returns **429** until the first finishes.
7. CV input: send `cv_json` in the JSON Resume schema (jsonresume.org) if you hold the CV as data, or `cv_base64` with `cv_type` of `pdf`, `docx` or `txt`. You never need to render a PDF.
8. Documents: every match carries `documents.cv_markdown` and `documents.cover_letter_markdown`, written for that specific role. The same documents are emailed as PDFs.

Full protocol: https://jobherder.com/auth.md  
OpenAPI: https://jobherder.com/openapi.json  
Overview: https://jobherder.com/agents
