# Teamtailor Jobs Scraper: Company Career Sites (`santamaria-automations/teamtailor-jobs-scraper`) Actor

Scrape open jobs from Teamtailor career sites (company.teamtailor.com): title, location, department, workplace type, description, posting date and apply URL. Filter by keyword, location and date. Pay per result.

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

## Pricing

Pay per event

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

## Teamtailor Jobs Scraper: Company Career Sites

Get the open jobs of any company that hires through [Teamtailor](https://www.teamtailor.com). Paste a Teamtailor career site URL such as `https://career.teamtailor.com` (or just the company name) and receive title, location, apply URL and, when the site provides them, department, workplace type, description and posting date as clean dataset rows.

### What you can do with it

- Pull all open roles of a list of target companies for lead generation or recruiting research.
- Track hiring over time: run it on a schedule with `postedWithinDays` and `sortBy: newest` to see only new postings.
- Feed a job board or alert system with the openings of the companies you follow.
- Filter by keyword in the title, by location or by country.

### What you get

One dataset row per job. Duplicates are removed before anything is charged, so the number of rows is the number of results you pay for.

| Field | Description |
|-------|-------------|
| `id` | Job id, unique across Teamtailor career sites |
| `ats_job_id` | The id Teamtailor uses for the posting |
| `title` | Job title |
| `ats_platform` | `teamtailor` |
| `company` | The employer's name as the career site shows it (the career site's address name when it shows none) |
| `location`, `city`, `country` | Location text as posted (city and country; several locations are joined with `;`), the city and the two-letter country code, when the site provides a location |
| `department` | Department or team; the job's role when it names no department |
| `remote` | `true` only for remote postings (a hybrid or on-site job is `false`), or when the location says remote |
| `workplace_type` | `remote`, `hybrid` or `on_site`, when the site provides it; empty when the posting does not say |
| `description` | Full job description as HTML, when the site provides it. Empty when `includeDescription` is off or the posting has none |
| `apply_url`, `job_url` | Link to the posting and to the application page |
| `created_at` | Publication date and time of the posting in UTC |
| `language` | Language of the posting, when it can be determined |
| `scraped_at` | Time of the run |

Salary fields (`salary_text`, `salary_min`, `salary_max`, `salary_currency`, `salary_period`, `salary_source`) are filled only when the posting states a salary range. They are never estimated.

### Input

| Field | Description |
|-------|-------------|
| `companies` | Teamtailor career site URLs or bare company names (`career` is `https://career.teamtailor.com`). Strings, `{"url": "..."}` objects, a single string, or several separated by commas or new lines. Empty = one sample Teamtailor career site. |
| `ats` | `auto` (default) recognises addresses ending in `.teamtailor.com`. Set `teamtailor` to read a career site on the company's own domain. |
| `keywords` | Keep only jobs whose title matches at least one keyword. They filter the jobs of the Teamtailor career sites you list; they do not search other companies. |
| `location` | Keep only jobs in this city, region or country (`Geneva`, `Switzerland`, `CH`). |
| `countries` | ISO-2 codes such as `["CH", "DE"]`: keep only jobs located in these countries (jobs whose country cannot be determined are left out). |
| `includeRemoteWithoutRegion` | Only with a country filter: also keep remote jobs that state no country or region (they may not be open to applicants in that country). Default `false`. |
| `postedWithinDays` | Drop jobs older than this many days. Jobs without a posting date are kept. |
| `sortBy` | `newest` (default) or `relevance` (the site's own order). |
| `maxJobsPerCompany` | Cap per career site, counted after the filters. `0` = all. Default 50. |
| `maxResults` | Cap for the whole run. The run stops cleanly when it is reached. `0` = no limit. Default 100. |
| `includeDescription` | Include the description HTML. Default `true`. |

#### Example: one career site

```json
{
  "companies": ["https://career.teamtailor.com"],
  "maxResults": 20
}
```

#### Example: several Teamtailor career sites with filters

```json
{
  "companies": [
    "https://career.teamtailor.com",
    "https://acme.teamtailor.com"
  ],
  "keywords": ["engineer", "data"],
  "postedWithinDays": 30,
  "sortBy": "newest",
  "maxJobsPerCompany": 25
}
```

Only Teamtailor career sites are read. A URL of any other job system (Greenhouse, Lever, Workday and so on) is skipped with a log line that names the actor to use, and is never charged.

#### Supported URL formats

- Career site: `https://{company}.teamtailor.com` (with or without a trailing slash, or without `https://`; tracking parameters such as `utm_source` are ignored).
- Posting: `https://{company}.teamtailor.com/jobs/{job-id-and-title}` is reduced to its career site; the whole site is read.
- Bare company name: `{company}`.
- Career site on the company's own domain: the URL of the site together with `ats` set to `teamtailor`.

### Output

```json
{
  "id": "teamtailor-a1b2c3d4-1001",
  "ats_job_id": "1001",
  "title": "Platform Engineer",
  "company": "Example AB",
  "ats_platform": "teamtailor",
  "location": "Stockholm, Sweden",
  "city": "Stockholm",
  "country": "SE",
  "department": "Engineering",
  "remote": false,
  "workplace_type": "hybrid",
  "apply_url": "https://example.teamtailor.com/jobs/1001-platform-engineer",
  "job_url": "https://example.teamtailor.com/jobs/1001-platform-engineer",
  "created_at": "2026-10-05T07:30:00Z",
  "scraped_at": "2026-10-27T09:00:00Z"
}
```

The row above is illustrative; values depend on the career site.

### Pricing

Pay per result, two events:

- `apify-actor-start`: $0.001 once per run.
- `job-result`: $0.001 per job in the dataset ($1.00 per 1,000 jobs).

The start fee is charged on top of the job results. Filtered-out and duplicate jobs are never charged, and a career site that is not found costs nothing. Set a maximum total charge on the run to stop at a budget; the run ends cleanly when it is reached. The pricing box on the actor page always shows the current rates.

### Use with AI Agents (MCP)

Connect this actor to any MCP-compatible AI client, such as Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, or custom agents.

**Example prompts once connected:**

> "Use `teamtailor-jobs-scraper` for https://career.teamtailor.com and list the open roles with title, location and apply URL."

> "Use `teamtailor-jobs-scraper` for the companies career and acme and return the roles posted in the last 30 days."

Configure the MCP server with the Teamtailor Jobs Scraper preconfigured at `mcp.apify.com?tools=santamaria-automations/teamtailor-jobs-scraper`:

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=santamaria-automations/teamtailor-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}
```

See the auto-generated API tab on the actor page for language-specific examples (cURL, JavaScript, Python, and more).

### FAQ

**How do I find a company's Teamtailor career site URL?**
Open the company's careers page. If the address ends in `.teamtailor.com`, that is the URL. You can pass either the URL or just the company name. If the careers page is on the company's own domain, pass its URL and set `ats` to `teamtailor`.

**What if the career site is on the company's own domain?**
Pass its URL and set `ats` to `teamtailor`. With `ats` on `auto` only addresses ending in `.teamtailor.com` are recognised.

**Can I search by keyword across all Teamtailor companies?**
No. Give the URL or name of each company. Keywords only filter the titles of the jobs of the career sites you list.

**What if a career site is not found?**
The run continues with the other Teamtailor career sites. The run status line names the career site and the reason (for example `board_not_found`), and nothing is charged for it.

**Why is the description empty?**
It is empty when `includeDescription` is off, or when the posting could not be read. The row still has title, location, date and the apply URL, and is charged the same.

**Why is the salary empty?**
Salary fields are filled only when the posting states a salary range, and only with `includeDescription` on. Nothing is estimated.

**How do I get only new jobs?**
Run it on a schedule with `postedWithinDays` set to the interval (for example `1` for a daily run) and `sortBy` set to `newest`.

**How do I stop at a budget?**
Set `maxResults` or the maximum total charge of the run. The run stops cleanly when either is reached.

**Why did I get fewer jobs than `maxJobsPerCompany`?**
The caps apply after your filters, and a career site can simply have fewer open jobs. The Teamtailor career sites are read in the order you list them, and the run stops once `maxResults` is reached.

### Limits

- Career sites only; no company-name search across Teamtailor.
- Salary fields are filled only when the posting text states a salary, and only with `includeDescription` on.
- Postings carry no employment type and no last-update date; `employment_type` and `updated_at` stay empty.

### Related actors

- [Career Site Jobs Scraper](https://apify.com/santamaria-automations/career-site-jobs-scraper): the same engine for 40+ job systems (Workday, Personio, Workable and more).
- [SuccessFactors Jobs Scraper](https://apify.com/santamaria-automations/successfactors-jobs-scraper): jobs of SAP SuccessFactors career sites.
- [iCIMS Jobs Scraper](https://apify.com/santamaria-automations/icims-jobs-scraper): jobs of iCIMS career sites.
- [Recruitee Jobs Scraper](https://apify.com/santamaria-automations/recruitee-jobs-scraper): jobs of Recruitee career sites.
- [Rippling Jobs Scraper](https://apify.com/santamaria-automations/rippling-jobs-scraper): jobs of Rippling career pages.
- [JOIN Jobs Scraper](https://apify.com/santamaria-automations/join-jobs-scraper): jobs of JOIN company pages.
- [Softgarden Jobs Scraper](https://apify.com/santamaria-automations/softgarden-jobs-scraper): jobs of Softgarden career sites.
- [SmartRecruiters Jobs Scraper](https://apify.com/santamaria-automations/smartrecruiters-jobs-scraper): jobs of any SmartRecruiters company board.
- [Workable Jobs Scraper](https://apify.com/santamaria-automations/workable-jobs-scraper): jobs of any Workable company board.
- [Greenhouse, Lever & Ashby Jobs Scraper](https://apify.com/santamaria-automations/greenhouse-lever-ashby-jobs-scraper): jobs of any Greenhouse, Lever or Ashby board, with keyword search across companies.
- [Website Job Extractor](https://apify.com/santamaria-automations/website-job-extractor): any company website to its careers page, job system and jobs.

### Support

- **Questions or issues?** Email contact@nanoscrape.com, we typically reply within 6 hours, or open a ticket in the Issues tab on the actor page.
- **Need a scraper for a job board we don't cover yet?** Email contact@nanoscrape.com with the target site and your rough usage volume.

# Actor input Schema

## `companies` (type: `array`):

Teamtailor career site URLs such as https://career.teamtailor.com, or bare company names such as career (the part before .teamtailor.com). Strings or {"url": "..."} objects; a single string, or several separated by commas or new lines, also works. A URL of one job posting is reduced to its career site; tracking parameters such as utm_source are ignored. A career site on the company's own domain (for example https://jobs.example.com) needs ats set to teamtailor. URLs of other job systems are skipped with a log line that names the right actor, and are never charged. With no companies (an empty input does this too) the actor runs one sample career site (career).

## `ats` (type: `string`):

Only needed for a career site on the company's own domain (for example https://jobs.example.com). auto recognises addresses ending in .teamtailor.com. Set teamtailor to read the URLs you pass as Teamtailor career sites.

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

Return only jobs whose TITLE matches at least one of these words or phrases (OR). Case and accents are ignored. A keyword of 4 or more characters matches anywhere inside the title; a keyword of 3 or fewer characters (for example QA, PM) must match as a whole word. Example: \["engineer", "manager"]. The keywords filter the jobs of the career sites you list; they do not search other companies.

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

Optional. Return only jobs in this city, region or country, for example "London", "Germany" or "DE". Country names and ISO codes match in both directions.

## `includeRemoteWithoutRegion` (type: `boolean`):

Only matters when you filter by country (the Location input is a country, or a query carries a country). Off (default): a remote job counts for the country only when it names it ("Remote - Germany"), names a region that contains it (EMEA, Europe, EU, DACH, Americas, APAC) or is open worldwide. Remote jobs that say only "Remote" are left out and are not charged. On: those jobs are kept too, but they may not be open to applicants in the chosen country.

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

Optional. ISO 3166-1 alpha-2 codes such as \["DE", "CH"]. Returns only jobs located in these countries (jobs whose country cannot be determined are left out).

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

Optional. Drop jobs posted more than this many days ago. Jobs without a posting date are kept.

## `sortBy` (type: `string`):

"newest" returns the most recently posted jobs of each career site first, so maxJobsPerCompany keeps the newest ones. "relevance" keeps the site's own order. Career sites are read in the order you list them.

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

Maximum number of jobs returned per career site, counted after the filters (filtered-out jobs are never returned or charged). 0 = all jobs.

## `maxResults` (type: `integer`):

Maximum number of jobs returned in total across all companies. The run stops cleanly once it is reached. 0 = no limit.

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

Include the job description (HTML) and the stated salary, when the posting has one. Switch off for a smaller, faster run (salary fields are then empty).

## Actor input object example

```json
{
  "companies": [
    "https://career.teamtailor.com"
  ],
  "ats": "auto",
  "includeRemoteWithoutRegion": false,
  "sortBy": "newest",
  "maxJobsPerCompany": 20,
  "maxResults": 20,
  "includeDescription": true
}
```

# Actor output Schema

## `items` (type: `string`):

Job listings from Teamtailor career sites

# 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 = {
    "companies": [
        "https://career.teamtailor.com"
    ],
    "maxJobsPerCompany": 20,
    "maxResults": 20,
    "includeDescription": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/teamtailor-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 = {
    "companies": ["https://career.teamtailor.com"],
    "maxJobsPerCompany": 20,
    "maxResults": 20,
    "includeDescription": True,
}

# Run the Actor and wait for it to finish
run = client.actor("santamaria-automations/teamtailor-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 '{
  "companies": [
    "https://career.teamtailor.com"
  ],
  "maxJobsPerCompany": 20,
  "maxResults": 20,
  "includeDescription": true
}' |
apify call santamaria-automations/teamtailor-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,santamaria-automations/teamtailor-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/xCNA207TURY22mgkw/builds/86FPMosbpPsTNrjVS/openapi.json
