Skip to main content

Overview

The ProviderCredentials interface defines authentication credentials for supported job boards. It allows authenticated scraping when anonymous access is blocked or rate-limited.

Interface Definition

export interface ProviderCreds {
  username: string;
  password: string;
}

export interface ProviderCredentials {
  linkedin?: ProviderCreds;
  indeed?: ProviderCreds;
  glassdoor?: ProviderCreds;
  zip_recruiter?: ProviderCreds;
  bayt?: ProviderCreds;
  naukri?: ProviderCreds;
  bdjobs?: ProviderCreds;
}

Fields

linkedin
ProviderCreds
LinkedIn account credentials
  • username: LinkedIn email address
  • password: LinkedIn password
indeed
ProviderCreds
Indeed account credentials
  • username: Indeed email address
  • password: Indeed password
glassdoor
ProviderCreds
Glassdoor account credentials
  • username: Glassdoor email address
  • password: Glassdoor password
zip_recruiter
ProviderCreds
ZipRecruiter account credentials
  • username: ZipRecruiter email address
  • password: ZipRecruiter password
bayt
ProviderCreds
Bayt account credentials
  • username: Bayt email address
  • password: Bayt password
naukri
ProviderCreds
Naukri account credentials
  • username: Naukri email address
  • password: Naukri password
bdjobs
ProviderCreds
BDJobs account credentials
  • username: BDJobs email address
  • password: BDJobs password

Example Usage

Using Credentials Object

import { scrapeJobs, ProviderCredentials } from 'jobspy-js';

const credentials: ProviderCredentials = {
  linkedin: {
    username: '[email protected]',
    password: 'your-linkedin-password'
  },
  indeed: {
    username: '[email protected]',
    password: 'your-indeed-password'
  }
};

const response = await scrapeJobs({
  site_name: ['linkedin', 'indeed'],
  search_term: 'software engineer',
  location: 'New York, NY',
  use_creds: true,
  credentials: credentials
});

Using Individual Parameters

import { scrapeJobs } from 'jobspy-js';

const response = await scrapeJobs({
  site_name: 'linkedin',
  search_term: 'product manager',
  location: 'San Francisco, CA',
  use_creds: true,
  linkedin_username: '[email protected]',
  linkedin_password: 'your-password'
});

Using Environment Variables

# Set environment variables
export LINKEDIN_USERNAME="[email protected]"
export LINKEDIN_PASSWORD="your-password"
export INDEED_USERNAME="[email protected]"
export INDEED_PASSWORD="your-password"
export JOBSPY_CREDS=1
import { scrapeJobs } from 'jobspy-js';

// Credentials are automatically loaded from environment variables
const response = await scrapeJobs({
  site_name: ['linkedin', 'indeed'],
  search_term: 'data scientist',
  location: 'remote'
});

Conditional Authentication

import { scrapeJobs } from 'jobspy-js';

async function scrapeWithFallback(
  searchTerm: string,
  credentials?: ProviderCredentials
) {
  try {
    // Try anonymous scraping first
    console.log('Attempting anonymous scraping...');
    const response = await scrapeJobs({
      site_name: 'linkedin',
      search_term: searchTerm,
      use_creds: false
    });
    return response;
  } catch (error) {
    // Fall back to authenticated scraping if blocked
    console.log('Anonymous scraping blocked, using credentials...');
    const response = await scrapeJobs({
      site_name: 'linkedin',
      search_term: searchTerm,
      use_creds: true,
      credentials: credentials
    });
    return response;
  }
}

const creds: ProviderCredentials = {
  linkedin: {
    username: process.env.LINKEDIN_USERNAME!,
    password: process.env.LINKEDIN_PASSWORD!
  }
};

const jobs = await scrapeWithFallback('software engineer', creds);

Loading from Configuration File

// jobspy.json
{
  "profiles": {
    "default": {
      "linkedin": {
        "username": "[email protected]",
        "password": "your-password"
      },
      "indeed": {
        "username": "[email protected]",
        "password": "your-password"
      }
    }
  }
}
import { scrapeJobs } from 'jobspy-js';
import fs from 'fs';

interface Config {
  profiles: Record<string, ProviderCredentials>;
}

function loadCredentials(profileName: string = 'default'): ProviderCredentials {
  const config: Config = JSON.parse(
    fs.readFileSync('jobspy.json', 'utf-8')
  );
  return config.profiles[profileName];
}

const credentials = loadCredentials('default');

const response = await scrapeJobs({
  site_name: ['linkedin', 'indeed'],
  search_term: 'engineer',
  use_creds: true,
  credentials: credentials
});

Multi-Site Authentication

import { scrapeJobs, ProviderCredentials } from 'jobspy-js';

const allCredentials: ProviderCredentials = {
  linkedin: {
    username: process.env.LINKEDIN_USERNAME!,
    password: process.env.LINKEDIN_PASSWORD!
  },
  indeed: {
    username: process.env.INDEED_USERNAME!,
    password: process.env.INDEED_PASSWORD!
  },
  glassdoor: {
    username: process.env.GLASSDOOR_USERNAME!,
    password: process.env.GLASSDOOR_PASSWORD!
  }
};

const response = await scrapeJobs({
  site_name: ['linkedin', 'indeed', 'glassdoor'],
  search_term: 'senior developer',
  location: 'Boston, MA',
  use_creds: true,
  credentials: allCredentials,
  results_wanted: 100
});

Security Best Practices

Store Credentials Securely

// ❌ BAD: Hardcoded credentials
const response = await scrapeJobs({
  site_name: 'linkedin',
  linkedin_username: '[email protected]',
  linkedin_password: 'password123', // Never hardcode passwords!
  use_creds: true
});

// ✅ GOOD: Environment variables
const response = await scrapeJobs({
  site_name: 'linkedin',
  linkedin_username: process.env.LINKEDIN_USERNAME,
  linkedin_password: process.env.LINKEDIN_PASSWORD,
  use_creds: true
});

// ✅ GOOD: Secure credential store
import { scrapeJobs } from 'jobspy-js';
import keytar from 'keytar';

const credentials = {
  linkedin: {
    username: await keytar.getPassword('jobspy', 'linkedin_username') || '',
    password: await keytar.getPassword('jobspy', 'linkedin_password') || ''
  }
};

const response = await scrapeJobs({
  site_name: 'linkedin',
  search_term: 'engineer',
  use_creds: true,
  credentials: credentials
});

Validate Credentials Before Use

import { ProviderCredentials } from 'jobspy-js';

function validateCredentials(
  creds: ProviderCredentials,
  requiredProviders: string[]
): boolean {
  for (const provider of requiredProviders) {
    const providerCreds = creds[provider as keyof ProviderCredentials];
    if (!providerCreds?.username || !providerCreds?.password) {
      console.error(`Missing credentials for ${provider}`);
      return false;
    }
  }
  return true;
}

const credentials: ProviderCredentials = {
  linkedin: {
    username: process.env.LINKEDIN_USERNAME || '',
    password: process.env.LINKEDIN_PASSWORD || ''
  }
};

if (validateCredentials(credentials, ['linkedin'])) {
  const response = await scrapeJobs({
    site_name: 'linkedin',
    search_term: 'developer',
    use_creds: true,
    credentials: credentials
  });
} else {
  console.error('Invalid credentials. Please set LINKEDIN_USERNAME and LINKEDIN_PASSWORD.');
}

Environment Variables

JobSpy JS automatically loads credentials from these environment variables:
ProviderUsername VariablePassword Variable
LinkedInLINKEDIN_USERNAMELINKEDIN_PASSWORD
IndeedINDEED_USERNAMEINDEED_PASSWORD
GlassdoorGLASSDOOR_USERNAMEGLASSDOOR_PASSWORD
ZipRecruiterZIPRECRUITER_USERNAMEZIPRECRUITER_PASSWORD
BaytBAYT_USERNAMEBAYT_PASSWORD
NaukriNAUKRI_USERNAMENAUKRI_PASSWORD
BDJobsBDJOBS_USERNAMEBDJOBS_PASSWORD
Set JOBSPY_CREDS=1 to enable authenticated scraping by default.

Notes

  • Authenticated scraping should only be used when anonymous scraping fails or is rate-limited.
  • Credentials are only used when use_creds: true is set in the parameters.
  • The credentials object takes precedence over individual username/password parameters.
  • Individual parameters take precedence over environment variables.
  • Never commit credentials to version control. Use .env files or secure credential stores.
  • Some job boards may have terms of service that restrict automated access even with valid credentials.
  • Failed authentication attempts may temporarily lock your account on some platforms.

Build docs developers (and LLMs) love