4Geeks chosen to deliver AI education in the Bahamas alongside Harvard, Oxford, and Columbia.See more
11 min read

How to Use AI to Find a Job (n8n Workflow)

A 13-node pipeline that finds live postings, names the hiring contact and drafts a message you review before you send.
Authors:4Geeks AcademyLast updated

How to use AI to find a job means letting a workflow do the repetitive part of the search: find live postings, identify the person who is actually hiring and draft a specific first message, while you keep the decision to send it. The AI Job Hunter workflow built for the 4Geeks workshop does that in 13 n8n nodes, from a candidate form to a Gmail draft. This is the working version as of September 2026, node by node, including the mistakes that broke it the first time.

This is not a list of "AI job search tools". ChatGPT rewriting a cover letter does not solve the two steps that actually move a candidacy: a current posting and a named person. The workflow below is a data pipeline with a human checkpoint.

What does it mean to use AI to find a job?

Most applications die in the same two places. The candidate spends hours on job boards reading postings that are stale or irrelevant, and the few applications that go out land in a form that nobody reads. A message that reaches a recruiter or a hiring manager by name, and mentions something real about the role, gets a different kind of attention. Finding that person and writing that message takes about twenty minutes per posting, so almost nobody does it.

Using AI here means attacking those two bottlenecks, not spraying applications. The workflow pulls postings from Google for Jobs through an API, so the openings are real and current. It asks Apollo for the recruiter, talent acquisition lead or hiring manager at that company and reveals a verified work email. Then it hands Claude the posting, the contact and the candidate's profile with strict rules, and gets back an 80 to 120 word message that references the job description and connects it to one concrete achievement.

What it deliberately does not do is send anything. That is the part people get wrong when they think of "AI applying for jobs". The value is not that a model writes for you. The value is a pipeline of real data with a human checkpoint at the end. For the manual side of the same search, the article on how to get a job in tech covers portfolio, networking and interviews.

What does the AI Job Hunter workflow do, node by node?

The workflow runs in n8n, free or self-hosted. Each row is a real node with the configuration that ended up working.

#NodeWhat it does
1Candidate Form Triggern8n's public form collects the candidate profile
2Build Candidate ProfileSet node normalizes the form fields into short names
3JSearch - Find JobsHTTP Request finds real postings via Google for Jobs
4Filter & Select Top JobsCode node cleans the response and keeps up to 5 postings
5Apollo - Find Hiring ContactHTTP Request finds the likely hiring contact
6Apollo - Reveal Contact EmailHTTP Request reveals the email, costs 1 Apollo credit
7Merge Job + ContactCode node combines posting and contact
8Claude - Draft Outreach MessageHTTP Request drafts the message
9Compile Final RecordCode node assembles the final record
10Log to Google SheetsOne row per run
11Gmail - Create DraftCreates the draft, never sends
12-13Error Trigger and SlackSeparate branch that reports failures

Accounts you need: n8n, RapidAPI with the JSearch API by OpenWeb Ninja (a paid plan is recommended), Apollo.io with a master API key (paid plan), the Anthropic API (pay per use), Google Sheets and Gmail through OAuth, and a Slack workspace for alerts.

Downloadable guide

Rebuild the 13-node workflow without the silent failures.

The article maps the pipeline. The 7-page guide has the exact n8n configs, the code and the eight errors that broke the first build.

AI Job Hunter Workflow Full Guide

7 pages. 4Geeks Academy

  • Working node configs for JSearch v2, Apollo and Claude
  • Filter, merge and prompt code you can paste
  • The 8 silent failures, in the order they hit

Get the free guide

Your copy, in minutes

How do you capture the candidate profile? (nodes 1 and 2)

The form asks for six things: name, target role, country as an ISO code (co, mx, ar, cl, es), key skills separated by commas, years of experience and one concrete achievement. That last field matters more than it looks. Without a specific achievement, the model has nothing real to connect to the posting and the message drifts into generic praise.

Node 2 is a Set node that renames the long form labels into short variables: candidate_name, target_role, country_code, skills, years_experience and achievement. The most common failure in the whole workflow lives right here. Each field label in node 2 has to match the form label exactly, accents included. A single mismatch produces an "undefined" three or four nodes later, where it is much harder to trace.

How does the workflow find real job postings? (nodes 3 and 4)

Node 3 is an HTTP Request to JSearch:

GET https://jsearch.p.rapidapi.com/search-v2
query = $json.target_role
country = $json.country_code
language = es
num_pages = 1

Two details cost the original build real time. The version in the URL matters, because v1 is deprecated for many RapidAPI accounts and returns errors that look like authentication problems. And the authentication has to be n8n's Custom Auth, not Header Auth, because JSearch needs two headers (X-RapidAPI-Key and X-RapidAPI-Host) and Header Auth only supports one.

Node 4 is a Code node. The real results are nested under data.jobs, not under data, and postings without a company website are dropped because Apollo needs the domain in the next step:

javascript
const jobs = ($input.first().json.data && $input.first().json.data.jobs) || [];
const profile = $('Build Candidate Profile').first().json;
 
return jobs
  .filter(j => j.employer_name && j.job_apply_link && j.employer_website)
  .slice(0, 5)
  .map(j => ({ json: {
    job_title: j.job_title,
    company: j.employer_name,
    company_domain: j.employer_website || '',
    job_description: (j.job_description || '').slice(0, 800),
    job_apply_link: j.job_apply_link,
    candidate_name: profile.candidate_name,
    target_role: profile.target_role,
    skills: profile.skills,
    years_experience: profile.years_experience,
    achievement: profile.achievement
  }}));

The description is cut at 800 characters on purpose. It is enough for the model to find something specific, and it keeps the prompt short and cheap.

How do you find the person who is actually hiring? (nodes 5 to 7)

Node 5 calls Apollo's people search. The old endpoint, /mixed_people/search, is deprecated; the one that works is POST https://api.apollo.io/api/v1/mixed_people/api_search. The body asks for people with the titles Recruiter, Talent Acquisition or Hiring Manager at the company domain, five per page.

The domain has to be clean. If it arrives as https://www.company.com, Apollo does not complain; it silently ignores the filter and returns people from unrelated companies. The build strips the protocol and the www with a one-line replace before sending it. The second silent failure is the key type: with a regular API key Apollo also returns generic results instead of filtering by domain. Only a master API key, generated under Settings, Integrations, API, filters correctly.

Node 6 is a second call, POST /api/v1/people/match, because the search returns name, title and company but not the email. Revealing the email costs one Apollo credit per contact, and the request sets reveal_personal_emails to false so it only returns work addresses.

Node 7 is a Code node that merges by index. Name and title come from node 5, the email from node 6 and the posting from node 4. No single node has everything, so the code walks the three arrays in parallel and builds one record per posting with contact_name, contact_title, contact_linkedin and contact_email.

How does Claude write a message that does not sound generic? (node 8)

Node 8 posts to https://api.anthropic.com/v1/messages with the model claude-sonnet-4-6 and max_tokens set to 400. The quality of the output comes almost entirely from the system prompt, which is a set of constraints rather than a creative brief:

You are an assistant that helps a candidate reach out directly to the
person likely responsible for hiring for a specific job posting. Write a
short message (80-120 words), natural and specific, never generic.
Rules: 1) Reference something specific and real from the job description.
2) Connect that requirement to a concrete achievement or skill of the
candidate's. 3) Confident but humble, conversational tone, no LinkedIn
cliches. 4) Close with a low-commitment, open-ended question, never
'hire me'. 5) Never invent facts. 6) Write in neutral Latin American
Spanish.

Rule 5 is the one that keeps the workflow honest: the model only knows what the form and the posting say. Rule 4 changes the reply rate more than any wording trick, because a low-commitment question is easier to answer than a request. Rule 6 is set for the workshop audience; change it to your market's language before running it elsewhere. The user message assembles name, role, posting and contact from the fields produced by node 7.

Where does the result go, and why is the email never sent automatically? (nodes 9 to 13)

Node 9 joins the drafted message with the rest of the record and stamps a generated_at timestamp. Node 10 appends one row per run to a Google Sheet with a tab named exactly Workshop Results, using the appendOrUpdate operation and autoMapInputData so columns match by name, not by position. Suggested headers: candidate_name, target_role, job_title, company, contact_name, contact_title, contact_email, drafted_message, generated_at.

Node 11 creates a Gmail draft with the subject "About the [job title] role at [company]" and the drafted message as the body. It never uses the send operation, and that is a design decision, not an oversight. The message goes to a real person's real email address. Sending stays in the hands of whoever reviews the draft, reads the posting again and decides that the message is worth the recipient's time.

Nodes 12 and 13 sit on a separate branch that is not connected to the main flow. The Error Trigger fires automatically when any node fails and posts to a Slack channel the workflow name, the last node executed and the error message. When JSearch changes a version or Apollo rejects a key, you find out in Slack instead of in an empty spreadsheet.

One more rule for live demos: do not show the full email address on screen. Name and title are enough to make the point without exposing the personal data of someone who never agreed to be projected in front of a room.

What breaks first when you rebuild it?

These are the failures hit during the original build, in the order they are likely to hit you:

  • Form labels that do not match node 2 exactly, which surfaces as "undefined" far downstream.
  • JSearch v1 instead of search-v2, deprecated for many accounts.
  • Header Auth in n8n, which only carries one header when JSearch needs two.
  • Reading results from data instead of data.jobs.
  • Apollo's deprecated /mixed_people/search endpoint.
  • A domain sent with https:// or www, which Apollo ignores without an error.
  • A regular Apollo key instead of a master key, which returns unrelated companies.
  • Expecting the email from the search call, when it only comes from the match call.

Manual search or AI Job Hunter: what really changes?

Manual searchAI Job Hunter workflow
PostingsWhatever you open on a job boardReal, current postings from Google for Jobs, filtered to companies with a domain
ContactA form or a generic careers inboxA named recruiter or hiring manager with a verified work email
MessageWritten from scratch, usually generic80 to 120 words that cite the posting and one real achievement
RecordScattered across tabsOne row per run in a sheet
SendingManualManual, from a reviewed draft
FailuresInvisibleReported to Slack with the node and the error

The honest verdict: the workflow does not get you hired, and anyone who promises that is selling something. It removes the reasons people skip the step that works, which is contacting a real person with a specific message. If you want the human side of that step, 7 hacks to land a job is the complement to this piece.

Is this really AI engineering?

Yes, and that is the point of building it in a workshop. Strip away the job-search framing and you have a data pipeline: a trigger, two external APIs with real quirks, deterministic code that cleans and merges, a language model constrained by explicit rules, persistent logging, a human checkpoint and an error channel. That is the same shape as the agents companies are deploying in 2026, and it is the kind of work described in the article on AI engineer jobs.

Your next step

Rebuild the 13 nodes with your own profile, run it for one role and one country, and read the five drafts before sending any of them. The moment you want to add a second source of postings, score candidates or plug in a different model, you are doing AI engineering. The AI Engineering program teaches exactly that: connecting real data, APIs and language models into systems that hold up outside a demo.

Start Your AI Career Today

Join thousands of graduates who have transformed their careers with 4Geeks Academy.

Frequently asked questions