Docs · Reference · SDK

TypeScript SDK.

@whizz/hire is a zero-dependency, fetch-based client for Node 18+, Bun, Deno, and edge runtimes — typed against the wire format exactly as the API returns it.

Install#

npm
npm i @whizz/hire

End-to-end example#

Node 18+
import { WhizzHire } from "@whizz/hire";

const hire = new WhizzHire({ apiKey: process.env.HIRE_KEY! });

// job → publish
const ack = await hire.jobs.create(
  {
    title: "Fleet Operations Manager",
    seniority: "senior",
    location: "Dubai, UAE",
    skills: ["fleet management", "route optimization", "SAP"],
    bilingual: true,
  },
  { idempotencyKey: "fleet-ops-001" },
);
await hire.runs.waitFor(ack.run_id!, {
  onProgress: (r) => console.log("stage:", r.stage),
});
await hire.jobs.publish(ack.job.id);

// screen every CV, get the top 5 with evidence
const screen = await hire.jobs.screen(ack.job.id, { k: 5 });
await hire.runs.waitFor(screen.run_id);
const screening = await hire.screenings.get(screen.screening_id, {
  include: "results",
});
const top = screening.results!.filter((r) => r.in_top_k);

// interview kit for the front-runner
const kitAck = await hire.applications.interviewKit(top[0].application_id);
await hire.runs.waitFor(kitAck.run_id);
const kit = await hire.interviewKits.get(kitAck.kit_id);
console.log(kit.content.probes);

Client surface#

FieldTypeDescription
hire.jobsresourcecreate(params, {idempotencyKey}) · list({status, limit}) · get(id) · update(id, params) · publish(id) · screen(id, {k, mode}) · applications(id, {status, limit}).
hire.screeningsresourceget(id, {include: "results"}) — ranked results with criterion scores and evidence.
hire.applicationsresourceinterviewKit(applicationId, {language}) — 202 ack with kit_id + run_id.
hire.interviewKitsresourceget(id) — content fills in when the run succeeds.
hire.cvsresourceupload({job_id, files}) — bulk base64 intake, ≤10 files.
hire.runsresourceget(id) · waitFor(id, opts) — poll with backoff until terminal.
hire.usageresourceget({days}) — balance + daily usage.
hire.webhooksresourcecreate({url, events}) · list().
verifyWebhookSignaturefunctionStandard Webhooks HMAC verification (Web Crypto — works on edge).

runs.waitFor#

Polls a run until it reaches a terminal state, starting at 1.5s and backing off ~1.6× per poll toward a 10s ceiling. Resolves with the succeeded run; throws HireError with code run_failed, run_canceled, or poll_timeout (status 0) otherwise. Fully abortable:

Abort + progress
const controller = new AbortController();
setTimeout(() => controller.abort(), 120_000); // hard 2-minute budget

const run = await hire.runs.waitFor(runId, {
  signal: controller.signal,
  pollMs: 2000,
  timeoutMs: 600_000,
  onProgress: (r) => console.log(r.stage),
});

Errors & retries#

Every non-2xx response (after retries) throws a HireError carrying the error envelope. The client retries 429 and 5xx automatically (default 2 attempts), honoring retry-after; network failures retry with exponential backoff.

Handling
import { WhizzHire, HireError } from "@whizz/hire";

try {
  await hire.jobs.publish(jobId);
} catch (err) {
  if (err instanceof HireError) {
    console.error(err.status, err.code, err.message);
    // 403 job_limit "Your free plan allows 1 active job post. …"
    if (err.code === "rate_limit_exceeded") {
      console.log("retry after", err.retryAfter, "seconds");
    }
  }
}

Webhook verification#

Verify a delivery
import { verifyWebhookSignature } from "@whizz/hire";

// in your webhook handler — payload must be the RAW body string
const ok = await verifyWebhookSignature(
  rawBody,
  {
    "webhook-id": req.headers["webhook-id"],
    "webhook-timestamp": req.headers["webhook-timestamp"],
    "webhook-signature": req.headers["webhook-signature"],
  },
  process.env.HIRE_WEBHOOK_SECRET!, // whsec_…
);
if (!ok) return res.status(401).end();

Constant-time comparison and a 5-minute replay tolerance (configurable via toleranceSeconds). The scheme itself is documented on the Webhooks page.

Options#

Constructor options
new WhizzHire({
  apiKey: "wz_live_…",                     // required
  baseUrl: "https://hire.whizztech.ai", // default
  maxRetries: 2,                           // 429/5xx retries per request
  fetch: customFetch,                      // instrumentation/testing
});