Recruiting
Area: HR Workflow: workflows/hr/recruiting.json
Purpose
Sección titulada «Purpose»End-to-end recruiting pipeline for clients who hire through Wulpers. The product is structured around six conceptual stages, of which two are implemented today (Onboarding + Consultant AI). The remaining four (LinkedIn sourcing, CV screening, calendar, human interview) live as roadmap stickies and are explicitly deferred.
The distinctive piece is Stage 2: Consultant AI — before sourcing humans, we run the brief through an LLM that flags responsibilities current AI tooling could cover. The requester gets a consultant note in their inbox and can revise the brief (e.g. replace a slot with an agent, split the role) before we hire.
Pipeline (current — Stages 1 & 2)
Sección titulada «Pipeline (current — Stages 1 & 2)»Form Trigger: Receive Recruiting Brief → Code: Normalize Recruiting Brief → Google Sheets: Append Brief (recruiting_briefs tab, status: pending) → OpenAI: Suggest AI Replacements (gpt-4o-mini) → Code: Parse AI Suggestions (renders email HTML lists) → Google Sheets: Update Brief With AI Suggestions (match by brief_id, status: consulted) → Gmail: Send Consultant Report (HTML email to requester)| Stage | Name | Status | Notes |
|---|---|---|---|
| 1 | Onboarding | Implemented | Form intake + persist brief. |
| 2 | Consultant AI | Implemented | LLM flags AI-replaceable tasks, emails report, updates row. |
| 3 | LinkedIn Recruiter | Deferred | Sourcing on LinkedIn requires Talent API partnership or ATS bridge. |
| 4 | CV Screening | Deferred | Gmail-triggered, parses PDFs, scores against the brief. |
| 5 | Pre-Interview Calendar | Deferred | Google Calendar invite for shortlisted candidates. |
| 6 | Client Interview | Out of scope | Human-led — lives outside n8n. |
Trigger — form fields
Sección titulada «Trigger — form fields»| Field | Type | Required | Notes |
|---|---|---|---|
| Requester Name | text | yes | |
| Requester Email | yes | ||
| Company | text | yes | |
| Role Title | text | yes | E.g. “Senior Backend Engineer”. |
| Role Type | dropdown | yes | Technical / Professional / Hybrid. |
| Seniority | dropdown | yes | Junior / Mid / Senior / Lead / Manager. |
| Employment Type | dropdown | yes | Full-time / Part-time / Contract / Freelance. |
| Location And Mode | text | yes | E.g. “Remote”, “Hybrid Madrid”, “On-site NYC”. |
| Key Responsibilities | textarea | yes | One per line. |
| Required Skills | textarea | yes | Hard + soft, non-negotiable. |
| Nice-To-Have Skills | textarea | no | |
| Budget Range | text | no | E.g. “60k-80k USD/year”. |
| Start Date | date | no | |
| Notes | textarea | no |
Normalized brief shape
Sección titulada «Normalized brief shape»{ "brief_id": "<ISO-8601 timestamp>", "requester_name": "string", "requester_email": "string", "company": "string", "role_title": "string", "role_type": "Technical | Professional | Hybrid", "seniority": "Junior | Mid | Senior | Lead | Manager", "employment_type": "Full-time | Part-time | Contract | Freelance", "location_mode": "string", "responsibilities": "string", "required_skills": "string", "nice_to_have_skills": "string", "budget_range": "string", "start_date": "string", "notes": "string", "status": "pending", "submitted_at": "<ISO-8601 timestamp>"}After the consultant pass, Code: Parse AI Suggestions enriches the item with:
{ "ai_replaceable_json": "<JSON string of [{task, agent_type, confidence, rationale}]>", "human_only_json": "<JSON string of [string]>", "ai_summary": "string", "ai_replaceable_html": "<rendered <ul> for the email>", "human_only_html": "<rendered <ul> for the email>", "status": "consulted", "last_updated_at": "<ISO-8601 timestamp>"}Persistence — recruiting_briefs tab
Sección titulada «Persistence — recruiting_briefs tab»Lives in the existing workbook ($env.WORKBOOK_ID). One row per submitted brief; Stage 2 updates the same row keyed by brief_id.
| Column | Type | Notes |
|---|---|---|
brief_id |
string | PK. ISO-8601 timestamp. |
requester_name |
string | |
requester_email |
string | |
company |
string | |
role_title |
string | |
role_type |
enum | Technical / Professional / Hybrid. |
seniority |
enum | Junior / Mid / Senior / Lead / Manager. |
employment_type |
enum | Full-time / Part-time / Contract / Freelance. |
location_mode |
string | |
responsibilities |
string | |
required_skills |
string | |
nice_to_have_skills |
string | |
budget_range |
string | |
start_date |
string | ISO-8601. |
notes |
string | |
ai_replaceable |
json | JSON array of { task, agent_type, confidence, rationale }. Filled by Stage 2. |
human_only |
json | JSON array of strings. Filled by Stage 2. |
ai_summary |
string | Consultant summary. Filled by Stage 2. |
status |
enum | pending → consulted → publishing → screening → interviewing → closed. |
submitted_at |
string | ISO-8601. |
last_updated_at |
string | ISO-8601. Refreshed by Stage 2 and every subsequent stage. |
Consultant report email
Sección titulada «Consultant report email»Sent via Gmail to requester_email with subject Consultant note on <role_title> at <company>. HTML body includes:
- A list of AI-replaceable tasks with proposed agent type + confidence + rationale.
- A list of human-only tasks.
- A short summary.
- An invitation to revise the brief before sourcing.
Credentials
Sección titulada «Credentials»| Credential type | Used by |
|---|---|
googleSheetsOAuth2Api |
Google Sheets: Append Brief, Google Sheets: Update Brief With AI Suggestions. |
openAiApi |
OpenAI: Suggest AI Replacements — bind in n8n on import. |
gmailOAuth2 |
Gmail: Send Consultant Report — bind in n8n on import. |
commercial.
active: false.- Stages 1 + 2 are the only implemented stages.
Roadmap
Sección titulada «Roadmap»Stage 3 — LinkedIn Recruiter (deferred)
Sección titulada «Stage 3 — LinkedIn Recruiter (deferred)»Goal: publish the job and source candidates on LinkedIn.
Why deferred: n8n’s built-in linkedIn node only posts to a personal feed, which is not a job posting. Real sourcing on LinkedIn Recruiter / Talent Solutions requires either:
- Official LinkedIn Talent API — requires partnership and case-by-case approval.
- An ATS that bridges to LinkedIn (Workable, Greenhouse, JobAdder, Lever) — paid SaaS.
- A scraping service such as Phantom Buster or Apify — recurring cost and against LinkedIn ToS.
Trigger when built: status transition consulted → publishing on the brief row, either by a manual edit or a follow-up confirmation flow after the consultant note.
Stage 4 — CV Screening (deferred)
Sección titulada «Stage 4 — CV Screening (deferred)»Goal: filter inbound CVs against the brief and surface the strongest matches.
Trigger when built: Gmail Trigger on a dedicated alias (e.g. jobs@<company> — exact alias to be decided per client).
Pipeline (planned):
- Pull PDF / DOCX attachments from incoming emails matching the alias.
- Extract text (PDF text layer first; OCR fallback for image-PDFs via OpenAI Vision or Tesseract).
- Score each candidate against
required_skills+nice_to_have_skillswith OpenAI; output{ candidate_name, candidate_email, fit_score, strengths, gaps }. - Append candidates above a threshold to a
candidatestab keyed bybrief_id+ candidate email; deduplicate.
Stage 5 — Pre-Interview Calendar (deferred)
Sección titulada «Stage 5 — Pre-Interview Calendar (deferred)»Goal: book pre-interview slots between the requester and shortlisted candidates.
Trigger when built: candidate row marked shortlisted in the candidates tab (manual or auto when fit_score ≥ threshold).
Plan:
- Create a Google Calendar event with the candidate + requester as attendees.
- Attach a Meet link.
- Send the invite via Gmail (or rely on Calendar’s native invitation email).
- If the candidate declines, log status
declinedand notify the requester.
Stage 6 — Client Interview (out of scope)
Sección titulada «Stage 6 — Client Interview (out of scope)»Goal: human-led interview. Lives outside n8n.
Loop back: after the meeting the requester updates the candidate row (hired / rejected / next_round). That status change can later trigger contract drafting (e.g. via DocuSign) or a polite rejection email.
Open questions
Sección titulada «Open questions»- Status state machine. Confirm the brief status enum (
pending→consulted→publishing→screening→interviewing→closed) once Stage 3 is built. Thedroppedterminal status may be needed too. - Stage 2 idempotency. Re-running the consultant pass on an already-consulted brief currently overwrites the previous AI columns silently. Decide if we want to version them (
ai_replaceable_v1,ai_replaceable_v2) or always overwrite. - Multilingual. The consultant prompt is instructed to “respond in the same language as the brief.” Confirm with a non-English test (e.g. Spanish brief → Spanish email).
- PII. The brief stores requester email but no candidate PII yet. Stage 4 introduces candidate PII — decide retention policy before that stage ships.