This Node.js (18+) example adds a lead from your own form or system to HiringCenter, leaves a note on it, and gives the prospect's owner a follow-up task. See the API Reference for every field.
Code
const BASE_URL = "https://api.hiringcenterpro.com/v2";const API_KEY = process.env.HIRINGCENTER_API_KEY; // hc_<keyId>.<secret>async function hc(method, path, body, idempotencyKey) { const response = await fetch(`${BASE_URL}${path}`, { method, headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", ...(idempotencyKey ? { "X-Idempotency-Key": idempotencyKey } : {}), }, body: body ? JSON.stringify(body) : undefined, }); if (response.status === 429) { const waitSeconds = Number(response.headers.get("Retry-After") || 1); await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000)); return hc(method, path, body, idempotencyKey); } const text = await response.text(); const data = text && response.headers.get("content-type")?.includes("json") ? JSON.parse(text) : text; if (!response.ok) { throw new Error(`${method} ${path} failed (${response.status}): ${JSON.stringify(data)}`); } return data;}async function sendLead(lead) { // 1) Find the stage to place new leads in ("<pipeline> - <stage>"). const stages = await hc("GET", "/account/stages"); const stage = stages.items.find((s) => s.name.endsWith(" - New Lead")); // 2) Create the prospect, or match an existing one by email/phone without changing it. // The same idempotency key makes a retry after a network error safe. const created = await hc( "POST", "/prospects", { firstName: lead.firstName, lastName: lead.lastName, email: lead.email, phone: lead.phone, // US/Canada; returned as 11 digits, e.g. "15552345678" stageId: stage?.id, labels: ["Website"], update: false, }, `lead-${lead.externalId}` ); const prospect = created.item; // 201 when new, 200 when an existing prospect matched console.log(prospect.message, prospect.id); // 3) Record where the lead came from. With no userId, the note is credited to the API key. await hc( "POST", "/notes", { prospectId: prospect.id, body: `<p>Submitted the website form: ${lead.message}</p>` }, `lead-note-${lead.externalId}` ); // 4) Ask the prospect's owner to follow up within an hour of the submission. assignedTo decides // who the task belongs to; with no userId, the task is credited to the API key. dueAt comes // from the submission, not the clock, so a retry sends the same body for the same key. await hc( "POST", "/tasks", { prospectId: prospect.id, assignedTo: prospect.ownerId, task: `Call ${lead.firstName} about the website form`, dueAt: lead.submittedAt + 60 * 60 * 1000, }, `lead-task-${lead.externalId}` ); return prospect.id;}sendLead({ externalId: "form-1042", firstName: "Jordan", lastName: "Miller", email: "jordan.miller@example.com", phone: "(555) 234-5678", message: "Interested in joining the downtown office.", submittedAt: Date.parse("2026-11-03T15:04:00Z"),}).catch((error) => { console.error(error); process.exit(1);});
Notes:
Every request acts on the account that owns the API key; you never send an accountId.
Reuse an idempotency key only with the same request body. A retry that changes the body (for example a time computed from the current clock) returns 409 instead of the saved response.
Activity without a userId is credited to the API key by its name. Send userId to credit a user. ownerId (prospects, meetings) and assignedTo (tasks) decide who a record belongs to.
Use POST /meetings (with ownerId, meetingDate, timeZone, and meetingType) to book a meeting, POST /prospects/<prospectId> with updates.stageId to move the prospect, and POST /hires to record a hire.
"update": false leaves an existing prospect's fields as they are, with one exception: when the same person is submitted again more than 24 hours after the prospect was created, HiringCenter still adds the new details and labels and creates a follow-up task for the owner. Send "skipDuplicateProspectHandling": true to turn that off. With the default "update": true, a matched prospect is updated and the response body is the updated prospect itself rather than { success, item }.
To react to new prospects created anywhere in HiringCenter, have an account admin add a webhook in Settings -> API / Webhooks, or poll GET /webhooks/poll. See Webhooks.