Skip to main content

API reference

LightningHire exposes a REST-style HTTP API powered by Next.js 16 route handlers under src/app/api/. Most endpoints back the first-party web app, but the same routes are usable programmatically with an API key. This page documents the auth model, the high-level domains, and enough example requests to get you oriented.

This is a reference, not an exhaustive endpoint list. Endpoints evolve frequently — treat your installed source under src/app/api/ as the source of truth.

Authentication

LightningHire supports three auth modes. Each route declares what it accepts via the apiHandler wrapper in @/lib/api/api-handler.

1. Session auth (first-party web app)

Browser requests from the logged-in app carry a NextAuth v5 session cookie. Server-side, route handlers resolve the user via verifySession() or requireUserId() from @/lib/session. You do not need to do anything extra in the browser — the cookie is set at sign-in.

2. BYOK API keys (programmatic access)

Bring-your-own-key users and Pro accounts can mint API keys from Settings → API keys. Pass the key as a bearer token:

curl https://lightninghire.com/api/me \
-H "Authorization: Bearer lh_live_..."

Keys are scoped to the issuing user. Revoke a key from the same settings page — revocation is immediate.

3. Cron secret (scheduled jobs)

Routes under /api/cron/* and a handful of admin endpoints require a shared secret passed as a bearer token. This is set by Vercel Cron via the CRON_SECRET env var.

curl https://lightninghire.com/api/cron/lifecycle-emails \
-H "Authorization: Bearer $CRON_SECRET"

Requests without a valid CRON_SECRET receive 401. See vercel.json for the live cron schedule.

Never expose CRON_SECRET to the browser

The secret is server-side only. Rotating it requires redeploying with the new value set in Vercel env vars.

Response shape

Successful responses are wrapped via successResponse() from @/lib/utils:

{
"ok": true,
"data": { "...": "..." }
}

Errors are thrown as typed AppError instances from @/lib/api/errors and returned as:

{
"ok": false,
"error": {
"message": "Too many requests. Please try again later.",
"code": "RATE_LIMIT"
}
}

Status codes follow HTTP semantics: 400 validation, 401 unauthenticated, 402 entitlement/paywall, 403 forbidden, 404 missing, 409 conflict, 429 rate-limited, 5xx server.

Rate limits

Public endpoints (/api/leads, /api/contact) apply per-IP in-memory rate limits — for example /api/leads caps at 10 submissions per 15-minute window per IP. Authenticated endpoints are gated by entitlements rather than a raw rate limit: free-tier users hit feature caps (e.g. 10 AI actions/day), Pro users are uncapped.

Domains

Endpoints are grouped by domain under src/app/api/. The domains below are the ones you'll touch most often.

Interview & preparation

DomainPurpose
mock-interviewAI-scored practice sessions — create, score, list, retrieve.
sessions / conversations / transcriptLive interview sessions and their transcripts.
storiesSTAR story CRUD plus stories/generate and stories/build AI helpers.
questions / question-groupsInterview question bank browsing and search.
interviewsScheduled interview events and reminders.
mentorshipMentor-matching and session bookings.

Job search & tracking

DomainPurpose
applicationsJob pipeline — candidate's own applications.
jobsJob search, job-match scoring, and job details.
companies / company-requestsCompany intel, follow-worthy companies, intel requests.
rolesRecruiter requisitions (job postings being hired for).
candidatesRecruiter-side candidates attached to requisitions.
resume / resumes / builder-resumesResume CRUD, tailoring, and the structured builder.

AI tooling

DomainPurpose
analyzeDeep evaluation of a candidate/job match (A–F scoring).
chatRAG-backed chat over the user's data.
contextAggregated user context for prompts.
toolsPoint-in-time tools — salary negotiation, offer comparison, etc.
negotiate-feedbackFeedback loop for negotiation drafts.

Outreach & communication

DomainPurpose
contactsNetwork CRM — contact CRUD.
outreach / messages / emailDrafted outreach messages, template rendering, delivery.
templatesUser and system message templates.
notificationsIn-app notification inbox.

Account, billing, admin

DomainPurpose
authNextAuth callbacks and session endpoints.
me / user / users / accountCurrent-user profile, preferences, API keys.
billing / stripe / creditsSubscription state, Stripe webhook, credit balance.
entitlementsBulk feature-access payload for the client.
usage / statsPer-feature usage counters.
settingsUser settings CRUD.
adminAdmin-only surfaces (super-admin role required).

Lead magnets & marketing

DomainPurpose
leadsLead magnet capture — rate-limited, sends email.
contactContact form submissions.
support / feedbackSupport ticket intake and product feedback.
blog / courses / help / publicContent APIs for marketing surfaces.
unsubscribeEmail unsubscribe handler.

Background & scheduled

DomainPurpose
cron/*Vercel-cron-triggered jobs — lifecycle emails, streak nudges, win-back, abandoned-signup, lead drip, job recommendations. All require CRON_SECRET.
job-digestDaily digest generator for saved searches.
telemetryClient-side telemetry ingest.

Examples

Capture a lead

Public endpoint, IP rate-limited, no auth required.

curl -X POST https://lightninghire.com/api/leads \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"source": "interview-prep-guide",
"marketingOptIn": true,
"utm": { "source": "twitter", "medium": "social" }
}'

On success, the user receives an email with the download link and the endpoint returns:

{ "ok": true, "downloadUrl": "https://lightninghire.com/downloads/..." }

Start a mock interview

Authenticated — requires a valid session or API key.

curl -X POST https://lightninghire.com/api/mock-interview \
-H "Authorization: Bearer lh_live_..." \
-H "Content-Type: application/json" \
-d '{
"company": "Stripe",
"role": "Staff Engineer",
"interviewType": "behavioral",
"focusAreas": ["leadership", "conflict"]
}'

Free-tier users are capped at 3 mock interviews per 7-day window. Exceeding the cap returns 402 with an upgradeHint string suitable for display.

Fetch current entitlements

The client uses this to render paywalls. The response includes per-feature usage and remaining counts.

curl https://lightninghire.com/api/entitlements \
-H "Authorization: Bearer lh_live_..."

See the entitlements reference for the full payload shape.

Trigger a cron job manually

Useful for debugging locally.

curl https://lightninghire.com/api/cron/lifecycle-emails \
-H "Authorization: Bearer $CRON_SECRET"

Conventions

  • Route handlers use the apiHandler wrapper. It applies auth, entitlement checks, and error normalization. New routes should not hand-roll these.
  • Validation is Zod-first. Every request body is parsed with a Zod schema before the handler touches it.
  • Database calls are Mongoose. Call connectToDatabase() from @/lib/db/connection before any model operation.
  • AI calls go through src/lib/ai/ai-client.ts. Don't import OpenAI/Anthropic SDKs directly in routes.

See also