NewSearch millions of jobs from your AI agent with MCP
All posts
GuideRecruitee
Guide·Aug 25, 2026·7 min read

Recruitee API: the careers-site endpoint that needs no key at all

Every Recruitee-hosted careers site exposes its published jobs as public JSON: GET company.recruitee.com/api/offers/, no token, no signup, full description HTML included in the list response. We tested it this week against a live tenant - 56 fields per offer, a department filter that actually works, and a salary object that ships empty. Here is the field-by-field walkthrough, how the public Careers Site API differs from the token-gated ATS API that was rebuilt with rate limits in late 2025, and where the one-tenant-at-a-time model stops working.

Dvir Atias

Dvir Atias

Founder, JobsPipe

Two different things answer to Recruitee API. One is the ATS API at api.recruitee.com - token-gated, customer-scoped, built for a company automating its own hiring. The other is the Careers Site API: every Recruitee-hosted careers site exposes its published jobs as public JSON, no token, no signup, no contract. If what you want is job postings - yours or another company’s - the second one is the endpoint you are looking for, and it is one of the friendliest in the ATS world. We tested it this week against a live tenant. Here is what actually comes back.

The two Recruitee API surfaces

  • The Careers Site API - served under each customer’s careers address at https://{company}.recruitee.com/api/offers/. Recruitee’s own docs state it plainly: “This API does not require authorization and is available under your Careers Site address.” It reads published postings and accepts candidate applications, which is why custom career pages are built on it.
  • The ATS API - api.recruitee.com/c/{company_id}/... with Authorization: Bearer and a personal API token. Tokens are generated per user, per company, and carry the exact permission scope of the user who created them - there is no way to scope one down. This is the surface for candidates, pipelines, and requisition management inside your own account.

Recruitee - now branded Tellent Recruitee - documents both at docs.recruitee.com and apidocs.recruitee.com. The newer docs portal calls itself a work in progress, but the public endpoint has been stable for years.

One GET, full postings included

We pulled a live Dutch tenant, energy company Vandebron:

curl https://vandebron.recruitee.com/api/offers/

{ "offers": [
  { "title": "Sourcing & Pricing Analyst",
    "slug": "sourcing-pricing-analyst",
    "status": "published",
    "department": "Finance & Control",
    "city": "Amsterdam",
    "country_code": "NL",
    "employment_type_code": "fulltime_permanent",
    "category_code": "finance",
    "remote": false, "hybrid": true, "on_site": false,
    "published_at": "2026-08-14 08:23:10 UTC",
    "careers_url": "https://werkenbij.vandebron.nl/o/sourcing-pricing-analyst",
    "description": "<h3>...</h3><p>...</p>",
    ... }, ... ] }

Twelve published offers, about 190 KB, one request. The detail that matters if you have integrated other ATSs: the full description HTML rides along in the list response - 8,700 characters of it on the first offer we pulled. There is no list-then-fetch-each-job dance. A per-offer endpoint exists at /api/offers/{slug} and returns the same record, but you rarely need it.

Three other behaviors we verified: a tenant with nothing published returns {"offers":[]} rather than an error, a subdomain that is not a Recruitee customer returns 404, and the endpoint stays live on the recruitee.com subdomain even when the company serves its careers page from a custom domain - Vandebron’s careers_url points at werkenbij.vandebron.nl, but the API answers on vandebron.recruitee.com.

Query filters are honored, too. Adding ?department=Finance%20%26%20Control cut the twelve offers to the three in that department, and a nonsense value returns zero. A small thing, until you have met feeds like RemoteOK’s, which accept a tags parameter and silently ignore it.

The 56 fields, and which ones to trust

Each offer carries 56 fields. The useful core for anyone consuming job data:

  • Identity and lifecycle - id, slug, guid, status (published offers only on this surface), created_at, published_at, updated_at and close_at, timestamped like 2026-08-14 08:23:10 UTC. Real publish timestamps are rarer in this industry than they should be.
  • Location - city, country_code, state_code, postal_code, a formatted location string, and a locations array for multi-site roles.
  • Classification - department, category_code, employment_type_code (values like fulltime_permanent), education_code, experience_code and free tags.
  • Work arrangement - three explicit booleans: remote, hybrid, on_site. Our sample tenant marked every Amsterdam role hybrid.
  • Content - description as HTML, a separate requirements field that in practice often arrives empty with everything folded into the description, and translations for multilingual tenants.

The one to distrust: salary. The object is always there - {min, max, period, currency} - and on every offer of the tenant we sampled, every value was null. Recruitee gives employers the field; European employers mostly decline to fill it. If you need advertised compensation, plan on parsing it from the description text or sourcing it elsewhere.

The rest of the 56 are application-form plumbing - options_cv, options_cover_letter, open_questions, dynamic_fields - which matter only if you are building an apply flow, plus social sharing_* images and titles.

The gated ATS API changed in late 2025

If you are a Recruitee customer integrating your own account, the picture moved recently. Recruitee introduced rate limiting on the ATS API in October 2025, and on December 1, 2025 shipped a rebuilt /offers endpoint with more filtering options - the old reference is now flagged as a legacy endpoint, and the classic examples (GET /c/{company_id}/offers?scope=active&view_mode=brief, where the subdomain works in place of the numeric company id) sit under a migration notice. Custom integrations written before late 2025 may need code changes. The public Careers Site API is not part of that migration.

Where the one-tenant model stops

In the taxonomy of public versus gated ATS APIs, Recruitee lands in the best tier: genuinely public postings, no key at all - friendlier than Teamtailor’s clean but key-per-tenant API. The structural limit is the same as every per-company surface. The endpoint answers “what is company X hiring?” perfectly, one X at a time. It cannot answer “which companies are hiring data engineers in the Netherlands right now?” - there is no cross-tenant search and no directory of Recruitee customers to enumerate. You discover subdomains one by one, and you poll each one yourself.

Cross-company search is a different product

That aggregation layer is what JobsPipe sells. We index live postings from 11 source platforms - LinkedIn, Indeed, Workday, Greenhouse and the other majors - where the companies you would poll tenant-by-tenant cross-post the same roles, normalized into one schema with skills, ISCO-08 occupation codes and industry classification attached:

curl https://api.jobspipe.dev/v1/jobs/search \
  -H "Authorization: Bearer jp_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "job_title_or": ["data engineer"],
    "job_country_code_or": ["NL", "DE"],
    "posted_at_max_age_days": 14,
    "limit": 25
  }'

One request, every company hiring for the role across sources - scope to a single employer with company_name_partial_match_or when you do want the one-company view. The free tier includes 1,000 jobs per month, and the wider market is compared in the best jobs APIs of 2026.

A fair split: the Recruitee Careers Site API is exactly right for rendering one company’s openings on a custom site - public, stable, full descriptions in one call. The moment the question becomes who is hiring rather than what X is hiring, you need an aggregator.

Cross-company job search over 11 platforms - full postings, free tier included.

Get a free API key

Skip the scraper - try the API right now

Live, normalized postings from 30+ ATS feeds and job boards in one JSON schema. No key, no signup - this sandbox returns sample data in the exact live shape.

Results

Press Test search to see normalized job records rendered here, and the raw JSON on the right.

JSON responsePOST /v1/sandbox/jobs/search
{
  "job_title_or": [
    "software engineer"
  ],
  "limit": 3,
  "remote": true
}
Advanced: edit the raw request, or copy it as curl
curl -X POST https://api.jobspipe.dev/v1/sandbox/jobs/search \
  -H "Content-Type: application/json" \
  -d '{"job_title_or":["software engineer"],"remote":true,"limit":5}'

For live results, get a free key (1,000 jobs/month) and swap /v1/sandbox/jobs/search for /v1/jobs/search with an Authorization: Bearer header - request and response shapes are identical.