# Company Career Page Jobs from a List of Websites (`usta/career-site-jobs`) Actor

Paste a list of company websites. The tool finds each careers page, works out which hiring system it runs on (Greenhouse, Lever, Ashby, Workable, Recruitee, Personio) and returns every open job from that system's public job list. One honest row for any company it cannot read. Pay per row.

- **URL**: https://apify.com/usta/career-site-jobs.md
- **Developed by:** [US Tech Automations](https://apify.com/usta) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 result rows

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

## Company Career Page Jobs from a List of Websites

This is a career site jobs tool, a company careers scraper, and an ATS jobs API for Greenhouse, Lever, Ashby, Workable, Recruitee and Personio jobs: paste company websites and get one row per open job from that company's public hiring-system job list.

It opens the page you give it. When that address is a homepage, it also opens at most three careers or jobs links found on that page. It names the hiring system from links in the HTML, then reads only that system's official public job list. A company it cannot read comes back as one error row. When the page names no hiring system, it tries the company's own name as a Greenhouse board and keeps that result only when the board's jobs link back to the same company site.

### Input

| Field | What you put in |
|---|---|
| **Company websites** | Required. Company homepages or careers-page addresses. At most 500. |
| **Title keywords** | Optional. Keep a job only when its title contains one of these words or phrases. Case does not matter. Leave empty for every job. |
| **Maximum jobs per company** | Default 200. The run stops adding jobs from that company at this number. |
| **Maximum rows** | Default 1,000. Hard cap 20,000. This is also the spend cap. |
| **Ids already seen** | Optional. Job ids or dedupe keys from an earlier run. A match is marked not new. |
| **Proxy configuration** | Optional Apify proxy. Off by default, including on a local run. |

### Pricing

**Pay per result.** $0.003 per row. No start fee.

Every dataset row bills from row one, including an error row for a company that could not be read. A run that returns no rows costs nothing. **Maximum rows** is the spend cap.

### Output (one row per job)

One example row from a real local run on 21 September 2026. The input was `https://www.palantir.com`. The run returned 5 rows. This is the first:

```json
{
  "company_input": "https://www.palantir.com",
  "careers_page": "https://www.palantir.com/careers/",
  "hiring_system": "lever",
  "board_id": "palantir",
  "job_id": "ac978161-6f46-4f6b-ad9e-a258e642751c",
  "title": "Administrative Business Partner",
  "department": "Administrative",
  "location": "London, United Kingdom",
  "remote": false,
  "employment_type": "Full-time",
  "posted_at": "2024-03-25T21:50:16Z",
  "updated_at": null,
  "job_url": "https://jobs.lever.co/palantir/ac978161-6f46-4f6b-ad9e-a258e642751c",
  "apply_url": "https://jobs.lever.co/palantir/ac978161-6f46-4f6b-ad9e-a258e642751c/apply",
  "dedupe_key": "lever:palantir:ac978161-6f46-4f6b-ad9e-a258e642751c",
  "is_new": true,
  "fetched_at": "2026-09-21T18:03:02Z",
  "error": null
}
```

| Field | What it holds |
|---|---|
| `company_input` | The address you pasted |
| `careers_page` | The page where the hiring system was named |
| `hiring_system` | `greenhouse`, `lever`, `ashby`, `workable`, `recruitee`, `personio`, `smartrecruiters` (named, but its job list is never read — see below), or a named unsupported system such as `workday` |
| `board_id` | The board id written on the page. Empty when it was not written there |
| `job_id` | The id from the official job list |
| `title` | Job title |
| `department` | Department, when the job list has one |
| `location` | Location string from the job list |
| `remote` | `true` or `false` when the job list says so. Empty when it does not |
| `employment_type` | Employment type from the job list. Empty when it has none |
| `posted_at` / `updated_at` | Dates from the job list. Empty when that list has no such date |
| `job_url` / `apply_url` | Public job and apply links from the job list |
| `dedupe_key` | `system:board id:job id` |
| `is_new` | `false` when that id or dedupe key was in **Ids already seen**. Otherwise `true` on a job row |
| `error` | Empty on a job row. A plain-English reason on a failed company |
| `fetched_at` | When this run read the list, in UTC |

### What this does not do

- It does not log in, use cookies, solve a CAPTCHA, or read applicants.
- Stripe's public homepage and `/careers` page, fetched on 21 September 2026, did not contain a Greenhouse board id. `/careers/search` contains Greenhouse job ids and still does not contain the board id, so those jobs are not returned.
- It does not read SmartRecruiters. `api.smartrecruiters.com/robots.txt` says `Disallow: /` for a normal browser.
- It does not read Workday, iCIMS, Phenom, or other systems it can name. Those companies return one error row.
- It does not turn Ramp's homepage into a careers page. On this machine that homepage came back as a short markdown "Machine Version" with no careers link. `https://ramp.com/careers` did contain Ashby links for board `ramp`.
- It does not return recruiter names, emails, or phone numbers.
- It does not grant a licence to republish a company's jobs. See `SOURCE_TERMS.md`.
- It does not promise speed or uptime. One local Palantir run returned 5 rows in 21.48 seconds. That is one measurement, not a rate.

### Limits

- At most 500 company addresses.
- At most 6 requests for each company (its robots file, the page, up to three careers links, one possible Greenhouse board guess, and the job list).
- One second between requests to the same host.
- Official lists used, and only when that host's robots file allows the path: Greenhouse `https://boards-api.greenhouse.io/v1/boards/{id}/jobs?content=false`, Lever `https://api.lever.co/v0/postings/{id}?mode=json`, Ashby `https://api.ashbyhq.com/posting-api/job-board/{id}`, Workable `https://apply.workable.com/api/v1/widget/accounts/{id}`, Recruitee `https://{id}.recruitee.com/api/offers/`, Personio `https://{id}.jobs.personio.de/xml`.
- Workable's robots file allows that path and also contains `Content-Signal: search=yes, ai-input=yes, ai-train=no`. That line is not a path block. This tool does not train a model.
- `api.ashbyhq.com/robots.txt` returned HTTP 401 on this machine. That is not a Disallow line. The Ramp job list itself returned HTTP 200 during the probe.
- A blocked or missing company is one error row. Other companies in the same run still run.

### When the careers page hides its hiring system

If no hiring system is named on the page, the tool tries the company's own name as a Greenhouse board and keeps the result only when that board's job links point back to the same company website. If they do not match, the guess is thrown away and you get one plain row that says the company's own name was tried as a board and rejected. An unverified guess is never returned as a match.

# Actor input Schema

## `companyUrls` (type: `array`):

Company homepages or careers-page addresses, one per line. At most 500. A homepage may be followed to at most three careers links found on that page, such as /careers or /jobs.

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

Optional. Keep a job only when its title contains one of these words or phrases. Matching ignores case. Leave empty for every job.

## `maxJobsPerCompany` (type: `integer`):

Stop reading a company after this many jobs. The run can still return an error row for a company that could not be read.

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

Hard ceiling on rows returned, and therefore on the cost of the run. Every row bills at the listed price from row one, including an error row. There is no start fee.

## `previousIds` (type: `array`):

Optional. Job ids or dedupe keys from an earlier run. A job whose id or dedupe key is in this list is marked is\_new false. Others are marked is\_new true.

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

Optional Apify proxy. Leave off for a local run. Pages and job lists are ordinary HTTPS GET requests.

## Actor input object example

```json
{
  "companyUrls": [
    "https://www.palantir.com"
  ],
  "maxJobsPerCompany": 200,
  "maxItems": 1000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `report` (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 = {
    "companyUrls": [
        "https://www.palantir.com"
    ],
    "maxJobsPerCompany": 200,
    "maxItems": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("usta/career-site-jobs").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 = {
    "companyUrls": ["https://www.palantir.com"],
    "maxJobsPerCompany": 200,
    "maxItems": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("usta/career-site-jobs").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 '{
  "companyUrls": [
    "https://www.palantir.com"
  ],
  "maxJobsPerCompany": 200,
  "maxItems": 1000
}' |
apify call usta/career-site-jobs --silent --output-dataset

```

## MCP server setup

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

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/ntPvaKFM1CfPSS8Py/builds/irQadrubjBEdyqOHV/openapi.json
