# Indeed Jobs Scraper — Salary, Rating, Full Description (`foxlabs/indeed-jobs-scraper`) Actor

Indeed job postings with the published salary (structured min/max), the employer's star rating and the full job description. Search by keyword, location, country, posting date, remote and minimum salary. One row per job, closed and placeholder listings are dropped and never charged.

- **URL**: https://apify.com/foxlabs/indeed-jobs-scraper.md
- **Developed by:** [Berkan Kaplan](https://apify.com/foxlabs) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 job postings

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

## Indeed Jobs Scraper — Salary, Rating & Full Description 🚀

**foXLabs hiring series:** [Job Postings Database](https://apify.com/foxlabs/job-postings-database) · [Greenhouse](https://apify.com/foxlabs/greenhouse-job-board-scraper) · [Lever](https://apify.com/foxlabs/lever-job-board-scraper) · [Ashby](https://apify.com/foxlabs/ashby-job-board-scraper) · [Workday](https://apify.com/foxlabs/workday-job-board-scraper) · [SmartRecruiters](https://apify.com/foxlabs/smartrecruiters-job-board-scraper) · [Personio](https://apify.com/foxlabs/personio-job-board-scraper) · [Teamtailor](https://apify.com/foxlabs/teamtailor-job-board-scraper) · [Workable](https://apify.com/foxlabs/workable-ats-scraper) · [BambooHR](https://apify.com/foxlabs/bamboohr-ats-scraper) · [Google Jobs](https://apify.com/foxlabs/google-jobs-scraper)

🎉 Indeed job postings as clean rows: the **published salary as structured numbers** (min, max, period), the **employer's star rating and review count**, the **full job description** (measured median 3,695 characters), location, posting date, employment type and a direct link. Search by keyword, location, country, posting age, remote and minimum salary.
Built for sales & competitive-intelligence teams scoring hiring intent, recruiters, job boards and salary-data pipelines.

### 🔍 What is the Indeed Jobs Scraper — and when should you use it?

Indeed is the largest job aggregator in most countries, and it publishes two things that company career sites usually do not: a **salary estimate or range** and an **employer rating**. This Actor reads Indeed's own search payload (not fragile HTML selectors), then opens each posting to add the full description and the employer's structured salary from the posting's own metadata.

**Use it when you need:** salary benchmarks by role and city · employers hiring for a function right now, with their rating · a job feed with full descriptions for an LLM pipeline · a daily list of new postings in a market.

**Use something else when:** you want every open role of specific companies straight from their own careers site — then use the **foXLabs hiring series** above, or [Job Postings Database](https://apify.com/foxlabs/job-postings-database), which keeps a daily-refreshed index of 440,000+ roles from ~33,000 Greenhouse, Lever, Ashby, SmartRecruiters, BambooHR, Personio and Teamtailor boards and answers one query across all of them.

**How coverage works — read this before you set `maxItems`.** Indeed puts **deep pagination behind a login**: page 2 of any search redirects to its sign-in screen (measured 2026-10-20, with a real browser). This Actor therefore does not page — **each keyword × location pair returns up to ~45 postings**, and coverage grows by adding more pairs. Want 1,000 nursing jobs in Texas? Give 25 city lines instead of one state line. No Actor can give you Indeed's full result set without an account, and this one will not pretend otherwise.

### 🤖 Use with AI agents

**Already on the Apify MCP server?** Ask for this Actor by name: `foxlabs/indeed-jobs-scraper`.

**Your agent can pay for its own runs.** This Actor is pay-per-event with agentic payments, so an agent can discover it, run it and settle the bill over **x402 (USDC on Base)** or **Skyfire** — no Apify account or API token of its own. Billing is $0.005 per search that delivered rows plus $0.002 per delivered posting ($0.004 more when its full description comes back); errors, blocked pages and searches that find nothing are free.

Otherwise paste this into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```
I want Indeed job postings with salary and employer rating using the Apify Actor `foxlabs/indeed-jobs-scraper`.
Input: `queries` is a list of job titles/keywords, `locations` is a list of cities or states.
Each keyword × location pair returns up to ~45 postings (Indeed hides deeper pages behind a login),
so to widen coverage add more pairs rather than raising `maxItems`.
Optional: `country` (us, uk, de, ca, au…), `postedWithinDays` (1|3|7|14), `remote` (any|only|exclude),
`minSalary` (yearly), `withDescription` (true adds the full description; it costs one extra bulk request per search, not one page per posting).
Start with: {"queries":["registered nurse"],"locations":["Texas"],"maxItems":50,"withDescription":true}
Ask me which roles and cities I care about, run the Actor, then summarise salary ranges per city as a table.
```

The machine-readable API, MCP config and OpenAPI definition live at `apify.com/foxlabs/indeed-jobs-scraper.md`.

### 📋 Overview

Why teams pick this one:

- 💰 **Salary as numbers, not a string** — `salaryMin`, `salaryMax`, `salaryPeriod`, `salaryCurrency`. A one-sided range ("From $50 an hour") returns `salaryMax: null`, never Indeed's internal `-1`.
- ⭐ **Employer rating + review count** on the same row. No rating means `null`, not a misleading `0`.
- 📝 **Full description on every row** — measured 47 of 47 postings, median 3,847 characters. All descriptions of one keyword × location slice arrive in a **single extra request**, so turning them on costs seconds, not minutes.
- 🎁 **Benefits as a list** — `401(k)`, `Dental insurance`, `Tuition reimbursement`… published on 67% of postings in measurement. Most Indeed scrapers never surface this.
- 🗓️ **Real dates** — `postedAt` and `createdAt` as ISO timestamps, 100% filled in measurement.
- 🏷️ **Job type and schedule** — `employmentType` 83% filled, `schedule` ("Monday to Friday", "Day shift") where Indeed publishes it, plus Indeed's own tag list.
- 🚫 **No decoy rows.** Indeed's result DOM carries placeholder job keys that lead nowhere; rows are built only from the page's embedded job data, so a decoy is never delivered or charged.
- 🌍 **23 country sites** — us, uk, ca, au, de, fr, nl, es, it, ie, in, sg, nz, za, pl, se, ch, at, be, br, mx, tr, ae.

### ✨ Features

- 🔎 Keyword × location slicing with automatic de-duplication across slices
- 💵 `minSalary` filter that converts hourly, weekly and monthly pay to a yearly figure
- 🏠 `remote` filter that never guesses: unknown stays unknown (`isRemote: null`)
- ⏱️ `postedWithinDays` (1, 3, 7, 14 — the windows Indeed itself accepts)
- 📄 `withDescription` toggle: one bulk request per slice, so the full text costs almost no extra time
- 🧾 One flat row shape, same keys in the same order, every time
- 🤖 MCP + x402 ready, with input and output schemas published

### 🎬 Quick Start

```bash
curl -X POST "https://api.apify.com/v2/acts/foxlabs~indeed-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["registered nurse"], "locations": ["Texas"], "maxItems": 20, "withDescription": true}'
```

### 🚀 Getting Started (3 steps)

1. **Say what you are looking for** — one or more `queries` (job titles or keywords).
2. **Say where** — `locations` (cities or states as Indeed spells them) and, if not the US, a `country`.
3. **Run it.** Rows arrive in the dataset as they are found; set `withDescription: false` for a quick, cheap scan first.

### 📥 Input

```json
{
  "queries": ["registered nurse", "nurse practitioner"],
  "locations": ["Houston, TX", "Austin, TX", "Dallas, TX"],
  "country": "us",
  "maxItems": 200,
  "withDescription": true,
  "postedWithinDays": "7",
  "remote": "any",
  "minSalary": 70000
}
```

| field | type | default | what it does |
|---|---|---|---|
| `queries` | array | — | Job titles / keywords, one search line each |
| `locations` | array | — | Cities, states or regions; empty = whole country |
| `country` | enum | `us` | Which national Indeed site (23 supported) |
| `maxItems` | integer | `100` | Hard cap on delivered postings (max 5,000) |
| `withDescription` | boolean | `true` | Add the full description to every row (one bulk request per slice) |
| `postedWithinDays` | enum | — | `1`, `3`, `7` or `14` |
| `remote` | enum | `any` | `any`, `only`, `exclude` |
| `minSalary` | integer | — | Keep postings whose published yearly salary reaches this |
| `proxyConfiguration` | object | Unblocker | Indeed refuses plain and datacenter requests and challenges residential IPs; Apify's Unblocker is the default and should stay |

At least one `queries` or `locations` entry is required. A bad value is a stated error, never a silently ignored filter.

### 📤 Output

| field | type | notes |
|---|---|---|
| `jobId` | string | Indeed's job key (16 hex chars) |
| `title` · `companyName` | string | 100% filled in measurement |
| `companyRating` · `companyReviewCount` | number | null | `null` when the employer has no rating |
| `companyUrl` | string | null | Indeed company profile |
| `location` · `city` · `state` · `country` | string | As published |
| `isRemote` | boolean | null | `null` when Indeed does not say |
| `salaryText` | string | null | Indeed's own wording, e.g. `From $50 an hour` |
| `salaryMin` · `salaryMax` | number | null | One-sided range → the missing end is `null` |
| `salaryPeriod` | string | null | `hour`, `day`, `week`, `month`, `year` |
| `salaryCurrency` | string | null | ISO code |
| `employmentType` | string | null | `Full-time`, `Part-time`, `Contract`… 83% filled in measurement |
| `schedule` | string | null | `Monday to Friday`, `Day shift`, `8 hour shift` |
| `benefits` | array | null | `401(k)`, `Dental insurance`, `Paid time off`… `null` when none is published |
| `tags` | array | Every Indeed attribute on the card |
| `snippet` | string | Short teaser from the result list |
| `description` | string | null | Full text, plain (only with `withDescription`) |
| `postedAt` · `createdAt` | ISO date | null | |
| `sponsored` · `easyApply` | boolean | |
| `url` | string | Canonical `https://<site>/viewjob?jk=…` |
| `searchQuery` · `searchLocation` · `scrapedAt` | string | Which slice produced the row |

```json
{
  "jobId": "4c58818367959016",
  "title": "Private Duty Nurse (RN) – Concierge In-Home Care",
  "companyName": "Home Care Assistance",
  "companyRating": 3.8,
  "companyReviewCount": 251,
  "location": "San Antonio, TX 78215",
  "isRemote": false,
  "salaryText": "From $50 an hour",
  "salaryMin": 50,
  "salaryMax": null,
  "salaryPeriod": "hour",
  "salaryCurrency": "USD",
  "employmentType": "Contract",
  "schedule": "8 hour shift",
  "benefits": ["401(k)", "Dental insurance", "Paid time off"],
  "tags": ["Contract", "8 hour shift", "Flexible schedule"],
  "postedAt": "2026-10-14T05:00:00.000Z",
  "easyApply": false,
  "url": "https://www.indeed.com/viewjob?jk=4c58818367959016"
}
```

### 💼 Use cases

**Salary benchmarking by city**
Input: `{"queries":["registered nurse"],"locations":["Houston, TX","Austin, TX","Dallas, TX"],"withDescription":false}`
Output: rows with `salaryMin`/`salaryMax`/`salaryPeriod` per city.
Use: build a pay-band table, or price your own job ad against the market.

**Hiring-intent lead list**
Input: `{"queries":["sales manager"],"locations":["Germany"],"country":"de","postedWithinDays":"7"}`
Output: employers that posted in the last week, with rating and review count.
Use: hand sales a list of companies that are visibly growing a function.

**Description corpus for an LLM**
Input: `{"queries":["data engineer"],"locations":["Remote"],"withDescription":true,"maxItems":500}`
Output: full descriptions averaging ~4,000 characters.
Use: extract required skills, tools and seniority signals at scale.

### 🔗 Integration

**JavaScript**

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('foxlabs/indeed-jobs-scraper').call({
    queries: ['registered nurse'],
    locations: ['Texas'],
    maxItems: 50,
    withDescription: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]?.salaryText);
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("foxlabs/indeed-jobs-scraper").call(run_input={
    "queries": ["registered nurse"],
    "locations": ["Texas"],
    "maxItems": 50,
})
## apify-client 3.x returns a Run object; with client 1.x/2.x use run["defaultDatasetId"]
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item["title"], item["salaryText"])
```

**n8n / Zapier / Make:** use the Apify integration, pick this Actor, and map `title`, `companyName`, `salaryMin`, `salaryMax`, `url` into your sheet, CRM or Slack message.

### 📊 Pricing

Pay per event, no monthly rental:

| event | price | when |
|---|---|---|
| `apify-actor-start` | **$0.00005** | once per run (per GB of run memory; the default 512 MB run counts as one) |
| `keyword-search` | **$0.005** | one keyword × location search that delivered at least one posting |
| `job` | **$0.002** | one delivered posting |
| `job-description` | **$0.004** | only when a full description was actually returned |

A list-only run (`withDescription: false`) costs $0.002 per posting. With descriptions, a posting costs $0.006 — and if Indeed does not return a description for a row, the description event is **not** charged.

The search fee exists because the cost of a search is fixed per keyword × location pair: one result page plus one bulk request that brings every description of that page. A full search of ~45 postings therefore bills $0.005 on top of $0.27 of postings — **1.8% of the invoice**. You only ever pay it for a search that actually delivered rows, and a 5-keyword × 3-city run pays it at most 15 times.

Never billed: blocked pages, network errors, searches that return nothing, rows without a description (the description event), postings filtered out by your own settings, and runs that deliver nothing. A run that cannot reach Indeed at all fails instead of reporting "no results".

### ❓ FAQ

#### Why do I only get ~45 postings per keyword and location?

Because Indeed hides deeper pages behind a login: page 2 of a search redirects to its sign-in screen. Measured on 2026-10-20 with a real browser, both on the desktop and the mobile site. Coverage grows by slicing — more keywords, more cities, narrower `postedWithinDays` windows — not by paging.

#### Do I need an Indeed account?

No. This Actor never logs in and never asks you for credentials.

#### How often is a salary published?

Indeed shows a salary on part of its listings. In our measurements the share ranged between **40% and 83%** depending on the query, so we do not promise a single number. With `minSalary` set, postings without a published salary are skipped — that is deliberate, so a filter never passes rows it could not check.

#### Why is `salaryMax` sometimes null when `salaryText` says a number?

"From $50 an hour" and "Up to $120,000 a year" are one-sided. Indeed marks the missing end with `-1` internally; we return `null` instead of a nonsense value.

#### Why is `companyRating` null for some employers?

Indeed sends `0` when an employer has no rating yet. A zero would read as a one-star employer, so we return `null`.

#### How are the descriptions fetched — isn't that slow?

No. The Actor does not open one page per posting. It asks Indeed's own bulk description endpoint for every job key of a slice at once: measured 47 keys in a single request, 1.4 seconds, 47 of 47 descriptions returned. That is also why a description never needs an Indeed login.

#### What is the `keyword-search` fee for?

Each keyword × location search costs us the same whether it yields 1 posting or 45: one result page plus one bulk description request. The $0.005 fee covers that fixed part, so the per-posting price can stay at $0.002 instead of carrying it. On a full search it is 1.8% of the bill, and a search that is blocked or finds nothing is never charged.

#### Why is `validThrough` not in the output?

It only exists on the posting page, and that page is behind Indeed's login wall (measured HTTP 401 on 2026-10-20, on every route we tried). We would rather drop a field than ship a column that is empty.

#### Can it run as a real-time API?

The default build is the batch/x402 version. A Standby ("… API") sibling can be published from the same code if there is demand — tell us.

#### Which countries are supported?

us, uk, ca, au, de, fr, nl, es, it, ie, in, sg, nz, za, pl, se, ch, at, be, br, mx, tr, ae.

### 🐛 Troubleshooting

- **Run failed with "could not be loaded" or "blocked"** — Indeed refuses plain and datacenter requests (HTTP 403 "Security Check") and challenges residential IPs with Cloudflare. The default `proxyConfiguration` uses Apify's Unblocker, which gets through; if you replaced it, put it back. Nothing is charged in that case.
- **"No job postings matched"** — the message names the filters that emptied the result. Try removing `minSalary` (it drops postings without a published salary) or widening `postedWithinDays`.
- **Descriptions missing** — rerun the slice; the bulk endpoint occasionally answers for only part of a batch, and rows without a description are not charged for one.
- **Fewer rows than `maxItems`** — see the FAQ: coverage comes from slices, not from paging.

### ⚠️ Trademark

Indeed is a trademark of Indeed, Inc. This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Indeed.

### ⚖️ Is it legal to scrape this data?

This Actor reads only publicly visible job postings — no login, no personal data about candidates, no private employer data. Public-data scraping is broadly lawful in the EU and the US, but a website's terms of service are a separate matter from the law: Indeed's terms restrict automated collection, so review your own use case, keep volumes reasonable, and do not republish Indeed's content as your own. You are responsible for how you use the output, including GDPR/CCPA duties if you enrich it with personal data.

### 🤝 Support & contact

- Issues and feature requests: the **Issues** tab of this Actor
- Website: [foxlabs.com.tr](https://foxlabs.com.tr)
- More Actors: [apify.com/foxlabs](https://apify.com/foxlabs)

### Changelog

See `CHANGELOG.md` in the Actor's source for the full history.

#### 0.1.10 — 2026-10-20

- README fix: the AI-agent prompt still described the pre-0.1.5 architecture ("one extra page per posting") and the agent billing line left out the search and description events. No code, input, output or price change.

#### 0.1.9 — 2026-10-20

- New `keyword-search` event ($0.005), charged once per keyword × location search that delivered at least one posting — 1.8% of a full 45-posting search. Blocked, failed and empty searches stay free.

#### 0.1.6 — 2026-10-20

- Default run memory 512 MB (measured peak 58 MB): a 15-posting run finishes in 6 seconds.
- Pricing published: `job` $0.002, `job-description` $0.004, `apify-actor-start` $0.00005.

#### 0.1.5 — 2026-10-20

- Descriptions now come from Indeed's own bulk endpoint — 47 of 47 in a single request — instead of one page per posting, which also removes the login wall those pages hit.
- New columns: `benefits` (67% filled) and `schedule`. `employmentType` now reads Indeed's taxonomy (83% filled instead of 6%).
- `validThrough` removed: its only source is the login-walled posting page.
- `salaryCurrency` is no longer filled when no salary figure is published.
- `detailDelayMs` removed — there are no posting pages left to pace.

#### 0.1 — 2026-10-20

- First release. Keyword × location slicing, structured salary, employer rating, full description from the posting's structured metadata, 23 country sites, pay-per-event billing with the description event charged only when a description is returned.

# Changelog

This Actor's version history is a separate document: https://apify.com/foxlabs/indeed-jobs-scraper/changelog.md

# Actor input Schema

## `queries` (type: `array`):

One search line per entry, exactly what you would type into Indeed's search box ("registered nurse", "backend engineer"). Each line is searched on its own, and each line × location pair returns up to ~45 postings — Indeed puts deeper pages behind a login, so add more lines (or more locations) for more coverage.

## `locations` (type: `array`):

Cities, states or regions as Indeed spells them ("Texas", "Austin, TX", "Remote"). Leave empty to search the whole country.

## `country` (type: `string`):

Which national Indeed site to search.

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

Hard cap on delivered postings across all query slices.

## `withDescription` (type: `boolean`):

Adds the full job description to every row (measured: 47 of 47 postings, median 3,847 characters). All descriptions of one query slice are fetched in a single extra request, so this is fast; the description event is only charged when a description is actually returned.

## `postedWithinDays` (type: `string`):

Only postings published in the last N days. Indeed accepts 1, 3, 7 or 14 only.

## `remote` (type: `string`):

Keep only remote postings, exclude them, or ignore the distinction. A posting whose remote status Indeed does not state is kept under "any" and never guessed.

## `minSalary` (type: `integer`):

Keep only postings whose published salary reaches this yearly figure (hourly and monthly pay is converted). Indeed publishes a salary on roughly 83% of postings; with this filter on, postings without a salary are skipped.

## `proxyConfiguration` (type: `object`):

Indeed refuses plain and datacenter requests (measured: HTTP 403 "Security Check") and challenges residential IPs with Cloudflare. Apify's Unblocker gets through and is the default — changing it will most likely break the run.

## Actor input object example

```json
{
  "queries": [
    "registered nurse",
    "nurse practitioner"
  ],
  "locations": [
    "Texas",
    "Austin, TX"
  ],
  "country": "us",
  "maxItems": 100,
  "withDescription": true,
  "postedWithinDays": "",
  "remote": "any",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "queries": [
        "registered nurse"
    ],
    "locations": [
        "Texas"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("foxlabs/indeed-jobs-scraper").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 = {
    "queries": ["registered nurse"],
    "locations": ["Texas"],
}

# Run the Actor and wait for it to finish
run = client.actor("foxlabs/indeed-jobs-scraper").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 '{
  "queries": [
    "registered nurse"
  ],
  "locations": [
    "Texas"
  ]
}' |
apify call foxlabs/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

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/J1mKWl8dZem4moehe/builds/ZTFgwfn7TgfJ8RD4l/openapi.json
