# Seek Jobs Scraper | $2.99 / 1k | (`glasswing/seek-jobs-scraper`) Actor

Scrape Seek job ads across Australia and New Zealand. One row per listing with title, company, suburb, salary parsed to min and max, work type, classification, listing date and the full ad text. Export to CSV, JSON or Excel.

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

## Pricing

from $2.99 / 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does Seek Jobs Scraper do?

Get every job ad on Seek as a clean spreadsheet row: job title, company, suburb, the advertised salary parsed into `salaryMin` and `salaryMax`, work type, industry classification, listing date and the full ad text. It is built for recruiters, job boards and labour-market analysts who need Australian and New Zealand job listings in bulk instead of one browser tab at a time.

Type a keyword and a location - `software engineer` in `Sydney NSW`, `registered nurse` in `Auckland` - and **scrape Seek jobs** into JSON, CSV or Excel, or read them straight from the Apify API. The Actor covers both Seek sites, `seek.com.au` (Australia) and `seek.co.nz` (New Zealand), so it doubles as a practical **Seek API alternative** and a general **Australian job listings API** when you have no documented feed to build on.

No headless browser, no residential proxies, no scraper to maintain. The default 20-job run, descriptions included, finished in **9.9 seconds** on the Apify platform.

It does not log in, does not read anything behind a paywall or a login wall, and does not work around access controls. It reads only the job data Seek serves publicly to anonymous visitors.

### Use cases for this Seek scraper

- **Recruitment agency building a client pipeline.** Pull every engineering ad posted in Melbourne VIC in the last 7 days, sort by `company` and `listingDate`, and call the employers who started hiring this week - ten open roles is a budget you can see.
- **Market researcher tracking salary trends.** `salaryMin`, `salaryMax` and `salaryPeriod` are parsed from the advertised label, so you can chart pay bands per role, suburb or `classification`, then re-run the same search monthly to build a time series.
- **Job board or aggregator seeding listings.** Schedule one run per keyword, export the ads with `descriptionText` and `bulletPoints`, and fill a niche board (nursing, trades, remote tech) with complete, first-party ad copy instead of thin stubs.
- **Sales team finding companies that are hiring.** A company advertising for Salesforce admins is a company buying Salesforce services. Filter on `classification`, `subClassification` and `listingDate` to hand your reps a weekly list of accounts with fresh hiring intent.
- **Workforce or policy analyst measuring a regional labour market.** Group by `area`, `countryCode` and `classification` to track vacancy volumes across Sydney, Auckland or an entire state over time.
- **Careers product exporting job ads to CSV.** Power a job-matching feature, a "who is hiring for X" newsletter or an internal dashboard from a scheduled dataset export.

### What data you get from every Seek job ad

One row per job ad. Every column below exists in the dataset schema; the **Overview** table view shows `title`, `company`, `location`, `salary`, `workType`, `listingDate`, `url`, `status`, `error` and `scrapedAt`.

**Row status and provenance**

| Field | Type | Description |
|---|---|---|
| `url` | string | Public job page, e.g. `https://www.seek.com.au/job/94002068`. On `not_found` / `error` rows this is the request that failed. |
| `status` | string | `ok`, `not_found` or `error` (see the table below). |
| `error` | string | Reason when `status` is not `ok`. Absent on `ok` rows. |
| `scrapedAt` | string | ISO 8601 time the row was extracted. |
| `site` | string | `seek.com.au` or `seek.co.nz`. |
| `keyword` | string | The search keyword that produced this row. |

**Job and employer**

| Field | Type | Description |
|---|---|---|
| `id` | string | Seek job id, e.g. `94002068`. |
| `title` | string | Job title as advertised. |
| `company` | string | Advertiser or employer name shown on the ad. Absent on ads posted as "Private Advertiser". |
| `companyProfileUrl` | string | Seek company profile URL, when the employer has one. |

**Location**

| Field | Type | Description |
|---|---|---|
| `location` | string | Location label as displayed, e.g. `Surry Hills, Sydney NSW`. |
| `area` | string | Metropolitan area or region part of the location, e.g. `Sydney NSW`. |
| `suburb` | string | Suburb part of the location, when the ad has one. |
| `countryCode` | string | `AU` or `NZ`. |

**Pay**

| Field | Type | Description |
|---|---|---|
| `salary` | string | Salary exactly as the advertiser wrote it, e.g. `$160k to $180k + super`. Absent when the ad shows no salary. |
| `salaryMin` | number | Lower bound parsed from `salary` (best effort). |
| `salaryMax` | number | Upper bound parsed from `salary` (best effort). |
| `salaryPeriod` | string | `hour`, `day`, `week`, `month` or `year`, when it can be read from the label. |

**Role details**

| Field | Type | Description |
|---|---|---|
| `workType` | string | `Full time`, `Part time`, `Contract/Temp` or `Casual/Vacation`. |
| `workArrangement` | string | `Remote`, `Hybrid` or `On-site`, when the advertiser set it. |
| `classification` | string | Seek industry classification, e.g. `Information & Communication Technology`. |
| `subClassification` | string | Seek sub-classification, e.g. `Engineering - Software`. |

**Dates and listing lifecycle**

| Field | Type | Description |
|---|---|---|
| `listingDate` | string | ISO 8601 time the ad was listed. |
| `expiresAt` | string | ISO 8601 expiry time. Needs `includeDescription`. |
| `isExpired` | boolean | Whether Seek marks the ad as expired. Needs `includeDescription`. |
| `listingStatus` | string | Seek's own listing status, e.g. `Active`. Not the same thing as the row `status`. Needs `includeDescription`. |

**Ad copy**

| Field | Type | Description |
|---|---|---|
| `teaser` | string | Short teaser shown in the search results. |
| `bulletPoints` | array | Up to three highlight bullets from the ad. |
| `descriptionText` | string | Full job description as plain text, paragraphs and bullets preserved. Needs `includeDescription`. |
| `descriptionHtml` | string | The description in the advertiser's original HTML. Needs `includeDescriptionHtml`. |
| `descriptionError` | string | Set when only the description could not be fetched; the rest of the row is still valid list-level data. |

**Ad placement flags**

| Field | Type | Description |
|---|---|---|
| `isFeatured` | boolean | Seek's featured flag. |
| `isPremium` | boolean | The ad uses Seek's Premium display type. |
| `isStandOut` | boolean | The ad uses Seek's StandOut display type. |
| `displayType` | string | Raw Seek display type, e.g. `standard`. |
| `isLinkOut` | boolean | Applying happens on the advertiser's own site instead of on Seek. |

A missing field is honest: it means Seek did not publish that value for this ad, never a guess. Deliberately **not** collected: recruiter names, e-mail addresses, phone numbers and any other contact data - see the legal notice at the end.

#### Result status (tri-state output)

| `status` | Meaning | Billed? |
|---|---|---|
| `ok` | The job was found and extracted. | Yes |
| `not_found` | Seek answered, but nothing matches the search (no jobs for that keyword, location and filter combination). | No |
| `error` | Seek could not be read after retries (network error, challenge page, or an endpoint change). `error` says why. | No |

If only a job's description fails, you still get the full list-level row with `status: ok` and a `descriptionError` explaining the gap - you never lose a job because one extra request failed.

### How to scrape Seek job ads with this Actor

1. Open the Actor in Apify Console and click **Try for free**.
2. Type one or more **Keywords** (one per line), exactly as you would type them into the Seek search box.
3. Set the **Location** (`Sydney NSW`, `Auckland`, `All Australia`, ...) and pick the **Seek site**.
4. Set **Maximum results** - start with the default 20 to see the output shape - and optionally the posted-within, minimum-salary and work-type filters.
5. Click **Start**. The default input finishes in well under a minute; rows appear in the dataset as they are scraped.
6. Open the **Output** tab or **Export** the dataset as JSON, CSV, Excel, XML or HTML.

To automate it, use the **API** tab (Node.js, Python, curl examples) or add a **Schedule**.

### Input

Every field is optional - the prefilled values already produce a complete run. See the **Input** tab for the full schema.

| Field | Type | Default | When to change it |
|---|---|---|---|
| `keywords` | array of strings | `["software engineer"]` | Set the roles you want. Each keyword is a separate search and a job found under several keywords is returned once; leave the list empty to take every job in the location. |
| `location` | string | `Sydney NSW` | Narrow or widen the geography: `Melbourne VIC`, `Brisbane QLD`, `Auckland`, `All Australia`, `All New Zealand`. Leave it empty for the whole country of the selected site. |
| `site` | string | `seek.com.au` | Switch to `seek.co.nz` for New Zealand ads; locations, currency labels and classifications follow the site you pick. |
| `maxItems` | integer | `20` | Raise it for production pulls, lower it while you shape the input. It counts rows across all keywords and is your main spending cap. |
| `includeDescription` | boolean | `true` | Turn it off for the fastest, list-level-only runs. With it on, each job costs one extra request and gains `descriptionText`, `expiresAt`, `isExpired`, `listingStatus` and a salary label when the search result had none. |
| `includeDescriptionHtml` | boolean | `false` | Turn it on when you need the advertiser's original markup in `descriptionHtml` (formatting, links). It roughly doubles the row size. |
| `postedWithinDays` | integer | empty (any date) | Set `1` on a daily schedule, or `7` for a weekly market snapshot, to collect only fresh ads. Accepts 1-31. |
| `salaryMin` | integer | empty (no filter) | Set it to skip ads below a pay threshold. Seek applies the filter itself, so ads without a disclosed salary are excluded by Seek. |
| `workType` | string | empty (all types) | Restrict to `Full time`, `Part time`, `Contract/Temp` or `Casual/Vacation` when only one employment model matters. |
| `proxyConfiguration` | object | Apify Proxy off | Leave it off - the Actor works from datacenter IPs. Enable the Apify Proxy datacenter group only if runs start returning `error` rows. |

Example input (exactly the prefilled default):

```json
{
    "keywords": ["software engineer"],
    "location": "Sydney NSW",
    "site": "seek.com.au",
    "maxItems": 20,
    "includeDescription": true,
    "includeDescriptionHtml": false,
    "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

You can download the dataset as JSON, CSV, Excel, XML or HTML. Here is a real row from a run of the example input above, with `descriptionText` trimmed for readability (in the dataset it is the whole ad, 3,192 characters):

```json
{
    "url": "https://www.seek.com.au/job/94002068",
    "status": "ok",
    "scrapedAt": "2026-09-08T10:34:11.303Z",
    "id": "94002068",
    "title": "Robotics Software Engineer",
    "company": "AEY & Associates",
    "location": "Sydney NSW",
    "area": "Sydney NSW",
    "countryCode": "AU",
    "salary": "$160k to $180k + super",
    "salaryMin": 160000,
    "salaryMax": 180000,
    "salaryPeriod": "year",
    "workType": "Full time",
    "workArrangement": "Hybrid",
    "classification": "Information & Communication Technology",
    "subClassification": "Engineering - Software",
    "listingDate": "2026-08-16T09:24:44Z",
    "expiresAt": "2026-09-15T09:24:00.000Z",
    "isExpired": false,
    "listingStatus": "Active",
    "teaser": "Build intelligent software for one of Australia's most exciting deep-tech engineering companies.",
    "bulletPoints": [
        "Solve complex problems spanning robotics, AI, computer vision, and software",
        "Experts across software, hardware, algorithms, sensing, and machine learning",
        "High ownership, challenging technical problems, and real-world impact"
    ],
    "descriptionText": "We're looking for experienced Software Engineers who enjoy solving difficult technical problems and building systems that perform reliably out in the field.\n\nWhat You'll Be Working On\n\n- Designing and building production-quality software for complex autonomous systems\n\n- Solving challenging engineering problems across robotics, sensing, AI, data processing, and distributed software\n\n...",
    "isFeatured": false,
    "isPremium": false,
    "isStandOut": false,
    "displayType": "standard",
    "isLinkOut": false,
    "site": "seek.com.au",
    "keyword": "software engineer"
}
```

A search that matches nothing produces one free row instead of an empty dataset:

```json
{
    "url": "https://www.seek.com.au/api/jobsearch/v5/search?siteKey=AU-Main&where=Sydney+NSW&page=1&keywords=underwater+basket+weaver",
    "status": "not_found",
    "error": "No jobs on seek.com.au match \"underwater basket weaver\" in Sydney NSW with the given filters",
    "scrapedAt": "2026-09-08T10:34:12.104Z"
}
```

### How much does it cost to scrape Seek?

This Actor uses **pay-per-event** pricing:

| Event | Price | Charged when |
|---|---|---|
| Actor start | $0.005 per run | Once when the run starts. The platform charges one event per GB of memory and the Actor runs on 1 GB, so this is one event. |
| Result | $0.00299 per job | One record with `status: ok` was saved to the dataset. |

**1,000 job ads cost about $3.00** ($0.005 to start plus 1,000 x $0.00299). You are never charged for a row with `status` `not_found` or `error`, and never for a duplicate: a job that turns up under several keywords or on two pages of the same search is emitted once, because the Actor deduplicates on the Seek job `id` for the whole run. The free Apify plan's $5 of monthly credit covers about 1,670 jobs in a single run.

You can cap spending per run with **Maximum results** and with the run's **Max total charge** option. When the charge limit is reached the Actor stops gracefully and keeps everything it has already saved.

### How it compares

This Actor is deliberately narrow and fast. It reads Seek's own public JSON over plain HTTP, which is why a 20-job run takes seconds rather than minutes and why it needs no browser, no proxy and no login. If you want broad Seek coverage across Australia and New Zealand with parsed salaries, full ad text and a tri-state row you can trust inside an automated pipeline, this is a good fit.

It is not for you if you need candidate data, applications or anything inside a Seek employer account; if you need Seek's other regional brands; if you need a vendor-backed, contractually stable data feed; or if you want one Actor that also covers other job boards. It reads a single public source, and says so honestly when that source changes.

### Integrations, exports and API access

Results export to **CSV, JSON, Excel**, XML and HTML from the **Output** tab or the dataset API. From there, Apify integrations and webhooks push the same rows into **Google Sheets, Airtable or a CRM**, plus Slack, Amazon S3 or your own endpoint - directly, or through Zapier, Make and n8n. Add a **Schedule** and yesterday's ads land in your sheet every morning.

The Actor can also be called from the **Apify API** (Node.js, Python and curl snippets are on the **API** tab), from the **Apify MCP server**, or by any AI agent that can call a tool: the inputs are plain strings and numbers, and every row carries `status` and `error`, so an agent can tell an empty search apart from a failure without parsing prose.

### Tips

- Keep `maxItems` small while you shape your input, then raise it. One keyword can return thousands of ads.
- Put several keywords in one run instead of running the Actor once per keyword: you pay the start fee once, and duplicates across keywords are removed automatically.
- Turn `includeDescription` off when you only need the list-level columns. That roughly halves the number of requests.
- Use `postedWithinDays: 1` on a daily schedule to collect only the ads posted since yesterday.
- `salary` is free text written by the advertiser. Filter on `salaryMin`/`salaryMax` for analysis and fall back to `salary` when they are empty - labels such as `Competitive` cannot be parsed into numbers.

### Limitations

- **Seek publishes no documented public API.** This Actor reads the same JSON endpoints the Seek website itself calls. They are undocumented, are covered by no stability promise, and can change without notice; when that happens rows come back as `error` and the Actor is fixed quickly (report it in the **Issues** tab with the run ID).
- **Australia and New Zealand only.** `seek.com.au` and `seek.co.nz` are supported. Seek's other regional brands (Jobstreet, Jobsdb) are not.
- **About 5,000 ads per keyword per run.** Each keyword is paged 100 ads at a time for at most 50 pages. Split deeper pulls by keyword, location or `postedWithinDays` across several runs.
- **Descriptions require `includeDescription`.** With it off, `descriptionText`, `descriptionHtml`, `expiresAt`, `isExpired` and `listingStatus` are absent, because the search endpoint does not carry them. With it on, every job costs one extra request.
- **Salary appears only when the advertiser disclosed it.** Many ads show no salary at all, and `salaryMin`/`salaryMax` are a best-effort parse of a free-text label, not a number Seek provides.
- **No candidate data and no applications.** The Actor reads job ads only; it cannot see applicants, employer dashboards or anything behind a Seek login.
- **A row is a snapshot.** Ads are edited and removed constantly, so re-run the Actor to refresh. A job that disappears between the search and the detail request is still delivered as an `ok` row carrying a `descriptionError`.

### FAQ

**Do I need a Seek login, an account or an API key?** No. The Actor reads the same public job data an anonymous visitor sees, so all you need is an Apify account. There is no login step and no key to manage.

**How do I get more results?** Raise `maxItems` - it is the only limit that stops a run early. Beyond about 5,000 ads per keyword, add more keywords, split the search by location, or run a daily schedule with `postedWithinDays: 1` and let the results accumulate in one dataset.

**How often does the data change?** Constantly. Seek ads are posted, edited and expired every hour, and most listings run for about 30 days. For a moving market picture, schedule a daily or weekly run rather than treating one export as permanent.

**What happens if Seek changes its site?** Rows come back with `status: error` and a reason instead of silently wrong data, so your pipeline can alert on it. Report it in the **Issues** tab with the run ID and the Actor is updated; you are not billed for `error` rows in the meantime.

**Does it work for New Zealand?** Yes. Set `site` to `seek.co.nz` and use a New Zealand location such as `Auckland`, `Wellington` or `All New Zealand`.

**Can I use this Actor from an AI agent or MCP client?** Yes. Inputs are plain strings and numbers, every row is self-describing (`status` plus `error`), and results can be fetched through the dataset API or the Apify MCP server.

**Why did I get fewer rows than `maxItems`?** The search matched fewer jobs than you asked for, or the run hit your **Max total charge** limit. The run log says which - look for "Stopping gracefully".

**Why is a field missing from a row?** Optional fields are omitted when Seek does not publish them for that ad - many ads carry no salary, no suburb or no work arrangement. If a field that should always be there is missing, open an issue in the **Issues** tab with the run ID.

### Legal and data-protection notice

Job advertisements are **business data**: a company, a role, a location, a pay range and ad copy written for the public to read. This Actor extracts only that, and only from pages Seek publishes publicly. It does not log in, does not read anything behind an access control, and does not attempt to defeat one.

**No recruiter names, e-mail addresses or phone numbers are collected.** Seek's job endpoint can return contact details (`phoneNumber`, `contactMatches`); this Actor's query deliberately does not ask for them, and no output column holds contact data, a personal profile or a photo. The only free text in a row is the advertiser's own ad copy in `teaser`, `bulletPoints` and `descriptionText`/`descriptionHtml`: if an advertiser typed a contact detail into the body of their ad it will be in there, so turn `includeDescription` off if you do not want the ad body at all.

Your results could still contain personal data. Personal data is protected by the GDPR in the European Union, by the Privacy Act 1988 in Australia, by the Privacy Act 2020 in New Zealand, and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with Seek's terms of service and applicable law when using the extracted data.

This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by Seek Limited or its owners. All trademarks belong to their respective owners.

# Actor input Schema

## `keywords` (type: `array`):

Search terms, one per line, exactly as you would type them into the Seek search box (e.g. `software engineer`, `registered nurse`, `forklift driver`). Each keyword is a separate search; jobs found under several keywords are returned once. Leave empty to list all jobs in the location.

## `location` (type: `string`):

Where to search, as Seek understands it: a city or region such as `Sydney NSW`, `Melbourne VIC`, `Brisbane QLD`, `Auckland`, `Wellington`, or `All Australia` / `All New Zealand`. Leave empty for the whole country of the selected site.

## `site` (type: `string`):

Which Seek site to search: `seek.com.au` (Australia) or `seek.co.nz` (New Zealand).

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

Stop after this many rows have been saved to the dataset (across all keywords). Each saved row with status `ok` is one billable result. Keep it small for test runs.

## `includeDescription` (type: `boolean`):

Fetch each job's detail (one extra request per job) to add `descriptionText`, `expiresAt`, `isExpired`, `listingStatus` and a salary label when the search result had none. Turn off for the fastest, list-level-only runs.

## `includeDescriptionHtml` (type: `boolean`):

Adds `descriptionHtml` (the ad's original HTML) next to `descriptionText`. Only applies when `Include full job description` is on. Roughly doubles the row size.

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

Only jobs listed in the last N days (1-31). Leave empty for any listing date.

## `salaryMin` (type: `integer`):

Only jobs whose advertised annual salary is at least this amount (in the site's currency, e.g. `100000`). Uses Seek's own salary filter, so jobs without a disclosed salary are excluded by Seek.

## `workType` (type: `string`):

Restrict to one Seek work type. Leave empty for all.

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

Optional. The Actor calls Seek's public JSON endpoints over plain HTTP and works from datacenter IPs without a proxy. Enable Apify Proxy (datacenter group) only if runs fail with 403/challenge errors; residential proxies are not needed.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "Sydney NSW",
  "site": "seek.com.au",
  "maxItems": 20,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "keywords": [
        "software engineer"
    ],
    "location": "Sydney NSW",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("glasswing/seek-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 = {
    "keywords": ["software engineer"],
    "location": "Sydney NSW",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("glasswing/seek-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 '{
  "keywords": [
    "software engineer"
  ],
  "location": "Sydney NSW",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call glasswing/seek-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,glasswing/seek-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/LErKQgrOHjXNcneI9/builds/j2FaieRJAOucUQx1L/openapi.json
