Teamtailor Jobs Scraper & API - ATS Career Page Data
Pricing
from $6.15 / 1,000 results
Teamtailor Jobs Scraper & API - ATS Career Page Data
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.
Pricing
from $6.15 / 1,000 results
Rating
5.0
(1)
Developer
Scrapers Lat
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
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 · 📤 Output · 💰 Pricing · ▶️ Examples
Table of contents
- What it does
- Use cases
- Quickstart
- Input reference
- Output reference
- Example output record
- How it compares
- Run via API and CLI
- Fetch results
- Billing and limits
- 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.
{"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}):
{"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:
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~teamtailor-jobs-scraper/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"companies":["career"],"maxJobs":25,"withDetails":true}'
Start a run asynchronously:
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~teamtailor-jobs-scraper/runs?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"companies":["career","autolivgroup"],"searchQuery":"engineer","maxJobs":200}'
Apify CLI:
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:
# JSONcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"# CSVcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"# Paginate large datasetscurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&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 (
resultevent), plus a smalldetailscharge only when the full job page is fetched successfully. See the pricing tab for current prices. - No charge on failure. If a career site errors, the actor writes a single item with a populated
errorfield and does not charge for it. Empty runs cost nothing. - Spend cap respected. Set
maxTotalChargeUsdon 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: Jobs from Talent.com across 30 country sites.
- LinkedIn Jobs Scraper: Job postings from LinkedIn.
- Indeed Jobs Scraper: Job postings from Indeed.
More scrapers at scrapers.lat
Built and maintained by 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.
Independent tool, not affiliated with Teamtailor. Accesses only publicly available career-site data.
