# Jobs API: Greenhouse, Lever, Workday, Keka (India) (`pk07007/ats-jobs-api`) Actor

Search 6,800+ company career sites across 24 ATS (Greenhouse, Lever, Ashby, Workday, Keka). India IT coverage: HCL, Infosys, Wipro, Accenture. Filter by keyword, country, city, remote, posted date. Direct apply URLs, refreshed every 24h. Not LinkedIn or Indeed.

- **URL**: https://apify.com/pk07007/ats-jobs-api.md
- **Developed by:** [Pratham Israni](https://apify.com/pk07007) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## India + ATS Career Site Jobs API

Search **6,801 company career sites** across **24 ATS platforms** — Greenhouse, Lever, Ashby, Workday, Zoho Recruit, Keka, RippleHire, and more.

Built for **India IT services** coverage (HCL, Infosys, Wipro, Accenture, Capgemini, Zoho) that most US-based job APIs don't track. Direct employer apply URLs, not aggregator redirects. Not LinkedIn, Indeed, or Naukri.

This is a **nightly-refreshed index**, not a live scrape per run. Every row carries `lastSeenAt` — the last time the refresh confirmed that posting was still on the employer's own board, not a one-time snapshot.

### Quick start

Default input (cheap, fast — a few seconds, ~25 results):

```json
{
  "keywords": "software engineer",
  "countries": ["India"],
  "postedWithinDays": 7,
  "maxItems": 25
}
```

Incremental / only-new (for a scheduled recurring run):

```json
{
  "keywords": "software engineer",
  "countries": ["India"],
  "postedAfter": "2026-10-01",
  "maxItems": 100
}
```

You're billed per matched job actually returned, not for the size of the underlying index.

### Coverage (measured 2026-10-02)

| | |
|---|---|
| Active jobs | 310,357 |
| Companies | 6,801 |
| Sources | 24 ATS / career-site feeds |
| Refresh | Nightly — `lastSeenAt` on every row |

Single-employer feeds (not multi-tenant ATS platforms): Amazon, Netflix, Accenture, HCLTech, and similar — filter with `ats` or `company`.

### Input

| Field | What it does |
|---|---|
| `keywords` | Comma-separated search terms, matched against title + company (full-text, prefix-matched — "engineer" matches "Engineering") |
| `countries` | Country names; aliases accepted (usa, uk, uae) |
| `city` | City names; common spelling variants normalized |
| `workModes` | `remote`, `hybrid`, `onsite` |
| `ats` | Source filter — most are multi-tenant ATS platforms, a few are single-employer feeds |
| `company` | Exact company name(s) |
| `postedWithinDays` | Relative freshness window |
| `postedAfter` | `YYYY-MM-DD` — use for scheduled, only-new runs |
| `maxItems` | Cap on returned rows. Default 25, kept low so a first run is cheap |

### Sample output

```json
{
  "id": "64698bc76e34a0db32dbf6f9c3affa24",
  "title": "Product Security Engineer, Senior",
  "company": "TraceLink, Inc",
  "companyDomain": "tracelink.com",
  "applyUrl": "https://www.tracelink.com/about/culture-and-careers/jobs?gh_jid=5244088007",
  "ats": "greenhouse",
  "city": "Pune",
  "country": "India",
  "isRemote": false,
  "postedAt": "2026-10-02",
  "lastSeenAt": "2026-10-02T14:04:22.434Z"
}
```

`id` is a stable hash of `applyUrl` — use it as the dedup key across separate runs.

### What this is for

- India / IT-services sourcing that needs HCL, Infosys, Wipro, Accenture, Capgemini coverage straight from the career site, not Naukri
- A filtered career-site feed for a newsletter or job board
- Recruiter watchlists — one query instead of visiting 50 separate career pages

### Limitations

- **No job descriptions in v1** — not stored. Title, location, apply URL, and dates only.
- **Not live.** The index refreshes roughly every 24 hours. If the freshest result in a run is older than ~36h, the Actor logs a warning rather than serving stale data silently.
- **Not LinkedIn, Indeed, or Naukri.** Employer career pages only. `applyUrl` reflects the source as of the last refresh; closed listings are dropped automatically.
- **`experienceMin` is almost never filled** — only 2 of 24 sources publish structured years-of-experience data. It's included in the output when present, not offered as a filter.
- **Field completeness** (measured 2026-10-02): `city` 32% null (78% on remote postings specifically), `country` 22%, `companyDomain` 24%, `postedAt` 8%.
- **Volume skews toward a few large employers** (Accenture, RippleHire, HCLTech). Use `company`/`ats` if you want to exclude that mix.
- **~0.07% of rows** can be the same real opening listed on two different sources — not cross-deduplicated.
- One aggregator source with tracking-redirect URLs (not the employer's own link) is excluded entirely.

### Notes

This Actor has no scraper of its own — it queries a backend index built from each source's public job board, refreshed nightly.

# Actor input Schema

## `keywords` (type: `string`):

Comma-separated search terms, matched against job title + company (full-text, prefix-matched — e.g. "engineer" matches "Engineering"). Leave empty to match all titles.

## `countries` (type: `array`):

Country names (e.g. India, United States). Case-insensitive, common aliases accepted (uae, usa, uk).

## `city` (type: `array`):

City names (e.g. Bengaluru, Pune). Common spelling variants are normalized automatically.

## `workModes` (type: `array`):

Filter by remote / hybrid / onsite. Leave empty for all.

## `ats` (type: `array`):

Filter by source. Most are multi-tenant ATS platforms; amazon/netflix/accenture are single-company feeds, not ATS platforms. Leave empty for all 24.

## `company` (type: `array`):

Exact company name(s) to filter by (e.g. Accenture, Stripe).

## `postedWithinDays` (type: `integer`):

Only return jobs posted within this many days.

## `postedAfter` (type: `string`):

Only return jobs posted on or after this date (YYYY-MM-DD). Use this instead of "Posted within" for recurring/incremental runs — pass yesterday's run date to get only new jobs.

## `maxItems` (type: `integer`):

Maximum number of jobs to fetch (and pay for). The run stops once this many results have been collected, or your Apify spending limit is reached, whichever comes first. Default is low (25) so a first "Try for free" run is cheap and fast — raise it for a real pull.

## Actor input object example

```json
{
  "keywords": "software engineer",
  "countries": [
    "India"
  ],
  "postedWithinDays": 7,
  "maxItems": 25
}
```

# Actor output Schema

## `jobListings` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("pk07007/ats-jobs-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("pk07007/ats-jobs-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call pk07007/ats-jobs-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pk07007/ats-jobs-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/XbcFbYzYBQ847N2qS/builds/pIdZX3sN1pZFGcluE/openapi.json
