jobdata

Company Job History API Endpoint Documentation

Tracking company hiring activity over time.

Table of contents

Introduction

The Company Job History endpoint gives access pro+ subscribers of the jobdata API a weekly and monthly time series of job counts for every company. Each record covers one completed week or month and shows how many jobs were open at the end of the period, how many were newly published or expired during it, and how many jobs the company has published in total, together with breakdowns by work mode, experience level, salary disclosure, location and job type.

This makes it easy to spot hiring ramp-ups, freezes and shifts in role mix without having to reconstruct job lifecycles yourself. It is particularly useful for sales intelligence and lead scoring, investment and market research, and any product that tracks companies' hiring momentum over time.

How the History Is Calculated

The history is derived from the published and expired timestamps of every job we track. A job counts as open at the end of a period if it was published before the period ended and had not expired by then.

  • Weeks start on Monday at 00:00 UTC, months on the first day of the month at 00:00 UTC.
  • Only completed periods are included. For live numbers, use the num_jobs_open and num_jobs_total fields of the Companies endpoint.
  • The latest 6 weeks and 3 months are recalculated daily, so jobs detected as expired a few days late are reflected retroactively.
  • A record is only included for periods in which the company had open, new or expired jobs.
  • Periods that ended before we started tracking a company are left out. The coverage_start field shows when tracking began, so values for the first period after that date may still be partial.

Limitations

The history inherits the limitations of our expired jobs data: the expired timestamp reflects when we detected that a job was no longer available, usually within a day, but for some sources it can take longer. Jobs that are never detected as expired are closed automatically after 180 days, which can make open counts of affected companies look higher than they are. The open_aged_90d field helps to identify and discount such long-running listings.

Breakdowns such as work mode, experience level and salary are based on the current attributes of each job, as we continuously improve our classification of existing listings. Jobs without a publication date are not included, so total_end can differ slightly from a company's num_jobs_total.

Endpoint Overview

Endpoint (list): /api/companyjobhistory/

Method: GET

Authorization Required: Yes (access pro+ subscription)

Description: Retrieves weekly or monthly job count history records for active companies, ordered by company ID and period start.

Request

Making a request to the Company Job History endpoint requires an authorization header with a pro+ access API key. Below are examples of how to make a request using curl and Python.

Using curl

curl -X GET "https://jobdataapi.com/api/companyjobhistory/?company_id=71605&period=week&period_start_since=2026-08-01" -H "Authorization: Api-Key YOUR_API_KEY"

Using Python

import requests

url = "https://jobdataapi.com/api/companyjobhistory/"
params = {
    "company_id": 71605,
    "period": "month",
    "period_start_since": "2025-11-01",
}
headers = {"Authorization": "Api-Key YOUR_API_KEY"}

response = requests.get(url, params=params, headers=headers)
data = response.json()

for row in data["results"]:
    print(row["period_start"], row["open_end"], row["new_count"], row["expired_count"])

Replace YOUR_API_KEY with your actual pro+ access API key.

Parameters

Some parameters allow for multiple values to be set. These are indicated by [mi] =multi-ID right behind their parameter name.

  • company_id [mi]: Filters records by company ID (see Companies endpoint for more info).
  • period: Period type, either week or month. Defaults to month when not set.
  • period_start_since: Limits results to periods starting on or after this date. Format: YYYY-MM-DD.
  • period_start_until: Limits results to periods starting on or before this date. Format: YYYY-MM-DD.
  • page: Specifies the page number of results to return.
  • page_size: Determines the number of results per page (1 - 4000, default: 200).

Unknown query parameters return a 400 response (bad request). Requests without a valid pro+ API key return a 403 response (forbidden).

Response

The response is a paginated JSON object containing a list of history records.

Response Structure

  • count: An integer representing the total number of records that match the query criteria.
  • next: A URL string pointing to the next page of results, or null if there is no next page.
  • previous: A URL string pointing to the previous page of results, or null on the first page.
  • results: An array of history records.

History Records (results Array)

Each record describes one company in one period:

  • company_id: The ID of the company (see Companies endpoint).
  • period: The period type, week or month.
  • period_start: The first day of the period (YYYY-MM-DD). The period ends right before the next period starts.
  • coverage_start: The date we started tracking jobs for this company (YYYY-MM-DD).
  • open_end: Number of jobs open at the end of the period.
  • new_count: Number of jobs published during the period.
  • expired_count: Number of jobs that expired during the period.
  • total_end: Total number of jobs the company published up to the end of the period.
  • open_aged_90d: Number of jobs open at the end of the period that had been published more than 90 days earlier.

Breakdowns are provided for jobs open at the end of the period (open_*) and for jobs published during the period (new_*):

  • open_remote / new_remote: Jobs offering remote or hybrid work (has_remote).
  • open_wm_hybrid, open_wm_remote, open_wm_remote_any, open_wm_unknown (and new_wm_*): Jobs by work_mode (hybrid, remote, remote anywhere, unknown or unclassified).
  • open_exp_en, open_exp_mi, open_exp_se, open_exp_ex, open_exp_unknown (and new_exp_*): Jobs by experience_level (entry, mid, senior, executive, unknown).
  • open_salary_disclosed / new_salary_disclosed: Jobs with a salary stated in the job post (salary estimates are not counted).

Additional details for jobs open at the end of the period:

  • open_salary_min_usd_median / open_salary_max_usd_median: Median of the USD-indexed minimum and maximum annual salary of open jobs with a stated salary, or null if none are available.
  • open_countries: The top 10 job countries as an object of ISO 3166-1 alpha-2 country codes and job counts (see Job Countries).
  • open_job_types: Job counts per job type as an object of job type IDs and job counts (see Job Types).
  • calculated_at: When the record was last calculated (ISO 8601).

A job can be counted in more than one breakdown group (e.g. in several countries), so country counts do not necessarily add up to open_end.

Example Response

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "company_id": 71605,
      "period": "month",
      "period_start": "2026-09-01",
      "coverage_start": "2025-06-12",
      "open_end": 812,
      "new_count": 164,
      "expired_count": 139,
      "total_end": 2931,
      "open_aged_90d": 97,
      "open_remote": 215,
      "open_wm_hybrid": 128,
      "open_wm_remote": 79,
      "open_wm_remote_any": 8,
      "open_wm_unknown": 597,
      "open_exp_en": 61,
      "open_exp_mi": 402,
      "open_exp_se": 301,
      "open_exp_ex": 22,
      "open_exp_unknown": 26,
      "open_salary_disclosed": 233,
      "new_remote": 41,
      "new_wm_hybrid": 25,
      "new_wm_remote": 14,
      "new_wm_remote_any": 2,
      "new_wm_unknown": 123,
      "new_exp_en": 15,
      "new_exp_mi": 80,
      "new_exp_se": 58,
      "new_exp_ex": 4,
      "new_exp_unknown": 7,
      "new_salary_disclosed": 52,
      "open_salary_min_usd_median": 118000,
      "open_salary_max_usd_median": 164000,
      "open_countries": {"US": 412, "IN": 96, "GB": 54, "CA": 41, "DE": 33, "PH": 28, "SG": 19, "MX": 16, "CO": 14, "CH": 12},
      "open_job_types": {"5": 798, "1": 14},
      "calculated_at": "2026-11-09T09:31:07.412093Z"
    },
    {
      "company_id": 71605,
      "period": "month",
      "period_start": "2026-10-01",
      "coverage_start": "2025-06-12",
      "open_end": 827,
      "new_count": 151,
      "expired_count": 136,
      "total_end": 3082,
      "open_aged_90d": 104,
      "...": "..."
    }
  ]
}

Bulk Downloads

access ultra subscribers can also download the complete history (weekly and monthly records for all active companies) as company_job_history.csv.gz with the weekly CSV and Parquet file downloads. The columns match the response fields above, with open_countries and open_job_types serialized as JSON strings. A small sample covering the latest 12 months for the companies in our 5K sample is included in the sample files and the demo SQLite database (company_job_history table).

Use Cases

  • Sales Intelligence: Identify companies that are ramping up hiring in specific roles, seniority levels or countries and prioritize outreach accordingly.
  • Investment Research: Track hiring momentum as an early signal of growth, restructuring or slowdowns.
  • Market Research: Compare remote-work adoption, seniority mix and salary transparency across companies and over time.
  • HR Tech: Enrich company profiles with historical hiring trends and charts.

Notes

  • Combine period_start_since and period_start_until to request a specific date range.
  • Use multiple company IDs (e.g. company_id=123|456|789) to fetch the history of several companies in one request.
  • Records of companies that are inactive in our database are not returned.
  • This endpoint is only accessible to users with an access pro+ subscription or higher.

Related Docs

CSV and Parquet File Downloads Documentation

Explore jobdata API with AI tools

Ask an AI assistant how to search and build with live job data.