New jobs

Active jobs we first collected in a time window, as a JSON array. This is the feed to poll when you keep your own copy of the catalogue: call it on a fixed schedule and every new job reaches you once.

GET/v1/active-ats

Time frames

ValueUseWindow
1hHourly pollingThe last full UTC hour. Called at 09:15 it returns jobs collected 08:00–09:00. Each hour becomes available two minutes after it ends.
24hDaily polling (default)The 24 hours up to the last full UTC hour. Call it in the same hour every day.
7dShort backfillRolling 7 days up to now.
6mFull backfillEvery active job collected in the last 183 days, which is essentially the whole catalogue. Page it with cursor.

Why windows end on the hour

A window that ends at a fixed hour boundary returns the same jobs whenever in the next hour you call it, so hourly or daily polling never skips or repeats a job. For the freshest data, poll 1h a few minutes after each hour, or use the changes feed, which is seconds behind collection.

Parameters

Pagination and response

ParameterTypeDescription
time_framestring1h, 24h, 7d or 6m. Default 24h.
limitintegerJobs per page, 1–1000. Default 100.
offsetintegerJobs to skip. Pages are ordered by date_posted, newest first (jobs without a posted date use date_created).
cursorintegerPass the last id of the previous page. Orders by id ascending and overrides offset. Use it for 6m backfills.
description_formatstringtext or html. Omit to leave descriptions out, which keeps pages small.
include_source_fieldsbooleantrue adds source_fields: department, pay tiers, qualifications and other facts exactly as the employer published them, with where each was found.
include_basic_organization_details, include_betabooleanAccepted for compatibility; they add no fields.

Search

ParameterTypeDescription
titlestringSearch the title. nurse manager needs both words, "nurse manager" is a phrase, nurse OR manager either, -assistant excludes, engineer* is a prefix.
descriptionstringSame syntax, over the title, employer name and description together.
locationstringFull place names, City, Region, Country, combined with OR. See Location search.
title_advanced, description_advanced, location_advanced, organization_advancedstringBoolean expressions with &, |, !, <->, parentheses and :*. They take precedence over the plain parameter. See Advanced search.

Dates

ParameterTypeDescription
date_posted_gte, date_posted_ltISO 8601When the employer says the job was posted. A time without a zone is UTC.
date_created_gte, date_created_ltISO 8601When we first collected the job. Use these to replay a missed window exactly. See Time fields.

Filters

ParameterTypeDescription
countrylistCA, US or both (the default).
organization, exclude_organizationlistExact, case-sensitive employer names, comma-separated. Quote a name that contains a comma: "Acme, Inc.". The organization list has every name.
source, exclude_sourcelistSource systems, e.g. workday,icims. See Sources.
has_salarybooleantrue: the employer published pay. false: it did not.
remotebooleantrue: marked remote by the employer. false: not remote.
has_no_locationbooleantrue: jobs without a resolved location.
idlistOnly these job ids.

Unknown parameters are rejected with a suggestion (timeframe → time_frame) instead of being ignored, so a typo never silently widens your results.

Example

bash
curl --get "https://api.thejobsapi.com/v1/active-ats" \
  -H "Authorization: Bearer $THEJOBSAPI_KEY" \
  --data-urlencode 'time_frame=1h' \
  --data-urlencode 'title="registered nurse" OR rn' \
  --data-urlencode 'location="Ontario, Canada" OR "New York, United States"' \
  --data-urlencode 'description_format=text'

Pagination

For 1h, 24h and 7d, page with offset: request limit=1000&offset=0, then offset=1000, and so on until a page has fewer than limit jobs.

For 6m, use cursor: start with cursor=0 and pass the last id of each page. Cursor pages are ordered by id and stay fast however deep you go.

Backfill with cursor
let cursor = 0;
for (;;) {
  const url = `https://api.thejobsapi.com/v1/active-ats?time_frame=6m&limit=1000&cursor=${cursor}&description_format=html`;
  const response = await fetch(url, { headers: { Authorization: `Bearer ${process.env.THEJOBSAPI_KEY}` } });
  if (!response.ok) throw new Error((await response.json()).detail);
  const jobs = await response.json();
  await saveJobs(jobs);
  if (jobs.length < 1000) break;
  cursor = jobs[jobs.length - 1].id;
}

Response

An array of jobs. Fields we don't collect are null; see Job fields for every field and where it comes from.

json
[
  {
    "id": 4183022,
    "title": "Registered Nurse, Emergency",
    "organization": "Example Health",
    "organization_url": null,
    "organization_logo": null,
    "date_posted": "2026-10-12T00:00:00Z",
    "date_created": "2026-10-12T14:31:07Z",
    "date_valid_through": "2026-11-01T00:00:00Z",
    "locations": [{
      "@type": "Place",
      "address": { "@type": "PostalAddress", "addressLocality": "Toronto", "addressRegion": "ON", "addressCountry": "CA" },
      "latitude": 43.70011, "longitude": -79.4163
    }],
    "locations_alt": ["Toronto, ON"],
    "locations_derived": ["Toronto, Ontario, Canada"],
    "location_type": null,
    "location_requirements": null,
    "salary": {
      "@type": "MonetaryAmount", "currency": "CAD",
      "value": { "@type": "QuantitativeValue", "minValue": 42.5, "maxValue": 51.0, "unitText": "HOUR" }
    },
    "employment_type": ["FULL_TIME"],
    "url": "https://example.wd3.myworkdayjobs.com/careers/job/Toronto/Registered-Nurse_R12345",
    "source": "workday",
    "source_type": "ats",
    "source_domain": "example.wd3.myworkdayjobs.com",
    "source_slug": "example.wd3.myworkdayjobs.com/careers",
    "domain_derived": null,
    "cities_derived": ["Toronto"],
    "counties_derived": null,
    "regions_derived": ["Ontario"],
    "countries_derived": ["Canada"],
    "timezones_derived": null,
    "lats_derived": [43.70011],
    "lngs_derived": [-79.4163],
    "country": "CA",
    "apply_url": null,
    "work_arrangement": "onsite"
  }
]

Usage

Each job returned counts once toward your plan's job allowance; each call counts as one request. See Errors, limits & usage.