# Teamtailor Jobs Scraper & API - ATS Career Page Data (`scrapers_lat/teamtailor-jobs-scraper`) Actor

Scrape jobs from any Teamtailor career site by company, subdomain or URL, no API key or login. Get title, description, department, location, remote status, employment type, salary, apply URL, and the hiring recruiter name and email. Filter by keyword, location or department. Export JSON, CSV, Excel.

- **URL**: https://apify.com/scrapers\_lat/teamtailor-jobs-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.15 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

[![Teamtailor Jobs Scraper & API](https://scrapers.lat/banners/teamtailor-jobs-scraper.png)](https://console.apify.com/actors/eddJZu8JzFVakMRiy/input)

## Teamtailor Jobs Scraper & API

Scrape job postings from any **Teamtailor career site** into clean JSON, CSV or Excel. No API key, no login, no browser. Point it at a company subdomain (`career` for `career.teamtailor.com`), a full career-site URL, or a custom career domain such as `https://jobs.lunar.app`, and get one normalized record per job: title, full description, department, location, remote status, employment type, salary when listed, apply URL, and the hiring recruiter's name, job title and public email.

This is the most complete **Teamtailor jobs data** extractor on Apify: it returns every field a Teamtailor job page exposes and adds the hiring contact, so it doubles as an **ATS jobs scraper** for recruiting, talent sourcing, sales prospecting and job-board aggregation.

**📥 [Input](https://apify.com/scrapers_lat/teamtailor-jobs-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/teamtailor-jobs-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/teamtailor-jobs-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/teamtailor-jobs-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Coverage](https://img.shields.io/badge/Coverage-Any%20Teamtailor%20site-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [Use cases](#use-cases)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [How it compares](#how-it-compares)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

Teamtailor is an applicant tracking system (ATS) used by 13,000+ companies, each hosting a public career page at `{company}.teamtailor.com` or a custom domain. This actor takes one or many of those career sites, lists every open job on each, and writes one clean record per posting to the run's dataset.

With `withDetails` on (the default) it opens each job page and collects:

- The full **job description** as both plain text and HTML.
- The parsed **JobPosting schema**: employment type, posting date, closing date, salary when the employer lists one, benefits, qualifications, responsibilities and requirements.
- The **structured job location**: city, region, two-letter country code, postal code and street address, plus every listed location.
- The visible **department** and **remote status** (Hybrid, Remote or On-site).
- The **hiring recruiter**: name, job title, public profile link, avatar and public email when the employer publishes one.
- Company **logo**, **social links** and share image.

Missing source values are returned as `null` rather than invented. You can filter by keyword, location, department and posting freshness, and cap results per company or overall.

### Use cases

- **Recruiting and talent sourcing**: track competitor hiring, build talent pipelines, and reach the named hiring recruiter directly.
- **Sales and lead generation**: companies that are hiring are buying; surface hiring signals plus a recruiter contact for outreach.
- **Job-board and aggregator feeds**: ingest full Teamtailor postings with descriptions into your own board or ATS.
- **Labor-market and comp research**: collect roles, locations, remote mix and salary data across many employers.
- **Hiring monitors and alerts**: schedule the actor and diff runs to detect newly posted jobs.

### Quickstart

Open the actor, paste this into the input, and press Run. It scrapes three Teamtailor career sites, up to 10 jobs each.

```json
{
  "companies": ["career", "https://jobs.lunar.app/", "autolivgroup"],
  "maxJobs": 30,
  "maxJobsPerCompany": 10,
  "withDetails": true
}
```

`companies` is the only required field. Leave the filters empty to return every open job. Turn `withDetails` off for faster, listing-only results.

### Input reference

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `companies` | string\[] | yes | `["career", "https://jobs.lunar.app/", "autolivgroup"]` | Teamtailor career sites to scrape. Add the subdomain (for example `career`), a full career-site URL, or a custom career domain. One entry per company. |
| `startUrls` | array | no | (none) | Optional extra career-site or job URLs, merged with `companies`. Accepts an Apify request list (objects with a `url`) or plain URL strings. |
| `maxJobs` | integer | no | `10` | Maximum jobs to collect across all companies. Leave empty for no overall limit. |
| `maxJobsPerCompany` | integer | no | (none) | Cap the number of jobs collected from each site. Leave empty for no per-company limit. |
| `withDetails` | boolean | no | `true` | Open each job page for the full description, employment type, dates, salary, structured location, department, remote status and recruiter. Off returns listing-level fields only. |
| `searchQuery` | string | no | (empty) | Keyword phrase. Keeps jobs whose title, department, location or company matches (case-insensitive). |
| `keywords` | string\[] | no | (none) | Keyword list. Keeps a job if any keyword appears in its title, department, location, company or description. |
| `location` | string\[] | no | (none) | Keep only jobs whose city, region or country matches any value. |
| `department` | string\[] | no | (none) | Keep only jobs whose department matches any value. |
| `postedWithinDays` | integer | no | (none) | Freshness filter. Keep only jobs posted within this many days. Requires `withDetails` on. |
| `proxyConfiguration` | object | no | off | Optional Apify proxy. Public Teamtailor sites work without one. |

Common aliases are accepted so you can reuse inputs from other scrapers: `includeDescription` (for `withDetails`), `maxItems` / `maxTotalJobs` (for `maxJobs`), `maxJobsPerUrl` (for `maxJobsPerCompany`), and `companyUrls` / `companySlugs` / `companyUrlsText` (merged into `companies`).

### Output reference

One dataset item per job. Types: `string`, `integer`, `boolean`, `string[]`, or `null` when the source value is absent.

| Field | Type | Description |
|---|---|---|
| `title` | string | Job title. |
| `company` | string | Company name as shown on the career site. |
| `companyName` | string | Company name (alias of `company`). |
| `companySlug` | string | Teamtailor subdomain slug (or host for custom domains). |
| `department` | string | Department or team the job belongs to. |
| `location` | string | Job location label. |
| `remoteStatus` | string | Remote arrangement, for example `Hybrid`, `Remote`, `On-site`. |
| `employmentType` | string | Employment type, for example `FULL_TIME`, `PART_TIME`. |
| `datePosted` | string | Publication date and time (ISO 8601). |
| `validThrough` | string | Posting expiry when published, otherwise `null`. |
| `industry` | string | Industry from the JobPosting schema, or `null`. |
| `occupationalCategory` | string | Occupational category from the schema, or `null`. |
| `jobBenefits` | string | Benefits text from the schema, or `null`. |
| `qualifications` | string | Qualifications from the schema, or `null`. |
| `responsibilities` | string | Responsibilities from the schema, or `null`. |
| `experienceRequirements` | string | Experience requirements from the schema, or `null`. |
| `educationRequirements` | string | Education requirements from the schema, or `null`. |
| `workHours` | string | Work hours from the schema, or `null`. |
| `directApply` | boolean | JobPosting directApply flag, or `null`. |
| `jobIdentifier` | string | Job identifier from the JobPosting schema. |
| `salaryMin` | integer | Minimum salary when the employer lists one, or `null`. |
| `salaryMax` | integer | Maximum salary when the employer lists one, or `null`. |
| `salaryCurrency` | string | Salary currency code, or `null`. |
| `salaryUnit` | string | Salary period unit (for example `MONTH`, `YEAR`), or `null`. |
| `salaryText` | string | Salary exactly as displayed on the page, when shown, or `null`. |
| `city` | string | Structured city of the job location. |
| `region` | string | Structured region of the job location. |
| `country` | string | Two-letter country code of the job location. |
| `postalCode` | string | Postal code of the job location. |
| `streetAddress` | string | Street address of the job location. |
| `locations` | string\[] | All listed locations for the job. |
| `description` | string | Full job description as plain text (only with `withDetails` on). |
| `descriptionHtml` | string | Full job description as HTML (only with `withDetails` on). |
| `recruiterName` | string | Hiring recruiter's name, or `null`. |
| `recruiterTitle` | string | Hiring recruiter's job title, or `null`. |
| `recruiterEmail` | string | Hiring recruiter's public email, or `null`. |
| `recruiterUrl` | string | Path to the recruiter's profile on the career site. |
| `recruiterAvatar` | string | Recruiter avatar image URL. |
| `companyLogo` | string | Company logo image URL. |
| `companySocial` | string\[] | Company links published on the career site. |
| `shareImage` | string | Social share image for the posting, or `null`. |
| `url` | string | Canonical job URL. |
| `applyUrl` | string | Direct application URL. |
| `jobId` | string | Teamtailor job ID (unique per posting). |
| `companySite` | string | Career-site host the job came from. |
| `observedAt` | string | ISO 8601 timestamp of when the record was collected. |
| `error` | string | `null` on success. On a failed site, a single item with a populated `error` field is written instead. |

### Example output record

Real record from a live run (input `{"companies": ["career"], "maxJobs": 10}`):

```json
{
  "title": "Group Financial Controller",
  "company": "Teamtailor",
  "companyName": "Teamtailor",
  "companySlug": "career",
  "department": "Finance",
  "location": "Stockholm",
  "remoteStatus": "Hybrid",
  "employmentType": "FULL_TIME",
  "datePosted": "2026-07-24T13:57:16+02:00",
  "validThrough": null,
  "jobIdentifier": "8124573",
  "salaryMin": null,
  "salaryText": null,
  "city": "Stockholm",
  "region": "Sweden",
  "country": "SE",
  "postalCode": "116 21",
  "streetAddress": "Östgötagatan 16",
  "locations": ["Stockholm, Sweden, SE"],
  "description": "Join Teamtailor and Help Shape the Future of Work! ... [full posting text returned in the real field]",
  "descriptionHtml": "<h4>Join Teamtailor</h4><p>...</p> [full posting HTML returned in the real field]",
  "recruiterName": "Martina Nunes",
  "recruiterTitle": "Sales Talent Acquisition Specialist",
  "recruiterEmail": "martina.nunes@teamtailor.com",
  "recruiterUrl": "/people/3631216-martina-nunes",
  "companyLogo": "https://images.teamtailor-cdn.com/images/s3/teamtailor-production/logotype-v3/image_uploads/5549c984-8723-4307-8ca4-454109714c72/original.png",
  "shareImage": "https://screenshots.teamtailor-cdn.com/04dbae39-cb51-4208-a432-20a8bceda596-facebook.png",
  "url": "https://career.teamtailor.com/jobs/8124573-group-financial-controller",
  "applyUrl": "https://career.teamtailor.com/jobs/8124573-group-financial-controller/applications/new",
  "jobId": "8124573",
  "companySite": "career.teamtailor.com",
  "observedAt": "2026-09-04T00:00:00.000Z",
  "error": null
}
```

Null-only schema fields are omitted here for readability but are present in the full dataset item.

### How it compares

Every field and filter offered by the common Teamtailor scrapers on Apify, plus more. This actor is a strict superset.

| Capability | This actor | Typical Teamtailor scraper | Basic Teamtailor scraper |
|---|---|---|---|
| Company subdomains / URLs / custom domains | Yes | Yes | Yes |
| `startUrls` support | Yes | Yes | Yes |
| Max overall / per-company caps | Yes | Yes | Per-company only |
| Keyword, location, department filters | Yes | Partial | No |
| Freshness (posted within N days) filter | Yes | Some | No |
| Job title, company, jobId, apply URL | Yes | Yes | Yes |
| Full description (text + HTML) | Yes | Text only | Text only |
| Department | Yes | Often null | Null |
| Remote status (Hybrid / Remote / On-site) | Yes | Sometimes | Null |
| Employment type | Yes | Sometimes | Null |
| Structured location (city, region, country, postal, street) | Yes | Partial | Country only |
| Salary (min, max, currency, unit, as-listed) | Yes | No | No |
| Benefits, qualifications, responsibilities, requirements | Yes | No | No |
| Hiring recruiter name, job title and email | Yes | No | No |
| Company logo, social links, share image | Yes | No | No |

### Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace `<TOKEN>` with your Apify API token.

Run synchronously and get dataset items in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~teamtailor-jobs-scraper/run-sync-get-dataset-items?token=%3CTOKEN%3E" \
  -H "Content-Type: application/json" \
  -d '{"companies":["career"],"maxJobs":25,"withDetails":true}'
```

Start a run asynchronously:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~teamtailor-jobs-scraper/runs?token=%3CTOKEN%3E" \
  -H "Content-Type: application/json" \
  -d '{"companies":["career","autolivgroup"],"searchQuery":"engineer","maxJobs":200}'
```

Apify CLI:

```bash
apify call scrapers_lat/teamtailor-jobs-scraper \
  --input '{"companies":["https://jobs.lunar.app/"],"withDetails":true}'
```

### Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing `format`:

```bash
## JSON
curl "https://api.apify.com/v2/datasets/%3CDATASET_ID%3E/items?token=%3CTOKEN%3E&clean=true&format=json"

## CSV
curl "https://api.apify.com/v2/datasets/%3CDATASET_ID%3E/items?token=%3CTOKEN%3E&clean=true&format=csv"

## Paginate large datasets
curl "https://api.apify.com/v2/datasets/%3CDATASET_ID%3E/items?token=%3CTOKEN%3E&offset=1000&limit=1000"
```

`<DATASET_ID>` is returned as `defaultDatasetId` in the run object. Use `offset` and `limit` to page through large result sets. `clean=true` drops empty and internal fields.

### Billing and limits

- **Pay per result.** You are charged per job returned (`result` event), plus a small `details` charge only when the full job page is fetched successfully. See the [pricing tab](https://apify.com/scrapers_lat/teamtailor-jobs-scraper/pricing) for current prices.
- **No charge on failure.** If a career site errors, the actor writes a single item with a populated `error` field and does not charge for it. Empty runs cost nothing.
- **Spend cap respected.** Set `maxTotalChargeUsd` on the run; once reached, the actor stops emitting and charging further billable results.
- **Free Apify plans** are capped at 10 records per run. Upgrade for a higher `maxJobs`.

### FAQ and troubleshooting

**Do I need a Teamtailor API key?**
No. The actor reads each company's public career page directly, so there is no API key, token or login to manage.

**A run returned 0 jobs. Why?**
The career site had no open jobs, the subdomain or URL was wrong, or your filters excluded everything. Confirm the site loads in a browser and loosen the keyword, location or department filter. Zero-result runs are not charged.

**How do I scrape a custom career domain?**
Add the full URL to `companies`, for example `https://jobs.lunar.app`. Subdomains like `career` are also accepted and resolve to `career.teamtailor.com`.

**Why are the salary fields null?**
Most Teamtailor employers do not publish a salary. When none is listed, the salary fields stay `null` rather than being guessed.

**Do I always get the recruiter email?**
Only when the employer publishes a hiring recruiter on the job page. When present, `recruiterName`, `recruiterTitle` and `recruiterEmail` are captured; otherwise they are `null`.

**Why is `description` missing?**
The full description and HTML are only collected when `withDetails` is on.

**Is this an official Teamtailor tool?**
No. This actor is independent and has no affiliation with Teamtailor. It reads only data that is publicly available on each career site.

### Related scrapers

- [Talent.com Jobs Scraper](https://apify.com/scrapers_lat/talent-jobs-scraper): Jobs from Talent.com across 30 country sites.
- [LinkedIn Jobs Scraper](https://apify.com/scrapers_lat/linkedin-jobs-scraper): Job postings from LinkedIn.
- [Indeed Jobs Scraper](https://apify.com/scrapers_lat/indeed-jobs-scraper): Job postings from Indeed.

### More scrapers at scrapers.lat

Built and maintained by [scrapers.lat](https://scrapers.lat), where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at [scrapers.lat](https://scrapers.lat).

***

> Independent tool, not affiliated with Teamtailor. Accesses only publicly available career-site data.

# Actor input Schema

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

Companies to scrape. Add the Teamtailor subdomain (for example career for career.teamtailor.com), the full career site URL, or a custom career domain such as https://jobs.lunar.app. Add one entry per company.

## `startUrls` (type: `array`):

Optional. Teamtailor career-site or job URLs to scrape, in addition to the Companies list. Accepts an Apify request list (objects with a url) or plain URL strings.

## `maxJobs` (type: `integer`):

Maximum number of jobs to collect across all companies. Leave empty for no overall limit. Free Apify plans are always capped at 10 results per run.

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

Optional. Cap the number of jobs collected from each career site (useful when scraping many companies at once). Leave empty for no per-company limit.

## `withDetails` (type: `boolean`):

When enabled, each job includes the full description (text and HTML), employment type, posting date, closing date, salary when the employer lists one, the structured job location (city, region, country), department, remote status and the hiring contact. When disabled, only the lightweight listing fields are collected.

## `searchQuery` (type: `string`):

Optional keyword phrase to filter jobs. Matches against the job title, department, location and company (case-insensitive). Leave empty to return every open job.

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

Optional list of keywords. A job is kept if any keyword appears in its title, department, location, company or description.

## `location` (type: `array`):

Optional. Keep only jobs whose location (city, region or country) matches any of these values. Case-insensitive substring match.

## `department` (type: `array`):

Optional. Keep only jobs whose department matches any of these values. Case-insensitive substring match.

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

Optional freshness filter. Keep only jobs posted within this many days. Requires Fetch full job details (the posting date comes from the job page).

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

Optional. Public Teamtailor career sites work without a proxy, so this is off by default. Enable an Apify proxy only if you scrape at high volume and want IP rotation.

## Actor input object example

```json
{
  "companies": [
    "career",
    "https://jobs.lunar.app/",
    "autolivgroup"
  ],
  "maxJobs": 10,
  "withDetails": true
}
```

# 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 = {
    "companies": [
        "career",
        "https://jobs.lunar.app/",
        "autolivgroup"
    ],
    "maxJobs": 10,
    "searchQuery": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/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": [
        "career",
        "https://jobs.lunar.app/",
        "autolivgroup",
    ],
    "maxJobs": 10,
    "searchQuery": "",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/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": [
    "career",
    "https://jobs.lunar.app/",
    "autolivgroup"
  ],
  "maxJobs": 10,
  "searchQuery": ""
}' |
apify call scrapers_lat/teamtailor-jobs-scraper --silent --output-dataset

```

## MCP server setup

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