Case Study · 01 · 2026
NexHire.
AI hiring, end-to-end.
An AI-native hiring platform that takes a job description to a ranked, scheduled, emailed shortlist — without a human in the loop for screening, matching, scheduling, or outreach.
- Year
- 2026
- Role
- Solo build
- Status
- Live (private beta)
- URL
- nexhire.sajidmiya.tech
01 · Problem
Hiring is a coordination tax.
Recruiters spend roughly 60% of their time on work that has nothing to do with judging candidates — resume screening, calendar coordination, scheduling emails, follow-ups, status updates. The actual signal work (deciding who is good) is squeezed into the remaining 40%.
The tooling hasn’t helped. Most “AI hiring” products are screeners bolted onto an ATS — they’re still a separate step in a longer workflow. None of them own the end of the pipeline: the email that gets sent, the calendar that gets booked, the notification that goes to the hiring manager.
NexHire’s bet: the integration is the product. If the AI can’t actually schedule the interview and send the email and post to Slack, then you’re still doing the coordination work by hand. So I built it to do all of it.
02 · Approach
Own the whole pipeline.
Three commitments shaped the design:
- 1.The AI must close the loop. Screening that doesn’t schedule, or scheduling that doesn’t email, is just an extra step. The product only matters if the AI takes a JD to a booked interview without a human touching it.
- 2.Multi-tenant from day one. Each organization’s jobs, candidates, and conversations must be strictly isolated. Tenant scoping is enforced at the query layer, not the UI.
- 3.No prompt change ships without evaluation. Every screening prompt is gated behind a fixture set and a regression check. The eval harness is what makes shipping safe.
03 · Architecture
How it’s wired.
A React frontend talks to a FastAPI backend. PostgreSQL holds the domain data; Redis handles sessions and rate limits. The AI layer is a set of agentic workflows that orchestrate retrieval against a JD corpus, structured resume parsing, and the third-party integrations.
The integrations bus is where the product earns its keep. Gmail sends the outreach and follow-ups. Google Calendar books the slot. Slack notifies the hiring manager the moment a candidate confirms. Stripe runs the subscription billing. Four third-party APIs, all wired, all live.
04 · Results
What shipped.
What the system actually does today:
Resume screening
LLM scores each resume against the JD, with explanations attached — not a black-box number.
Candidate matching
RAG over the job description plus structured resume parsing; ranks candidates with explainable scoring.
Interview scheduling
Agent negotiates the slot via Google Calendar, emails both sides, handles reschedules.
Outreach & follow-ups
Generates and sends the first-touch email plus polite follow-ups at configured cadences.
Team notifications
Posts updates to Slack so hiring managers see status without checking the dashboard.
Subscription billing
Stripe-powered plans. Multi-tenant isolation enforced at the query layer.
05 · Lessons
What I’d do differently.
Building it taught me more than any tutorial could. The things I’d change next time:
Async-by-default for I/O
Email sends, calendar bookings, and Slack posts were inline initially. Under load they tie up workers. Move them to a queue (Celery / RQ / Arq) from the start.
Evaluation harness before product code
I wrote the eval harness after shipping the first screening prompt. Wrong order. Build the harness first, gate every prompt change through it.
Observability from day one
OpenTelemetry traces from request to LLM call would have saved two debugging weekends. Logs are not enough when the bug is in a multi-step agent loop.
Separate the AI service
The AI workflows are currently inside the FastAPI monolith. A standalone AI service (its own repo, its own deploy) would make versioning and rollback cleaner.
Real authn from day one
JWT was correct, but tenant scoping lived in middleware for too long. Pushing it into a database row-level security policy would have been safer earlier.