DEV Community

Donny Nguyen
Donny Nguyen

Posted on • Originally published at rapidapi.com

Scrape Indeed Job Listings Without Getting Blocked (API Guide)

Indeed is the world's largest job board — 350 million unique visitors per month, postings from virtually every company that's hiring. If you're building a job aggregator, salary analysis tool, hiring market tracker, or recruitment automation — you need Indeed data.

Direct scraping is painful. Indeed blocks aggressively: rate limiting, CAPTCHAs, IP bans, JavaScript rendering. Their official API was shut down to new developers years ago.

I've built a hosted Indeed Job Scraper API that handles all of this. Here's how to use it.

API Link: Indeed Job Scraper API on RapidAPI

What It Returns

{
  "success": true,
  "query": "software engineer",
  "location": "Austin TX",
  "count": 25,
  "data": [
    {
      "jobId": "abc123def456",
      "title": "Senior Software Engineer",
      "company": "Dell Technologies",
      "location": "Austin, TX",
      "salary": "$120,000 - $160,000 a year",
      "salaryMin": 120000,
      "salaryMax": 160000,
      "jobType": "Full-time",
      "remote": false,
      "postedDate": "2026-03-08",
      "description": "We are looking for a Senior Software Engineer...",
      "applyUrl": "https://www.indeed.com/viewjob?jk=abc123def456",
      "benefits": ["Health insurance", "401k", "Remote work options"]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Quick Start

const axios = require('axios');

async function searchIndeedJobs(query, location, options = {}) {
  const response = await axios.get(
    'https://indeed-job-scraper.p.rapidapi.com/search',
    {
      params: {
        q: query,
        location: location,
        limit: options.limit || 25,
        jobType: options.jobType || '', // fulltime, parttime, contract, internship
        remote: options.remote || false,
        sortBy: options.sortBy || 'relevance' // relevance, date
      },
      headers: {
        'X-RapidAPI-Key': 'YOUR_RAPIDAPI_KEY',
        'X-RapidAPI-Host': 'indeed-job-scraper.p.rapidapi.com'
      }
    }
  );
  return response.data;
}

// Search for remote React jobs
const jobs = await searchIndeedJobs('React developer', 'Remote', {
  remote: true,
  jobType: 'fulltime',
  limit: 50
});
Enter fullscreen mode Exit fullscreen mode

Use Cases

1. Job Aggregator / Board

Build a niche job board that pulls from Indeed:

async function buildJobBoard(niches, locations) {
  const allJobs = await Promise.all(
    niches.flatMap(niche => 
      locations.map(loc => searchIndeedJobs(niche, loc))
    )
  );

  const jobs = allJobs.flatMap(r => r.data);

  // Deduplicate by jobId
  return [...new Map(jobs.map(j => [j.jobId, j])).values()];
}

// Crypto/blockchain jobs aggregator
const cryptoJobs = await buildJobBoard(
  ['blockchain developer', 'solidity engineer', 'web3 developer', 'DeFi'],
  ['Remote', 'New York NY', 'San Francisco CA', 'Austin TX']
);
Enter fullscreen mode Exit fullscreen mode

2. Salary Research Tool

Analyze salary ranges by role and location:

async function analyzeSalaries(jobTitle, locations) {
  const results = await Promise.all(
    locations.map(loc => searchIndeedJobs(jobTitle, loc, { limit: 100 }))
  );

  return locations.map((loc, i) => {
    const jobsWithSalary = results[i].data.filter(j => j.salaryMin && j.salaryMax);

    if (!jobsWithSalary.length) return { location: loc, insufficient_data: true };

    const avgMin = jobsWithSalary.reduce((s, j) => s + j.salaryMin, 0) / jobsWithSalary.length;
    const avgMax = jobsWithSalary.reduce((s, j) => s + j.salaryMax, 0) / jobsWithSalary.length;

    return {
      location: loc,
      averageSalaryRange: `$${Math.round(avgMin/1000)}k - $${Math.round(avgMax/1000)}k`,
      sampledJobs: jobsWithSalary.length
    };
  });
}

const salaryReport = await analyzeSalaries('Software Engineer', [
  'San Francisco CA', 'Austin TX', 'New York NY', 'Dallas TX', 'Remote'
]);
Enter fullscreen mode Exit fullscreen mode

3. Hiring Market Tracker

Track how many companies are hiring for a role over time — a proxy for market demand:

// Run weekly, store results in DB
async function trackHiringTrend(role, location) {
  const results = await searchIndeedJobs(role, location, { limit: 100, sortBy: 'date' });

  // Count unique companies hiring
  const companies = [...new Set(results.data.map(j => j.company))];

  return {
    role,
    location,
    openPositions: results.count,
    uniqueCompanies: companies.length,
    remotePercent: Math.round(
      results.data.filter(j => j.remote).length / results.data.length * 100
    ),
    weekOf: new Date().toISOString().split('T')[0]
  };
}
Enter fullscreen mode Exit fullscreen mode

4. Recruitment Automation

Find companies actively hiring for roles relevant to your product:

async function findCompaniesByHiringSignal(targetRole, targetLocation) {
  const results = await searchIndeedJobs(targetRole, targetLocation, { limit: 100 });

  // Companies hiring = companies that may need your tooling
  const companiesHiring = [...new Set(results.data.map(j => j.company))];

  return companiesHiring.map(company => ({
    company,
    openRoles: results.data.filter(j => j.company === company).length,
    signal: 'actively_hiring'
  }));
}

// If you sell developer tools — find companies actively hiring developers
const targets = await findCompaniesByHiringSignal('React developer', 'Dallas TX');
Enter fullscreen mode Exit fullscreen mode

5. Remote Work Trend Analysis

async function analyzeRemoteWork(roles) {
  const results = await Promise.all(
    roles.map(role => searchIndeedJobs(role, 'United States', { limit: 100 }))
  );

  return roles.map((role, i) => ({
    role,
    totalJobs: results[i].count,
    remoteJobs: results[i].data.filter(j => j.remote).length,
    remotePercent: Math.round(
      results[i].data.filter(j => j.remote).length / results[i].data.length * 100
    )
  }));
}
Enter fullscreen mode Exit fullscreen mode

Parameters

Parameter Type Required Description
q string Yes Job title or keyword
location string Yes City, state or "Remote"
limit number No Results (1-100, default: 25)
jobType string No fulltime, parttime, contract, internship
remote boolean No Filter remote only (default: false)
sortBy string No relevance, date (default: relevance)

Pricing

Plan Requests/mo Price
BASIC 500 Free
PRO 10,000 $9.99/mo
ULTRA 50,000 $29.99/mo
MEGA 200,000 $79.99/mo

Get Started

Subscribe to Indeed Job Scraper API on RapidAPI →

Free plan — 500 requests/month at no cost.


Built by Donny Dev — full data API suite: Google Maps Scraper · Apollo Lead Scraper · Email Extractor · Website Tech Detector · DuckDuckGo Search

Top comments (0)