API & SDK

Build FirstPanel into your hiring stack.

A REST API and SDKs to create requisitions, invite candidates, and pull evidence-backed results straight into your ATS or HRIS. Every result carries its confidence interval, evidence spans, and audit trail — and no disposition is ever automated.

BASE URL https://api.firstpanel.ai/v1 · Bearer auth · JSON · webhooks · SDKs for Node & Python

Authentication

One key, scoped to your org

Every request is authenticated with a secret API key sent as a Bearer token. Keys are scoped to a single corporate tenant — a key can only ever see its own requisitions and candidates. Rotate keys any time in the console; use restricted keys for read-only integrations.

Authorization: Bearer sk_live_…

test keys sk_test_… hit a sandbox with synthetic candidates.

Quickstart — create a requisition
curl
curl https://api.firstpanel.ai/v1/requisitions \
  -H "Authorization: Bearer $FIRSTPANEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Customer Success Manager",
    "jurisdictions": ["US", "US-NYC"],
    "description": "Own a book of SaaS accounts; drive retention.",
    "sentinel": { "presence": true, "faces": true, "identity": true }
  }'
Core resources

Endpoints

The full surface for a hiring integration: post a requisition, invite candidates, read results, and export the audit pack.

POST/v1/requisitionsCreate a requisition from a job description. Returns a drafted MERIT-8 rubric for approval.
GET/v1/requisitions/{id}Fetch a requisition, its rubric version, and pipeline counts.
POST/v1/requisitions/{id}/invitesInvite a candidate. Returns a consent-gated interview link; consent is collected before any interview begins.
GET/v1/candidates/{id}Candidate profile and application stage across your requisitions.
GET/v1/candidates/{id}/resultThe Role-Fit Index with confidence interval, per-competency scores, evidence spans, abstentions, and Sentinel flags.
GET/v1/candidates/{id}/audit-packThe signed, immutable audit pack (JSON or PDF): consent receipts, rubric version, scores + evidence, reviewer, disposition.
POST/v1/webhooksRegister a webhook endpoint and select the events to receive.
SDKs

Type-safe clients

Official SDKs wrap auth, pagination, retries, and webhook signature verification. The result object is fully typed — RFI, per-competency scores, evidence spans, and abstentions.

Node · @firstpanel/sdk
typescript
import { FirstPanel } from "@firstpanel/sdk";

const fp = new FirstPanel(process.env.FIRSTPANEL_API_KEY);

// Invite a candidate — the link carries the consent gate + Sentinel settings.
const invite = await fp.requisitions.invite("req_1042", {
  name: "Aisha Rahman",
  email: "[email protected]",
});
console.log(invite.interviewUrl);

// Later: pull the evidence-backed result.
const result = await fp.candidates.result("cand_88213");
console.log(result.rfi.value, "±", result.rfi.ci);      // 94 ± 3
for (const c of result.competencies) {
  console.log(c.key, c.abstained ? "ABSTAIN" : c.score, c.evidenceSpans.length);
}
Python · firstpanel
python
from firstpanel import FirstPanel

fp = FirstPanel(api_key=os.environ["FIRSTPANEL_API_KEY"])

invite = fp.requisitions.invite("req_1042",
    name="Aisha Rahman", email="[email protected]")
print(invite.interview_url)

result = fp.candidates.result("cand_88213")
print(result.rfi.value, "±", result.rfi.ci)   # 94 ± 3
Webhooks

Events, signed and ordered

Subscribe to pipeline events and drive your ATS from them. Payloads are signed (HMAC-SHA256) and retried with backoff. Note what these events do — and don’t — carry: a disposition is null until a named human records it.

interview.completedA candidate finishes; provisional scores submitted to the Adjudicator.
candidate.scoredThe Adjudicator finalizes the RFI and evidence.
candidate.shortlistedA human reviewer advances a candidate (never automated).
decision.recordedA named human records advance or decline, with rationale.
sentinel.flaggedThe Integrity Sentinel raises an identity/presence flag for human review.
adverse_impact.alertA four-fifths breach is detected on a requisition.
Example payload
json
{
  "event": "candidate.scored",
  "created": "2026-07-15T10:04:00Z",
  "data": {
    "candidate_id": "cand_88213",
    "requisition_id": "req_1042",
    "rfi": { "value": 94, "ci_low": 91, "ci_high": 97 },
    "recommendation": "STRONG_ADVANCE",
    "floor_breached": false,
    "abstained": [],
    "disposition": null            // stays null until a human decides
  }
}
Native connectors

Skip the glue code

Prebuilt connectors sync requisitions and candidates both ways, so results land on the candidate record your recruiters already use.

GreenhouseLeverWorkdayWorkableAshbySmartRecruitersZoom + Teamsnative
Human-in-the-loop

The API cannot record a disposition without a named reviewer. There is no auto-reject endpoint.

Content-only

No facial-expression, tone, or emotion signal is exposed anywhere — the capability does not exist.

Audit by default

Every result ships with consent receipts, rubric version, evidence spans, and reviewer identity.

Start with a test key.

Spin up a sandbox with synthetic candidates, wire your ATS, and go live when you’re ready. No credit card for the pilot.