API DOCUMENTATION / API REFERENCE

OpenAPI reference

Every route, parameter, request body, response and schema in the live OpenAPI specification.

Endpoints

Every route in the live OpenAPI specification (16 operations), with its parameters, request body and responses. Base URL: https://api.headcountlabs.com. The machine-readable source is https://api.headcountlabs.com/openapi (OpenAPI 3.1.0).

Method and pathSummary
GET /v1/companiesBrowse companies
POST /v1/companies/searchSearch companies
GET /v1/companies/{companyId}Get a company by UUID
GET /v1/companies/{companyId}/jobsList a company's jobs
GET /v1/jobsList public jobs
POST /v1/jobs/search/es_dslSearch public jobs with Elasticsearch-style clauses
POST /v1/jobs/exportsCreate a bulk jobs export
GET /v1/jobs/exportsList recent jobs exports
GET /v1/jobs/exports/{exportId}Get a jobs export
GET /v1/jobs/exports/{exportId}/files/{n}Download a gzip JSON Lines export file
GET /v1/jobs/changesList public job changes
GET /v1/jobs/countCount public jobs
GET /v1/jobs/{jobId}Get a job by ID
PUT /v1/account/overageTurn overage billing on or off and set its monthly limit
GET /v1/usage/requestsList customer request events
GET /v1/usage/analyticsRead customer daily usage

Overview

Search and sync job postings collected from employers' own job sources, with company records.

Authentication: send your API key as a bearer token, Authorization: Bearer jc_live_<id>.<secret> (keys issued before October 2026 start with ar_live_ and still work). Create keys in your account. A missing or wrong key returns 401 invalid_api_key.

Paging: list endpoints return next_cursor; pass it back as cursor for the next page. Every page of one listing reads the same catalog snapshot (snapshot_watermark), so results don't shift under you. A cursor from an older snapshot or with different filters returns 400; start again from the first page.

Keeping in sync: pull GET /v1/jobs/changes with since for the first call, then keep passing resume_cursor as after to receive created, updated and expired jobs in order.

Limits: your plan sets a request rate and a monthly allowance of returned records. Only successful responses count, and each job or company returned counts as one record; counts and usage reports are free. Going over returns 429 (rate_limited or data_limit_exceeded) with a Retry-After header in seconds. Paid plans can turn on overage (PUT /v1/account/overage) to go past the monthly job allowance, optionally with a monthly overage limit in dollars. Overage never adds API requests: the monthly request allowance still applies.

Errors always look like {"error": {"code", "message", "request_id"}}. Quote request_id when you contact support. 503 catalog_unavailable means the jobs catalog is being published; retry shortly. 504 query_timeout means a search ran longer than 10 seconds and was stopped; it uses no records. Narrow the filters and try again.

GET /v1/companies

Browse companies

Lists companies from one immutable registry release.

Parameters

NameInTypeDescription
namequerystring; min length 1, max length 200Case-insensitive canonical-name substring.
limitqueryinteger; min 1, max 100, default 50Page size, 1-100. Defaults to 50.
cursorquerystring; min length 1, max length 2048The next_cursor from the previous page. It pins the company release it started on.

Responses

StatusMeaningBody
200A page of public company records.CompanyPage
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope

POST /v1/companies/search

Search companies

Combines verified name, country, and status filters with AND. Search uses the same UUID company records and release-pinned cursor as company browse.

Request body (JSON, required)

Schema: CompanySearchRequest.

FieldTypeRequiredDescription
namestring; min length 1, max length 200noCase-insensitive canonical-name substring after trimming.
countrystringnoISO 3166-1 alpha-2 code, case-insensitive.
statusstring: "active", "retired", "merged"no
limitinteger; min 1, max 100, default 50no
cursorstring; min length 1, max length 2048no

Responses

StatusMeaningBody
200A page of matching public company records.CompanyPage
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope

GET /v1/companies/{companyId}

Get a company by UUID

Parameters

NameInTypeDescription
companyId (required)pathCompanyIdAtlas company ID (lowercase UUID). A merged company's old ID redirects (308) to its current ID.

Responses

StatusMeaningBody
200A public company record.object
308A merged company ID redirects to its current UUID.
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
404The company or customer-owned API key was not found.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope

GET /v1/companies/{companyId}/jobs

List a company's jobs

Lists the company's public jobs from the latest published jobs catalog, with the same filters, order and cursor rules as GET /v1/jobs. Resolves the company UUID and redirects merged IDs. Requires an active company registry release and a published jobs catalog, and responds 503 while either is missing.

Parameters

NameInTypeDescription
companyId (required)pathCompanyIdAtlas company ID (lowercase UUID). A merged company's old ID redirects (308) to its current ID.
fieldsquerystringComma list of the job properties to return; repeat the parameter or separate names with commas. Allowed names are job_id, currentness, stale, company_id, employer_name, title, description, work_arrangement, locations, job_first_seen_at, curated_at, job_updated_at, postings and company. job_id is always returned. Without fields the whole job is returned. An unknown name returns 400. It changes only the shape of each job, never which jobs match.

Responses

StatusMeaningBody
308A merged company ID redirects to its current UUID.
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
404The company or customer-owned API key was not found.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope
504The query did not finish within 10 seconds (code query_timeout). No records are charged. Narrow the filters, for example add a state, title, or employer, and try again.ErrorEnvelope

GET /v1/jobs

List public jobs

Returns included public jobs from the latest published jobs catalog. A search with q, title or description is ranked by relevance, with title matches weighted ten times description matches; any other list, or sort=updated, is newest job_updated_at first. Ties break by job_id, descending. Without a currentness or active filter only current jobs are returned. Every page of one listing reads the same catalog snapshot: next_cursor is bound to that snapshot, the filters and the limit, and a cursor from an older snapshot or a different query returns 400. Responds 503 catalog_unavailable while no jobs catalog has been published.

Parameters

NameInTypeDescription
companyquerystring; min length 1, max length 200Employer name contains this text. Case-insensitive. 1-200 characters. A term of 1-2 characters matches the whole employer name or its first word instead (`hp` finds "HP Inc." but not "Shop HP Repairs").
company_idqueryCompanyIdOnly jobs of this company, by its Atlas company ID (lowercase UUID).
titlequerystring; min length 1, max length 200Job title contains these words as one phrase, in this order (full-text match). "senior software engineer" does not match "Software Engineer, Senior" or "Senior Staff Software Engineer"; use title_advanced, such as senior AND "software engineer", to match the words in any order. 1-200 characters.
title_advancedquerystring; min length 1, max length 200Boolean title search: the words may appear in any order. Supports AND, OR and NOT keywords, &, | and !, parentheses, prefix terms such as engineer:*, and quoted phrases such as "product manager". Prefer it over title when job titles vary in word order, for example senior AND ("software engineer" OR "software developer"). A positive search term is required.
description_advancedquerystring; min length 1, max length 200Boolean description search. Supports AND, OR and NOT keywords, &, | and !, parentheses, prefix terms such as engineer:*, and quoted phrases such as "product manager". A positive search term is required.
qquerystring; min length 1, max length 200Keyword search: the phrase appears in the title or description. Results are ranked by relevance unless sort=updated. 1-200 characters.
locationquerystring; min length 1, max length 200Any job location contains this text (city, region or country as written). Case-insensitive. 1-200 characters.
statequerystring; min length 1, max length 200Two-letter subdivision code. On its own it means a U.S. state (state=CA is California only); combine with country for another country's subdivision (country=CA&state=BC is British Columbia).
countryquerystringTwo-letter ISO country code, for example US or CA. Case-insensitive. Send up to 10 codes separated by commas to match jobs in any of them.
msaquerystring5-digit CBSA code of a metropolitan or micropolitan statistical area, for example 12420 for Austin-Round Rock-San Marcos, TX. Matches any job location whose msa.cbsa_code equals it.
work_arrangementquerystring: "remote", "hybrid", "in_person"One of remote, hybrid or in_person, as the source states it. Jobs whose source doesn't say are not matched.
remote_typequerystring: "remote", "hybrid", "in_person"Alias for work_arrangement; do not send both.
employment_typequerystring; min length 1, max length 200Employment type as published, for example full_time or part_time. Exact match, case-insensitive. Send up to 10 values separated by commas to match jobs with any of them.
sourcequerystring; min length 1, max length 200The source vendor, such as greenhouse or smartrecruiters. Board IDs are not exposed.
currentnessquerystring; default "current"Comma list of current, uncertain and not_current.
activequerybooleantrue maps to currentness=current and false to currentness=not_current; do not send with currentness.
posted_sincequerystring (date) or string (date-time)Posted on or after this time, by the date the source published. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21). A plain date means the start of that day in UTC.
posted_untilquerystring (date) or string (date-time)Posted on or before this time. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21). A plain date means the end of that day in UTC.
published_sincequerystring (date) or string (date-time)Compatibility alias for posted_since; do not send both.
first_seen_sincequerystring (date) or string (date-time)First collected by Atlas on or after this time. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21).
updated_sincequerystring (date) or string (date-time)Job record last changed on or after this time; use it for incremental pulls. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21).
curated_sincequerystring (date) or string (date-time)Entered the final dataset on or after this time. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21).
job_idquerystring (uuid)One job by its job ID (a lowercase UUID).
descriptionquerystring; min length 1, max length 200Words that must appear together in the job description. Use description_advanced for a Boolean expression.
cityquerystring; min length 1, max length 200City name. Matches any job location whose city contains this text, case-insensitive. Combine with state and country to narrow it.
exclude_sourcequerystring; max length 200Comma list of up to 10 source vendors or source types to leave out. A job still matches when another of its postings comes from a source not on the list.
source_typequerystring; min length 1, max length 200The kind of job source, as in postings[].source_data.source_type. Exact match, case-insensitive.
source_classquerystring: "ats", "employer-site", "government-exchange", "aggregator", "staffing-network", "dataset", "purchased", "third-party-api", "unknown"The class of job source a posting came from, for example ats for an applicant tracking system board or employer-site for a company's own careers page.
posting_idquerystring; min length 1, max length 200The job that holds this posting, by Atlas's posting ID.
source_posting_idquerystring; min length 1, max length 200Jobs with a posting that has this source posting ID (the job source's own ID for the listing).
posting_statusquerystring: "listed", "no_longer_listed"Jobs with a posting in this state. listed means the source still shows it; no_longer_listed means a completed read no longer found it.
stalequerybooleantrue for jobs first listed more than 30 days ago (the earlier of the date Atlas first saw the job and the source's posted date), updated daily; false for the rest. Stale jobs stay in results; pass stale=false to leave them out.
company_linkedquerybooleantrue for jobs linked to a company record (company_id is set); false for jobs with no linked company.
has_descriptionquerybooleantrue for jobs with a known description; false for jobs without one.
has_locationquerybooleantrue for jobs with at least one known location; false for jobs with none.
has_payquerybooleantrue for jobs with a posting that publishes pay; false for jobs with a posting that does not.
has_posting_urlquerybooleantrue for jobs with a posting that has a known listing URL.
has_application_urlquerybooleantrue for jobs with a posting that has a known application URL.
pay_currencyquerystringISO 4217 currency code. Jobs with a posting whose published pay is in this currency.
pay_minquerynumber; min 0, max 1000000000Lowest yearly pay. Matches postings whose pay floor is at least this amount. Pay is compared per year (hourly x 2,080, monthly x 12); pay with an unknown interval never matches. Amounts are not converted between currencies, so pair it with pay_currency. Up to two decimal places.
pay_maxquerynumber; min 0, max 1000000000Highest yearly pay. Matches postings whose pay ceiling is at most this amount, compared per year the same way as pay_min. Must not be below pay_min.
first_seen_untilquerystring (date) or string (date-time)First collected by Atlas on or before this time. Accepts an RFC 3339 timestamp or a plain date.
updated_untilquerystring (date) or string (date-time)Last changed on or before this time. Accepts an RFC 3339 timestamp or a plain date.
curated_untilquerystring (date) or string (date-time)Entered the final dataset on or before this time. Accepts an RFC 3339 timestamp or a plain date.
last_fetch_sincequerystring (date) or string (date-time)Jobs with a posting whose job source was last read completely on or after this time. Accepts an RFC 3339 timestamp or a plain date.
last_fetch_untilquerystring (date) or string (date-time)Jobs with a posting whose job source was last read completely on or before this time. Accepts an RFC 3339 timestamp or a plain date.
application_checkquerystring: "available", "closed", "broken", "inconclusive"Jobs with a posting whose latest application check had this result. available means an application could still be started.
application_check_sincequerystring (date) or string (date-time)Jobs with a posting whose latest application check ran on or after this time. Accepts an RFC 3339 timestamp or a plain date.
includequerystringComma list containing company and/or source_data. company adds the linked public company record; source_data adds each posting's source data.
fieldsquerystringComma list of the job properties to return; repeat the parameter or separate names with commas. Allowed names are job_id, currentness, stale, company_id, employer_name, title, description, work_arrangement, locations, job_first_seen_at, curated_at, job_updated_at, postings and company. job_id is always returned. Without fields the whole job is returned. An unknown name returns 400. It changes only the shape of each job, never which jobs match.
description_formatquerystring: "text", "html"; default "text"text returns descriptions as plain text. html returns 503 because source HTML descriptions are not published yet.
limitqueryinteger; min 1, max 1000, default 50Page size, 1-250, or 1-1,000 when fields is exactly job_id. Defaults to 50.
cursorquerystring; min length 1, max length 2048The next_cursor from the previous page. It is tied to the same filters, page size, sort and catalog snapshot; start again from the first page if you get a 400 for a stale cursor.
sortquerystring: "relevance", "updated"relevance ranks by how well q, title and description match, and is the default when one of them is set; it returns 400 without one. updated lists the most recently updated jobs first, and is the default otherwise.

Responses

StatusMeaningBody
200A page of public job records.JobListResponse
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope
504The query did not finish within 10 seconds (code query_timeout). No records are charged. Narrow the filters, for example add a state, title, or employer, and try again.ErrorEnvelope

POST /v1/jobs/search/es_dsl

Search public jobs with Elasticsearch-style clauses

Translates the supported Elasticsearch-style query subset to the same filters as POST /v1/jobs/search. All must and filter clauses are AND-ed. should is supported only for term or match clauses on the same country or employment_type field, including when must/filter is also present. Range gt is treated as inclusive gte, and lt as inclusive lte. The response, cursor, request charge, limits, and errors match POST /v1/jobs/search. Page size is 1-250, or 1-1000 when fields is exactly job_id.

Request body (JSON, required)

FieldTypeRequiredDescription
queryobjectyesOne supported clause: match_all, bool, term, terms, match, match_phrase, range, exists, query_string, or simple_query_string. Unsupported clauses and fields return 400 invalid_request. See the operation description and JobCensus API documentation for the accepted field list.
limitinteger; min 1, max 1000, default 50noPage size 1-250. Values 251-1000 are accepted only when fields is exactly job_id.
cursorstring; min length 1, max length 2048no
sortstring: "relevance", "updated"no
fieldsstring or array of stringno
includearray of string: "company", "source_data"no
description_formatstring: "text", "html"; default "text"no

Responses

StatusMeaningBody
200A page of public job records.JobListResponse
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope
504The query did not finish within 10 seconds (code query_timeout). No records are charged. Narrow the filters, for example add a state, title, or employer, and try again.ErrorEnvelope

POST /v1/jobs/exports

Create a bulk jobs export

Request body (JSON, required)

FieldTypeRequiredDescription
qstringno
fieldsarray of stringno
includearray of string: "company", "source_data"no
description_formatstring: "text", "html"; default "text"no
sortstring: "relevance", "updated"no
max_recordsinteger; min 1, max 100000, default 100000no

Responses

StatusMeaningBody
202Export acceptedJobsExport
400Invalid export request
401Invalid API key
409The account already has a queued or running export
429Monthly request allowance is insufficient
503Export service is unavailable

GET /v1/jobs/exports

List recent jobs exports

Responses

StatusMeaningBody
200Exports for the authenticated account, newest first, limited to 20object
401Invalid API key
503Export service is unavailable

GET /v1/jobs/exports/{exportId}

Get a jobs export

Parameters

NameInTypeDescription
exportId (required)pathstring (uuid)

Responses

StatusMeaningBody
200Export status and file metadataJobsExport
401Invalid API key
404Export does not exist or belongs to another account
503Export service is unavailable

GET /v1/jobs/exports/{exportId}/files/{n}

Download a gzip JSON Lines export file

Parameters

NameInTypeDescription
exportId (required)pathstring (uuid)
n (required)pathinteger; min 1

Responses

StatusMeaningBody
200Gzip-compressed JSON Lines filestring (binary) (application/gzip)
401Invalid API key
404File is unknown, not ready, expired, or belongs to another account
503Export service is unavailable

GET /v1/jobs/changes

List public job changes

Lists created, updated and expired job events from the latest published jobs catalog, in event order. Send exactly one of since or after: start with since, then pass resume_cursor as after. A cursor from an older catalog snapshot returns 400. Responds 503 catalog_unavailable while no jobs catalog has been published, and 503 service_unavailable when the catalog changes during the request (retry).

Parameters

NameInTypeDescription
afterquerystring; min length 1, max length 2048The resume_cursor from your previous changes call. Send exactly one of after or since.
sincequerystring (date-time)Start of the change window: changes strictly after this RFC 3339 timestamp. Use it for the first call, then continue with after.
typesquerystring; default "created,updated,expired"Comma list of created, updated and expired. Defaults to all three.
limitqueryinteger; min 1, max 1000, default 100Events per page, 1-1,000. Defaults to 100.
company_idqueryCompanyIdOnly changes for this company's jobs (lowercase UUID).
includequerystring: "source_data"source_data adds allowlisted source metadata to each job in the events. The source payload and internal extraction details are not published.

Responses

StatusMeaningBody
200A page of job changes.JobsChangesResponse
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope
504The query did not finish within 10 seconds (code query_timeout). No records are charged. Narrow the filters, for example add a state, title, or employer, and try again.ErrorEnvelope

GET /v1/jobs/count

Count public jobs

Counts jobs matching the same filters as GET /v1/jobs in the latest published jobs catalog, with that catalog's snapshot watermark. Responds 503 catalog_unavailable while no jobs catalog has been published.

Parameters

NameInTypeDescription
companyquerystring; min length 1, max length 200Employer name contains this text. Case-insensitive. 1-200 characters. A term of 1-2 characters matches the whole employer name or its first word instead (`hp` finds "HP Inc." but not "Shop HP Repairs").
company_idqueryCompanyIdOnly jobs of this company, by its Atlas company ID (lowercase UUID).
titlequerystring; min length 1, max length 200Job title contains these words as one phrase, in this order (full-text match). "senior software engineer" does not match "Software Engineer, Senior" or "Senior Staff Software Engineer"; use title_advanced, such as senior AND "software engineer", to match the words in any order. 1-200 characters.
title_advancedquerystring; min length 1, max length 200Boolean title search: the words may appear in any order. Supports AND, OR and NOT keywords, &, | and !, parentheses, prefix terms such as engineer:*, and quoted phrases such as "product manager". Prefer it over title when job titles vary in word order, for example senior AND ("software engineer" OR "software developer"). A positive search term is required.
description_advancedquerystring; min length 1, max length 200Boolean description search. Supports AND, OR and NOT keywords, &, | and !, parentheses, prefix terms such as engineer:*, and quoted phrases such as "product manager". A positive search term is required.
qquerystring; min length 1, max length 200Keyword search: the phrase appears in the title or description. 1-200 characters.
locationquerystring; min length 1, max length 200Any job location contains this text (city, region or country as written). Case-insensitive. 1-200 characters.
statequerystring; min length 1, max length 200Two-letter subdivision code. On its own it means a U.S. state (state=CA is California only); combine with country for another country's subdivision (country=CA&state=BC is British Columbia).
countryquerystringTwo-letter ISO country code, for example US or CA. Case-insensitive. Send up to 10 codes separated by commas to match jobs in any of them.
msaquerystring5-digit CBSA code of a metropolitan or micropolitan statistical area, for example 12420 for Austin-Round Rock-San Marcos, TX. Matches any job location whose msa.cbsa_code equals it.
work_arrangementquerystring: "remote", "hybrid", "in_person"One of remote, hybrid or in_person, as the source states it. Jobs whose source doesn't say are not matched.
remote_typequerystring: "remote", "hybrid", "in_person"Alias for work_arrangement; do not send both.
employment_typequerystring; min length 1, max length 200Employment type as published, for example full_time or part_time. Exact match, case-insensitive. Send up to 10 values separated by commas to match jobs with any of them.
sourcequerystring; min length 1, max length 200The source vendor, such as greenhouse or smartrecruiters. Board IDs are not exposed.
currentnessquerystring; default "current"Comma list of current, uncertain and not_current (combined with OR). Defaults to current. A job is current when a completed read of its job source listed it within the last 31 days and no check has found it closed.
activequerybooleantrue maps to currentness=current; do not send with currentness.
posted_sincequerystring (date) or string (date-time)Posted on or after this time, by the date the source published. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21). A plain date means the start of that day in UTC.
posted_untilquerystring (date) or string (date-time)Posted on or before this time. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21). A plain date means the end of that day in UTC.
published_sincequerystring (date) or string (date-time)Compatibility alias for posted_since; do not send both.
first_seen_sincequerystring (date) or string (date-time)First collected by Atlas on or after this time. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21).
updated_sincequerystring (date) or string (date-time)Job record last changed on or after this time; use it for incremental pulls. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21).
curated_sincequerystring (date) or string (date-time)Entered the final dataset on or after this time. Accepts an RFC 3339 timestamp with a time zone (2026-09-21T00:00:00Z) or a plain date (2026-09-21).
job_idquerystring (uuid)One job by its job ID (a lowercase UUID).
descriptionquerystring; min length 1, max length 200Words that must appear together in the job description. Use description_advanced for a Boolean expression.
cityquerystring; min length 1, max length 200City name. Matches any job location whose city contains this text, case-insensitive. Combine with state and country to narrow it.
exclude_sourcequerystring; max length 200Comma list of up to 10 source vendors or source types to leave out. A job still matches when another of its postings comes from a source not on the list.
source_typequerystring; min length 1, max length 200The kind of job source, as in postings[].source_data.source_type. Exact match, case-insensitive.
source_classquerystring: "ats", "employer-site", "government-exchange", "aggregator", "staffing-network", "dataset", "purchased", "third-party-api", "unknown"The class of job source a posting came from, for example ats for an applicant tracking system board or employer-site for a company's own careers page.
posting_idquerystring; min length 1, max length 200The job that holds this posting, by Atlas's posting ID.
source_posting_idquerystring; min length 1, max length 200Jobs with a posting that has this source posting ID (the job source's own ID for the listing).
posting_statusquerystring: "listed", "no_longer_listed"Jobs with a posting in this state. listed means the source still shows it; no_longer_listed means a completed read no longer found it.
stalequerybooleantrue for jobs first listed more than 30 days ago (the earlier of the date Atlas first saw the job and the source's posted date), updated daily; false for the rest. Stale jobs stay in results; pass stale=false to leave them out.
company_linkedquerybooleantrue for jobs linked to a company record (company_id is set); false for jobs with no linked company.
has_descriptionquerybooleantrue for jobs with a known description; false for jobs without one.
has_locationquerybooleantrue for jobs with at least one known location; false for jobs with none.
has_payquerybooleantrue for jobs with a posting that publishes pay; false for jobs with a posting that does not.
has_posting_urlquerybooleantrue for jobs with a posting that has a known listing URL.
has_application_urlquerybooleantrue for jobs with a posting that has a known application URL.
pay_currencyquerystringISO 4217 currency code. Jobs with a posting whose published pay is in this currency.
pay_minquerynumber; min 0, max 1000000000Lowest yearly pay. Matches postings whose pay floor is at least this amount. Pay is compared per year (hourly x 2,080, monthly x 12); pay with an unknown interval never matches. Amounts are not converted between currencies, so pair it with pay_currency. Up to two decimal places.
pay_maxquerynumber; min 0, max 1000000000Highest yearly pay. Matches postings whose pay ceiling is at most this amount, compared per year the same way as pay_min. Must not be below pay_min.
first_seen_untilquerystring (date) or string (date-time)First collected by Atlas on or before this time. Accepts an RFC 3339 timestamp or a plain date.
updated_untilquerystring (date) or string (date-time)Last changed on or before this time. Accepts an RFC 3339 timestamp or a plain date.
curated_untilquerystring (date) or string (date-time)Entered the final dataset on or before this time. Accepts an RFC 3339 timestamp or a plain date.
last_fetch_sincequerystring (date) or string (date-time)Jobs with a posting whose job source was last read completely on or after this time. Accepts an RFC 3339 timestamp or a plain date.
last_fetch_untilquerystring (date) or string (date-time)Jobs with a posting whose job source was last read completely on or before this time. Accepts an RFC 3339 timestamp or a plain date.
application_checkquerystring: "available", "closed", "broken", "inconclusive"Jobs with a posting whose latest application check had this result. available means an application could still be started.
application_check_sincequerystring (date) or string (date-time)Jobs with a posting whose latest application check ran on or after this time. Accepts an RFC 3339 timestamp or a plain date.

Responses

StatusMeaningBody
200Matching job count and snapshot watermark.JobCountResponse
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope
504The query did not finish within 10 seconds (code query_timeout). No records are charged. Narrow the filters, for example add a state, title, or employer, and try again.ErrorEnvelope

GET /v1/jobs/{jobId}

Get a job by ID

Returns one job with all its linked postings from the latest published jobs catalog. Responds 503 catalog_unavailable while no jobs catalog has been published.

Parameters

NameInTypeDescription
jobId (required)pathJobIdAtlas job ID (lowercase UUID). A merged job redirects (308) to the job it merged into; a withdrawn job returns 410.
fieldsquerystringComma list of the job properties to return; repeat the parameter or separate names with commas. Allowed names are job_id, currentness, stale, company_id, employer_name, title, description, work_arrangement, locations, job_first_seen_at, curated_at, job_updated_at, postings and company. job_id is always returned. Without fields the whole job is returned. An unknown name returns 400. It changes only the shape of each job, never which jobs match.

Responses

StatusMeaningBody
200A public job record with all linked postings.JobDetailResponse
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope
504The query did not finish within 10 seconds (code query_timeout). No records are charged. Narrow the filters, for example add a state, title, or employer, and try again.ErrorEnvelope

PUT /v1/account/overage

Turn overage billing on or off and set its monthly limit

Overage is off by default: at the monthly job limit (plus any unused jobs carried over) requests stop with 429 data_limit_exceeded. Turn it on to keep going past the plan, billed at month end at the plan's price per 1,000 jobs (5,000 plan $3.00; 10,000 $2.70; 20,000 $2.40; 50,000 $2.10; 100,000 $1.88; 250,000 $1.65; 500,000 $1.50), rounded up to the cent. monthlyLimitUsd is an optional monthly overage limit in US dollars (a positive number with at most two decimals, up to 100000). With no limit, which is the default, overage has no ceiling. With a limit, once the month's overage dollars reach it requests stop with 429 data_limit_exceeded, nothing is billed above it, and a page that would cross it is refused whole. A limit of N dollars allows floor(N x 100 x 1000 / the plan's cents per 1,000 jobs) overage jobs: $1.00 on the 5,000 plan allows 333. null clears the limit and leaving the field out keeps the stored one. Overage does not add API requests: the monthly request allowance still applies with overage on. Needs a paid plan with an active subscription: the free plan answers 403 upgrade_required with an upgrade_url, and a plan without an active paid subscription answers 403 no_active_subscription. The same change is available to agents as the set_overage MCP tool. This request is not counted against the request windows or the monthly allowance.

Request body (JSON, required)

FieldTypeRequiredDescription
enabledbooleanno
monthlyLimitUsdnumber or null; above 0, max 100000noMonthly overage limit in US dollars; null clears it (no limit). Omit to keep the stored value.

Responses

StatusMeaningBody
200The overage setting and this month's overage use.OverageStatus
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
403upgrade_required (free plan; the error carries upgrade_url) or no_active_subscription.ErrorEnvelope
409overage_item_conflict. The subscription already carries another plan's overage price; contact support.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope

GET /v1/usage/requests

List customer request events

Lists the authenticated customer's admitted requests. The cursor freezes admission membership for one hour; settlement status stays current.

Parameters

NameInTypeDescription
from (required)querystring (date-time)Inclusive UTC RFC 3339 timestamp.
to (required)querystring (date-time)Exclusive UTC RFC 3339 timestamp; at most 31 days after from.
route_classquerystring: "jobs.list", "jobs.detail", "jobs.changes", "jobs.count", "companies.jobs", "companies.list", "companies.detail", "companies.search", "usage.requests", "usage.analytics"Only requests of this kind, for example jobs.list, jobs.count or companies.detail.
api_key_idquerystring; min length 1, max length 200Only requests made with this key (one of your own keys).
limitqueryinteger; min 1, max 100, default 50Rows per page, 1-100. Defaults to 50.
cursorquerystring; min length 1, max length 8192The next_cursor from the previous page. Usage cursors expire after one hour.

Responses

StatusMeaningBody
200A page of request events.UsageRequestsPage
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
404The company or customer-owned API key was not found.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope

GET /v1/usage/analytics

Read customer daily usage

Reports up to 100,000 unique events and 1,000 groups in a period of at most 31 days. Request metrics use admission day; record metrics use finalization day.

Parameters

NameInTypeDescription
from (required)querystring (date-time)Inclusive UTC RFC 3339 timestamp.
to (required)querystring (date-time)Exclusive UTC RFC 3339 timestamp; at most 31 days after from.
route_classquerystring: "jobs.list", "jobs.detail", "jobs.changes", "jobs.count", "companies.jobs", "companies.list", "companies.detail", "companies.search", "usage.requests", "usage.analytics"Only requests of this kind, for example jobs.list, jobs.count or companies.detail.
api_key_idquerystring; min length 1, max length 200Only requests made with this key (one of your own keys).
group_byquerystring: "route_class", "status_class", "api_key_id"Group the totals by route_class, status_class or api_key_id. Omit it for one overall total.

Responses

StatusMeaningBody
200Daily usage groups.UsageAnalytics
400The request parameters or body are invalid.ErrorEnvelope
401A valid bearer API key is required.ErrorEnvelope
404The company or customer-owned API key was not found.ErrorEnvelope
422The report exceeded a complete-result limit.ErrorEnvelope
429A request window or monthly returned-record allowance was reached.ErrorEnvelope
503The required service or publication is unavailable.ErrorEnvelope

Schemas

Every object returned or accepted by the routes above, with each field and its type.

JobsExport

FieldTypeRequiredDescription
export_idstring (uuid)yes
statusstring: "queued", "running", "completed", "failed", "expired"yes
created_atstring (date-time)yes
completed_atstring or null (date-time)yes
expires_atstring or null (date-time)yes
record_countinteger; min 0yes
snapshot_watermarkstring or nullyes
requestobjectyes
filesarray of objectyes
errorstringno

CompanyId

Type: string (uuid)

JobId

Type: string (uuid)

FieldStateSourceOmitted

The source did not publish this field.

FieldTypeRequiredDescription
stateanyyes

FieldStateSourceUnmapped

The source published a value outside this field's vocabulary. The value stays null and evidence keeps the source's own words.

FieldTypeRequiredDescription
stateanyyes
valuenullyes
evidencearray of stringyes

FieldStateExtractionFailed

The source published this field but Atlas could not read it.

FieldTypeRequiredDescription
stateanyyes

FieldStateKnownString

FieldTypeRequiredDescription
stateanyyes
valuestringyes

FieldStateDerivedString

A value computed from source data by a fixed rule, never by a model. Evidence names the rule's input.

FieldTypeRequiredDescription
stateanyyes
valuestringyes
evidencearray of stringyes

FieldStateString

Type: FieldStateKnownString or FieldStateSourceOmitted or FieldStateSourceUnmapped or FieldStateExtractionFailed or FieldStateDerivedString

FieldStateKnownWorkArrangement

FieldTypeRequiredDescription
stateanyyes
valuestring: "remote", "hybrid", "in_person"yes

FieldStateDerivedWorkArrangement

A value computed from source data by a fixed rule, never by a model. Evidence names the rule's input.

FieldTypeRequiredDescription
stateanyyes
valuestring: "remote", "hybrid", "in_person"yes
evidencearray of stringyes

FieldStateWorkArrangement

Type: FieldStateKnownWorkArrangement or FieldStateSourceOmitted or FieldStateSourceUnmapped or FieldStateExtractionFailed or FieldStateDerivedWorkArrangement

FieldStateKnownObject

FieldTypeRequiredDescription
stateanyyes
valueobjectyes

FieldStateDerivedObject

A value computed from source data by a fixed rule, never by a model. Evidence names the rule's input.

FieldTypeRequiredDescription
stateanyyes
valueobjectyes
evidencearray of stringyes

FieldStateObject

Type: FieldStateKnownObject or FieldStateSourceOmitted or FieldStateSourceUnmapped or FieldStateExtractionFailed or FieldStateDerivedObject

JobPosting

FieldTypeRequiredDescription
posting_idstringyesAtlas's ID for this posting (one public listing of the job on one job source).
sourcestringyesThe job source vendor, such as greenhouse or smartrecruiters.
source_posting_idstringyesThe job source's own ID for this posting.
posting_statusstring: "listed", "no_longer_listed"yeslisted while the source still shows the posting; no_longer_listed once a completed fetch no longer finds it.
posting_urlFieldStateStringyesThe posting's public page on the job source.
application_urlFieldStateStringyesWhere to apply for this posting, when the source gives an application link.
locationFieldStateObjectyesThe posting's location as the source published it (city, region, country). When the posting itself states a US postal code that is real and lies in the stated state, the object also has zip, the 5-digit ZIP (ZIP+4 is cut to 5). zip is absent for a city-only location, a street address without a ZIP, a remote posting and any non-US location; it is never derived from a city or a point.
payFieldStateObjectyesPay as the source published it (minimum, maximum, currency and period), not converted.
source_posted_atstring or null (date-time)yesThe date the job source says the posting was published.
first_seen_atstring (date-time)yesWhen Atlas first collected this posting.
last_completed_fetch_atstring or null (date-time)yesWhen Atlas last read the posting's job source completely.
latest_application_checkobject or nullyesAtlas's latest check of whether an application can still be started (available, closed, broken or inconclusive) and when it ran.
attributionobjectyesWhat the job source's rights record says about crediting it. null means the rights record does not say. When required is true, show text and link with the job.
source_dataobjectnoAllowlisted source metadata, present only when requested. The source payload and internal extraction details are not published.

Job

FieldTypeRequiredDescription
job_idJobIdyesThe combined JobCensus job ID. One job links every posting of the same opening.
merged_into_job_idJobIdnoPresent on merged-job redirects.
currentnessstring: "current", "uncertain", "not_current"yescurrent while a linked posting is listed and accepting applications; uncertain when Atlas cannot confirm that; not_current when every linked posting is no longer listed.
stalebooleanyestrue when the job was first listed more than 30 days ago: the earlier of job_first_seen_at and the source's posted date is over 30 days old. Updated daily. A label only; the job stays listed.
company_idCompanyId or nullyesThe Atlas company record. Null when the job's employer is not yet linked to a company record; employer_name then carries the name the source published.
employer_nameFieldStateStringyesThe employer name.
titleFieldStateStringyesThe job title.
descriptionFieldStateStringyesThe job description as plain text.
work_arrangementFieldStateWorkArrangementyesremote, hybrid or in_person, as the source states it.
locationsarray of FieldStateObjectyesEvery location of the job, combined from its linked postings. A known location value holds the address fields (street, city, region, postal_code, country); zip, the 5-digit US ZIP the posting states for that place when it states one that is real and in the stated state (the key is absent otherwise); and, when Atlas could place the location, county_fips (5-digit US county FIPS code, a string such as 48453) and msa (cbsa_code, cbsa_title and type, metro or micro, of the metropolitan or micropolitan statistical area; null when the location is in no statistical area).
job_first_seen_atstring (date-time)yesWhen Atlas first collected any posting of this job.
curated_atstring (date-time)yesWhen the job first entered the final dataset.
job_updated_atstring (date-time)yesWhen the job record last changed; sort=updated orders by this.
postingsarray of JobPostingyes

JobDetailResponse

FieldTypeRequiredDescription
dataJobyes

JobListResponse

FieldTypeRequiredDescription
dataarray of Jobyes
next_cursorstring or nullyes
snapshot_watermarkstring (date-time)yes

JobChange

FieldTypeRequiredDescription
event_idstringyes
job_idJobIdyes
typestring: "created", "updated", "expired"yes
occurred_atstring (date-time)yes
jobJobno

JobsChangesResponse

FieldTypeRequiredDescription
dataarray of JobChangeyes
resume_cursorstringyes
has_morebooleanyes
snapshot_watermarkstring (date-time)yes

JobCountResponse

FieldTypeRequiredDescription
countinteger; min 0yes
snapshot_watermarkstring (date-time)yes

Company

FieldTypeRequiredDescription
company_idCompanyIdyes
namestringyes
countrystring or nullyesISO 3166-1 alpha-2 code, or null when the registry country is unknown.
statusstring: "active", "retired", "merged"yes
regionstring or nullyesState or province code from the same government address as country, or null when unknown.
address_sourcestring or null: "sec", "dol_form5500", nullyesWhich government address gave country and region: sec (SEC business address) or dol_form5500 (Form 5500 plan sponsor address). Null when no government address is known.
identifiersarray of objectyesPublic registry identifiers, each from a US-government public source. Empty when none is known.
industriesarray of objectyesIndustry codes, each from a US-government public source. Empty when none is known.

CompanyPage

FieldTypeRequiredDescription
dataarray of Companyyes
next_cursorstring or nullyes

CompanySearchRequest

FieldTypeRequiredDescription
namestring; min length 1, max length 200noCase-insensitive canonical-name substring after trimming.
countrystringnoISO 3166-1 alpha-2 code, case-insensitive.
statusstring: "active", "retired", "merged"no
limitinteger; min 1, max 100, default 50no
cursorstring; min length 1, max length 2048no

ErrorEnvelope

FieldTypeRequiredDescription
errorobjectyes

UsageRequestRow

FieldTypeRequiredDescription
request_idstringyes
api_key_idstringyes
route_classstringyes
admitted_atstring (date-time)yes
finalized_atstring or nullyes
statestringyes
http_statusinteger or nullyes
request_chargedbooleanyes
records_returnedinteger; min 0yes
policy_idstring or nullyes
policy_versioninteger or nullyes
settlement_policy_idstring or nullyes
settlement_policy_versioninteger or nullyes

OverageStatus

FieldTypeRequiredDescription
overage_enabledbooleanyes
overage_monthly_limit_usdnumber or nullyesThe monthly overage limit in US dollars; null when the customer set none.
overage_limit_remaining_usdnumber or nullyesDollars of the limit not yet used this month; null when there is no limit.
overage_jobs_usedintegeryesJobs used this UTC month past the plan limit and the carried-over jobs.
overage_usdnumberyesThis month's overage so far at the plan's rate, rounded up to the cent.

UsageRequestsPage

FieldTypeRequiredDescription
dataarray of UsageRequestRowyes
next_cursorstring or nullyes
admissions_captured_atstring (date-time)yes

UsageDailyGroup

FieldTypeRequiredDescription
daystring (date)yes
groupstringyes
request_eventsintegeryes
charged_requestsintegeryes
pending_requestsintegeryes
rate_limited_requestsintegeryes
usage_limited_requestsintegeryes
http_status_2xxintegeryes
http_status_3xxintegeryes
http_status_4xxintegeryes
http_status_5xxintegeryes
error_ratenumber or null; min 0, max 1yesShare of admitted requests in this day and group that returned a 4xx or 5xx response, rounded to four decimal places; null when no requests were admitted.
returned_recordsintegeryes
job_records_returnedintegeryes
company_records_returnedintegeryes

UsageAnalytics

FieldTypeRequiredDescription
query_timestampstring (date-time)yes
time_basisobjectyes
group_bystring or null: "route_class", "status_class", "api_key_id", nullyes
dataarray of UsageDailyGroupyes

Continue in the reference

Check related request behavior before you build.

View route status and methods Discuss API requirements
All API documentation