docs platform
SDKs and n8n
Generated TypeScript and Python clients and the n8n node.
The TypeScript and Python clients and the n8n node are generated from the same openapi.yaml that renders the API reference. When the API gains an operation, the clients gain a method in the same release. They are not on npm or PyPI yet; install them from the sdks/ folder of the repository.
| Package | Install | Runtime |
|---|---|---|
@recruitmcp/sdk | npm install ./sdks/typescript | Node 18+, Deno, Bun, browsers, edge. No dependencies |
recruitmcp | pip install ./sdks/python | Python 3.9+. Standard library only |
n8n-nodes-recruitmcp | Build and link into ~/.n8n/custom | n8n 1.x. Scaffold |
TypeScript
import { RecruitMCP, type RunCreated } from "@recruitmcp/sdk";
const client = new RecruitMCP({ apiKey: process.env.RECRUITMCP_API_KEY });
const preview = await client.createRun(
{ job_description: "Senior backend engineer in Gent, Kubernetes, 5+ years", target: 30 },
{ dryRun: true },
);
const { run } = (await client.createRun({ plan_id: preview.plan?.id, budget: { max_credits: 25 } })) as RunCreated;
await client.waitForRun(run.id);
for await (const candidate of client.paginate((cursor) => client.listRunCandidates(run.id, { cursor }))) {
console.log(candidate.profile.full_name, candidate.distance_km);
}
Python
from recruitmcp import RecruitMCP
client = RecruitMCP() # reads RECRUITMCP_API_KEY
preview = client.create_run({"job_description": "Senior backend engineer in Gent, Kubernetes, 5+ years", "target": 30}, dry_run=True)
run = client.create_run({"plan_id": preview["plan"]["id"], "budget": {"max_credits": 25}})["run"]
client.wait_for_run(run["id"])
for candidate in client.paginate(lambda cursor: client.list_run_candidates(run["id"], cursor=cursor)):
print(candidate["profile"]["full_name"], candidate["distance_km"])
What both clients do
- One method per operation, named after its
operationId:createRunin TypeScript,create_runin Python. The reference lists every operation id. - Paid and sending calls take
dryRun/dry_runfor a free preview. Without it they send anIdempotency-Key: yours if you pass one, or a fresh one per call, so built-in retries never charge or send twice. - Retries 429, 5xx, a busy idempotency key, and network errors, up to
maxRetries(default 2), honouringRetry-After. A 402 is never retried. - Errors raise
RecruitMCPErrorwithstatus, the stablecodefrom Errors,requestId/request_id, anddetails. paginatewalksnext_cursorfor any list.waitForRun/wait_for_runpolls a run until it is completed, completed without an audience, failed, or cancelled.verifyWebhookSignature/verify_webhook_signaturechecks theX-RecruitMCP-Signatureheader of a webhook delivery.customer(on the client or per call) acts inside a customer.versionpinsRecruitMCP-Version.- Base URL defaults to
https://api.recruitmcp.com. PassbaseUrl/base_urlfor a local server.
n8n
The node is declarative: each operation maps to one REST call. Resources: search runs (preview, run, get, candidates), people (raw search, fetch, match, cached read), the seen register, lists, enrollments, and events.
Paid operations start with Dry Run on, so a new workflow never spends credits. Turn it off to execute. The node then sends an Idempotency-Key built from the execution id and the item index, so an n8n retry does not charge twice.
For push instead of polling, register the URL of an n8n Webhook node with POST /v1/webhook-endpoints and verify the signature in a Code node.
The node is a scaffold: it builds and is checked against the spec on every change, but it is not certified by n8n.
Other languages
openapi.yaml is OpenAPI 3.1 with an operationId, a summary, and examples on every operation, so other generators work too. Internal callback routes are kept in a separate spec and are not part of the public file.
What it costs
The clients are free. Calls cost what the same REST call costs.