Tutorial·

How to Build Automated Job Alerts with n8n - Jobven API Tutorial

Learn how to build an automated job alert system using n8n workflow automation and a job API. Get email notifications when new jobs match your criteria.

Manually checking job boards every day gets old fast. Whether you're job hunting, tracking competitors, or monitoring the market, you end up refreshing the same pages hoping something new appeared.

What if new jobs just showed up in your inbox instead?

In this tutorial, I'll show you how to build an automated job alert system using n8n (a workflow automation tool) and a job API. Once set up, you'll get email notifications whenever new jobs matching your criteria are posted.

The whole thing takes about 20 minutes to build.

What We're Building

Here's the workflow:

  1. Schedule trigger - Runs every hour (or however often you want)
  2. Fetch jobs - Calls a job API to get recent postings
  3. Filter - Keeps only jobs matching your criteria
  4. Send email - Notifies you about matching jobs

By the end, you'll have a working job alert system that runs automatically.

Prerequisites

You'll need:

  • n8n account - Sign up for n8n Cloud (free tier available) or self-host
  • Jobven API key - Sign up here (free tier includes 300 requests/month)
  • Email - We'll use n8n's built-in email node, or you can use Gmail/Outlook

Step 1: Create a New Workflow

Open n8n and create a new workflow. Name it something like "Job Alerts".

You'll start with an empty canvas. Let's add nodes.

Step 2: Add the Schedule Trigger

Click the + button and search for "Schedule Trigger". Add it to your workflow.

Configure it to run every hour:

  • Trigger Interval: Hours
  • Hours Between Triggers: 1

You can adjust this based on how often you want alerts. For job hunting, hourly is usually enough. For competitive intelligence, you might want every 15 minutes.

Step 3: Fetch Jobs from the API

Add an HTTP Request node and connect it to the Schedule Trigger.

Configure it:

SettingValue
MethodGET
URLhttps://api.jobven.com/v1/public/jobs
AuthenticationHeader Auth
Header NameX-API-Key
Header ValueYour Jobven API key

Add Query Parameters

Click "Add Parameter" to filter jobs. Here's an example setup for remote software engineering jobs posted in the last hour:

ParameterValue
qsoftware engineer
remoteType[]remote
postedAfter={{ $now.minus(1, 'hour').toSeconds().round() }}
limit10

Note: remoteType[] uses array syntax because the API accepts multiple values (e.g., remote, hybrid). The postedAfter parameter uses n8n expressions to calculate the Unix timestamp for 1 hour ago. The .round() ensures it's a whole number.

Tip: When testing, try a longer time window like $now.minus(1, 'week') or $now.minus(1, 'day'). Companies rarely post jobs on weekends or holidays, so a 1-hour window might return no results. Once you've verified the workflow works, adjust the interval to match your schedule trigger.

Available Filters

You can customize the query with these parameters:

  • q - Search query (searches title, summary, description)
  • remoteType - remote, hybrid, onsite, or flexible
  • experienceLevel - entry, mid, senior, lead, or executive
  • employmentType - full_time, part_time, contract, etc.
  • skills - Filter by required skills (e.g., react,typescript)
  • location - City, state, or country
  • minSalary / maxSalary - Salary range filter
  • postedAfter - Unix timestamp (seconds) for freshness

Step 4: Handle the Response

The API returns jobs in this format:

{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "title": "Senior Software Engineer",
      "summary": "Build scalable systems for a growing fintech company",
      "description": "<p>We're looking for a Senior Software Engineer...</p>",
      "companies": [{ "name": "Acme Corp", "website": "https://acme.com" }],
      "locations": [{
        "addressLocality": "San Francisco",
        "addressRegion": "California",
        "addressCountry": "US",
        "workLocation": "remote"
      }],
      "remoteType": "remote",
      "salary": { "min": 150000, "max": 200000, "currency": "USD", "period": "annual" },
      "skills": { "primary_skills": ["Python", "AWS", "PostgreSQL"] },
      "experienceLevel": "senior",
      "employmentType": "full_time",
      "applyUrl": "https://acme.com/careers/123",
      "postedAt": 1735344000,
      "status": "active"
    }
  ],
  "meta": {
    "total": 150,
    "count": 1,
    "hasMore": true,
    "nextCursor": "eyJpZCI6ImFiYzEyMyJ9"
  }
}

Add a Code node to extract and format all jobs into a single digest:

const response = $input.first().json;
const jobs = response.data;

if (!jobs || jobs.length === 0) {
  return []; // No jobs found, workflow stops here
}

// Build HTML for each job
const jobsHtml = jobs.map(job => {
  const company = job.companies?.[0]?.name || 'Unknown';
  const location = job.locations?.[0]?.addressLocality || 'Remote';
  const country = job.locations?.[0]?.addressCountry || '';
  const salary = job.salary
    ? `${job.salary.currency || 'USD'} ${job.salary.min?.toLocaleString() || '?'} - ${job.salary.max?.toLocaleString() || '?'}`
    : 'Not disclosed';
  const skills = job.skills?.primary_skills?.slice(0, 5).join(', ') || 'Not specified';
  const postedAt = job.postedAt
    ? new Date(job.postedAt * 1000).toLocaleDateString()
    : 'Unknown';

  return `
    <div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; margin-bottom: 16px;">
      <h3 style="margin: 0 0 8px 0;">${job.title}</h3>
      <p style="margin: 4px 0; color: #6b7280;"><strong>${company}</strong> · ${location}${country ? ` (${country})` : ''} · ${job.remoteType || 'Not specified'}</p>
      <p style="margin: 4px 0;"><strong>Salary:</strong> ${salary}</p>
      <p style="margin: 4px 0;"><strong>Skills:</strong> ${skills}</p>
      <p style="margin: 4px 0; font-size: 12px; color: #9ca3af;">Posted: ${postedAt}</p>
      <a href="${job.applyUrl}" style="display: inline-block; margin-top: 8px; background: #2563eb; color: white; padding: 8px 16px; text-decoration: none; border-radius: 4px;">Apply Now</a>
    </div>
  `;
}).join('');

// Return single item with digest
return [{
  json: {
    jobCount: jobs.length,
    subject: `Job Alert: ${jobs.length} new job${jobs.length > 1 ? 's' : ''} found`,
    htmlContent: `
      <h2>New Job Alerts</h2>
      <p>Found ${jobs.length} new job${jobs.length > 1 ? 's' : ''} matching your criteria:</p>
      ${jobsHtml}
      <hr style="margin-top: 24px; border: none; border-top: 1px solid #e5e7eb;" />
      <p style="font-size: 12px; color: #9ca3af;">Powered by <a href="https://jobven.com">Jobven</a></p>
    `
  }
}];

This creates a single digest email with all matching jobs, instead of one email per job.

Step 5: Additional Filtering (Optional)

The API supports many filters, but if you need custom logic, add it in the Code node before building the digest.

For example, to only include jobs with salary info, modify the Code node:

// After getting jobs from response.data
const filteredJobs = jobs.filter(job => job.salary && job.salary.min);

// Then use filteredJobs instead of jobs for the rest

Or filter by specific companies:

const filteredJobs = jobs.filter(job =>
  job.companies?.[0]?.name?.toLowerCase().includes('stripe')
);

Step 6: Send Email Notifications

Add a Send Email node (or Gmail/Outlook node if you prefer).

Since the Code node already built the HTML content, configuration is simple:

SettingValue
ToYour email address
Subject={{ $json.subject }}
HTML={{ $json.htmlContent }}

The = prefix tells n8n to evaluate the expression. The subject and HTML content are already formatted by the Code node, so you just reference them directly.

Alternative: Slack Notifications

If you prefer Slack over email:

  1. Add a Slack node instead
  2. Connect to your Slack workspace
  3. Choose a channel
  4. Use a similar message format

Step 7: Test Your Workflow

Before activating:

  1. Click Test Workflow to run it manually
  2. Check if jobs are fetched correctly
  3. Verify the email/Slack message looks right

If no jobs appear, try removing the postedAfter parameter temporarily to test with existing jobs.

Step 8: Activate

Once everything works, click Activate in the top right.

Your workflow will now run automatically on schedule. Every hour (or whatever interval you set), it will:

  1. Check for new jobs
  2. Filter by your criteria
  3. Send you notifications

The Complete Workflow

Here's what the finished workflow looks like:

Download the Workflow

Want to skip the setup? Download the complete workflow JSON and import it into n8n.

After importing, just add your Jobven API key and email settings.

Customization Ideas

Once you have the basic workflow running, try these variations:

Multiple searches - Duplicate the HTTP Request node with different filters, then merge results before sending

Daily digest - Instead of instant alerts, collect jobs throughout the day and send one summary email

Save to spreadsheet - Add a Google Sheets node to track all jobs you've been alerted about

Deduplication - Use n8n's storage or a Google Sheet to track job IDs and avoid duplicate alerts

Wrapping Up

You now have an automated job alert system that:

  • Runs on a schedule
  • Fetches fresh job postings from employer career pages
  • Filters by your criteria
  • Sends notifications automatically

No more manual checking. Jobs come to you.


Need job data for your project? Jobven provides fresh job postings scraped directly from employer career pages. Get your free API key →