HR Screening Agent
Run AI phone screens at the top of your hiring funnel. Create a role, upload candidate CVs, and Bolti calls each candidate with a screening agent that knows your JD and your custom questions.
The HR Screening module turns a role + a stack of resumes into structured phone screens — no recruiter time, no scheduling tag, no spreadsheet glue. It lives under Agents → HR Screening in the dashboard.
What you'll build
A repeatable funnel:
- Create a role with a job description and a list of custom questions.
- Upload candidate CVs — Bolti parses them, summarises each resume into bullet points, and lists candidates in the role.
- Pick a screening agent that knows how to read JD context and ask questions.
- Reach out in one of two ways:
- Schedule outbound calls for a specific date/time, or
- Send a scheduling link (email or WhatsApp) that lets the candidate self-book a slot — Bolti calls them when the slot lands.
- Watch status update live on the candidates table as links go out, calls are scheduled, calls happen, and screenings complete.
The data model in one picture
Role (Senior Backend Engineer)
└── JD + custom_questions[]
└── Screening agent (with required template variables)
└── Candidates[]
├── name / email / phone (editable)
├── raw_resume_text (parsed from CV)
├── refined_pointers[] (LLM-summarised bullets)
├── parse_status (pending → parsed → refined)
└── outreach_status (none → link_sent → call_scheduled → call_completed)
A role is the top-level container. Every candidate belongs to exactly one role. The agent and custom questions live on the role, so every candidate in that role gets the same screen.
1. Create a role
In the dashboard:
- Go to Agents → HR Screening.
- Click + New Role.
- Fill in:
- Role title — e.g. Senior Backend Engineer.
- Job description — paste the full JD. The agent uses this verbatim during the call, so include the things you actually want it to ask about (responsibilities, must-haves, tech stack).
- Click Create. You land on the role detail page.
You can edit the title and JD later via the Edit button on the role page. Custom questions are added in the next step.
2. Pick an agent + add custom questions
Open the Configuration strip on the role page. It expands to two settings:
Screening agent
Pick an agent from your workspace. The dropdown shows every agent you have access to. Once selected, Bolti checks the agent's prompt for the four template variables it needs to receive screening data:
| Variable | What Bolti fills in |
|---|---|
{{ candidate_name }} | The candidate's name from the parsed CV |
{{ jd_text }} | The role's job description |
{{ custom_questions }} | The list of role-level custom questions |
{{ candidate_details }} | The candidate's refined resume pointers |
If the prompt is missing any of these, you'll see a red Missing: … badge listing the gaps. Edit the agent's prompt to reference them with Jinja-style braces (e.g. Today you're screening {{ candidate_name }} for the {{ jd_text }} role.) and the badge flips to a green Ready.
Why these four? They're the contract between the role-level config and the agent. Without them the agent has no way to know who it's calling, what it's screening for, or what to ask beyond its base persona.
Custom screening questions
Free-form list. Each question becomes one bullet inside the {{ custom_questions }} variable, so the agent can rattle through them in order during the call. Examples:
- Walk me through your most impactful Go project in the last two years.
- Have you ever owned an on-call rotation? Tell me about an incident you led.
- What's your notice period?
Click Add question to add rows. Click the trash icon to remove. Hit Save changes when you're done — both the agent assignment and the question list are saved in one PATCH.
3. Upload candidate CVs
Click Upload CVs on the role page. Bolti opens a branded upload form (hosted on n8n) in a new tab. The form is signed with a short-lived HMAC over your role and workspace, so each link only works for that role.
- Drop one or more CVs (PDFs, Word docs — anything the parser handles).
- Submit the form.
- Switch back to the Bolti tab. Within a few seconds, parsed candidates start streaming into the Candidates table:
- Name / email / phone are extracted from the CV.
- Summary column shows an LLM-generated bullet list of the candidate's most relevant experience (auto-generated within ~2–3s of parsing).
- Outreach badge starts at Not contacted.
The table polls every 5 seconds while the page is open, so new candidates appear without a refresh.
Editing a candidate
If the parser misses something, click the edit (pencil) icon to inline-edit name, email, and phone. Email and phone are validated client-side (E.164-style for phone). Click the sparkles icon to re-summarise the resume — useful if the first refinement is thin or you've updated the JD and want a fresh angle.
Click anywhere on a candidate row (outside the action buttons) to open the side drawer with the full resume text and all refined pointers.
4. Reach out
Tick the checkbox next to one or more candidates. The table header turns into a selection toolbar with three actions: Schedule calls, Send link, and Delete.
Option A — Schedule calls directly
Use this when you already have a slot in mind (e.g. "tomorrow 4pm") and you don't want the candidate to choose.
- Select candidates and click Schedule calls.
- In the dialog:
- Caller ID (From) — pick one of your outbound-capable numbers. If the dropdown is empty, add a number under Settings → Phone Numbers first and make sure it supports outbound.
- Scheduled at — date + time picker in your local timezone. Bolti converts to UTC at submit.
- Click Schedule. Each candidate's
outreach_statusflips to Call scheduled, and the call dials at the chosen moment using your selected agent.
Candidates without a phone number are skipped — the dialog tells you upfront how many will actually be dialled vs. skipped.
Option B — Send a scheduling link
Use this when you want the candidate to self-book.
- Select candidates → click Send link → choose Email or WhatsApp.
- Bolti dispatches one outreach per candidate via your configured n8n workflow. The message contains a Cal.com booking link that's already prefilled with the candidate's name, email, and phone, plus three internal identifiers (
workspace_id,role_id,candidate_id) embedded as hidden booking questions. - Each candidate's
outreach_statusflips to Link sent. - When the candidate books a slot on Cal.com, Bolti receives a webhook, looks up the candidate, builds the agent's variable values from the role + candidate, and schedules the outbound call automatically.
outreach_statusflips to Call scheduled.
Whichever option you pick, the rest of the funnel is the same: the call dials, transcripts and recordings flow into the standard Conversation Intelligence views, and the candidate row updates as the call goes from Call in progress → Screening done.
5. Status reference
The Outreach column on the candidates table is the single source of truth for where each candidate sits in the funnel:
| Status | Means |
|---|---|
| Not contacted | No outreach attempted yet. |
| Link sent | A scheduling link was dispatched (email/WhatsApp). Waiting on the candidate to pick a slot. |
| Link failed | Dispatch attempt errored — usually a missing email/phone or an n8n misconfiguration. |
| Call scheduled | Either you scheduled directly, or the candidate booked via Cal.com. The call is queued. |
| Call in progress | The agent is on the phone with the candidate right now. |
| Screening done | Call completed. Transcript and recording are available under the candidate's Conversation Intelligence views. |
| Call failed | Dial attempt failed (busy, no answer, telephony error). |
The parse status is shown implicitly in the Summary column: Summarizing… while the LLM is working, Parse failed if the CV couldn't be read, and the bullet list once the refinement lands.
One-time setup
You only need to do this once per workspace. After that, every role you create reuses the same plumbing.
Agent prompt template
Your screening agent's system prompt must reference the four required variables (see §2). A minimal starting prompt:
You're a friendly HR screener calling {{ candidate_name }} for the role
described below.
JOB DESCRIPTION:
{{ jd_text }}
CANDIDATE BACKGROUND:
{{ candidate_details }}
QUESTIONS TO COVER:
{{ custom_questions }}
Open with a quick intro, confirm they have ~15 minutes, then walk through
the questions above. Probe on anything that sounds vague. Wrap up by
asking about notice period and salary expectations, then thank them.
The same agent works for every role — the variable values change per candidate, the prompt template doesn't.
n8n workflows (behind the scenes)
Two workflows power the integration. Your infra team configures them once:
- Resume Parser — receives the upload form submissions, runs each CV through a parser node, and POSTs the parsed payload back to Bolti's
/webhooks/n8n/candidate-parsedendpoint with an HMAC signature. Idempotent on(workspace_id, role_id, idempotency_key)so re-uploads are safe. - Send Scheduling Link — receives one POST per candidate from Bolti when you click Send link, builds the prefilled Cal.com URL, and dispatches it via Email or WhatsApp depending on the chosen channel. Both
emailandphoneare always sent so the booking page can be fully prefilled regardless of which channel delivers the message.
Both workflows use a shared HMAC secret (N8N_WEBHOOK_SECRET) so Bolti and n8n can verify each other's traffic.
Cal.com event type
If you're using the Send link path, the Cal.com event type used for screening needs three Hidden Booking Questions in addition to the built-in name / email / phone fields:
| Identifier | Label | Required | Disable input if URL identifier is prefilled |
|---|---|---|---|
workspace_id | Internal Company Reference | ✓ | ✓ |
role_id | Internal Role Reference | ✓ | ✓ |
candidate_id | Internal Candidate Reference | ✓ | ✓ |
These three values are how Cal.com round-trips identifiers back to Bolti when the candidate books a slot. The "Disable input if URL identifier is prefilled" toggle locks them so the candidate can't tamper with them on the booking page.
The event type also needs a webhook firing BOOKING_CREATED to https://api.bolti.co.in/webhooks/calcom/booking-created, signed with the secret stored in Bolti's CALCOM_WEBHOOK_SECRET.
Tips
- Parse first, edit later. The refined bullet pointers are good but not infallible — a quick scan of a candidate's drawer (full resume text) before you schedule the call is worth the 30 seconds.
- One agent, many roles. You don't need a different agent per role. The role provides the JD and questions; the agent provides the persona, voice, and conversational style. Most teams have one screening agent and a dozen roles.
- Bulk actions everywhere. Schedule, send link, and delete all work on multi-select — top-of-funnel velocity is the whole point.
- Polling vs. live. The candidates table polls every 5 seconds while open. If you've kicked off a 50-CV upload, leave the page open and watch them land.
Related
- Agent Setup → LLM for prompt template syntax
- Calling → Call Statuses for what each call-state badge means
- Conversation Intelligence → Transcripts for reviewing screening calls after they land