Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: VeritaHire Free, no key API
version: 1.0.0
description: 'Live US job postings verified on each employer''s own careers site and retired within about 36 hours of leaving it. FREE, NO KEY: search live jobs, read a whole posting, check whether a posting is still open, the Competitive Hiring Report for a healthcare, finance, IT, engineering, science, HR, legal, marketing, sales, customer service, admin, operations and logistics, skilled trades, retail and food, or education role (competitors'' close times and pay). WITH A KEY (self-serve 2,000-record trial at https://veritahire.com/developers/): the full Verified Jobs Feed - every live posting, cursor-paged, plus per-employer hiring velocity and employer profiles. An MCP server with the free tools is at https://veritahire.com/mcp. Data source: public postings on employers'' own career sites.'
servers:
- url: https://veritahire.com
tags:
- name: Free, no key
paths:
/api/benchmark.php:
get:
operationId: benchmarkRole
summary: Competitive Hiring Report for one job posting
description: 'Free summary for the employer of one healthcare, finance, IT, engineering, science, HR, legal, marketing, sales, customer service, admin, operations and logistics, skilled trades, retail and food, or education posting: the market''s posted pay range (salary benchmarking) and how many employers are hiring it. The full report (first one free, via /api/benchmark-claim.php) names each competitor with its pay and how long its postings stay open (posting up to posting down), and shows where this posting sits, openings vs closings, and how hard the role is to fill there. Identify the posting by job_url, job_id, or employer + title. Status 202 means the benchmark is being built: call again after retry_after_seconds.'
parameters:
- name: job_url
in: query
required: false
schema:
type: string
description: The posting URL on the employer's careers site, or a veritahire.com/j/ URL
- name: job_id
in: query
required: false
schema:
type: integer
description: VeritaHire job id
- name: employer
in: query
required: false
schema:
type: string
description: Employer name
- name: title
in: query
required: false
schema:
type: string
description: Job title
- name: city
in: query
required: false
schema:
type: string
description: City
- name: state
in: query
required: false
schema:
type: string
description: Two-letter US state
responses:
'200':
description: Benchmark ready
'202':
description: Being built; retry
'404':
description: Posting not found
'422':
description: Not a healthcare, finance, IT, engineering, science, HR, legal, marketing, sales, customer service, admin, operations and logistics, skilled trades, retail and food, or education role
'429':
description: Rate limited
tags:
- Free, no key
/api/job-status.php:
get:
operationId: isJobStillOpen
summary: Is this job posting still open?
description: open, closed, or unknown, with when the posting was last confirmed on the employer's own careers site.
parameters:
- name: url
in: query
required: false
schema:
type: string
description: The posting URL
- name: job_id
in: query
required: false
schema:
type: integer
description: VeritaHire job id
responses:
'200':
description: Status
'429':
description: Rate limited
tags:
- Free, no key
/api/benchmark-claim.php:
post:
operationId: requestFullReport
summary: Email the full Competitive Hiring Report to a hiring manager
description: Emails one link to the address given. The recipient's click creates a free account and opens the full report; a caller cannot complete that step for them. Send only with the user's consent.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
properties:
email:
type: string
format: email
job_url:
type: string
job_id:
type: integer
employer:
type: string
title:
type: string
city:
type: string
state:
type: string
responses:
'202':
description: Email sent
'400':
description: Bad input
'429':
description: Rate limited
tags:
- Free, no key
/api/jobs-search.php:
get:
operationId: searchLiveJobs
summary: Find live jobs near a place
description: 'Up to 25 jobs live on employers'' own careers sites, each with posted pay, what the posting asks for (education, licences, years), distance, last confirmation, the employer''s industry and size, and the employer''s apply link. Title matches first, newest first; one requisition posted in several places comes back once with also_listed_in. Only the filters given are applied; jobs without posted pay are kept when min_pay is set, listed last. The response''s place says what where resolved to (city, state, nationwide, remote, or a text match). 25 a page (page / next_page). For a person''s daily feed, run the same search each day with posted_within_days=1 and title_exclude. Free: 30 searches an hour from one address; for more, the same search on GET /api/v1/jobs.php with an X-API-Key (no hourly cap) - a 429 carries that call ready to run.'
parameters:
- name: what
in: query
required: false
schema:
type: string
description: Job title, keywords or an employer name
- name: where
in: query
required: false
schema:
type: string
description: '"City, ST" or 5-digit ZIP (radius_miles applies); a state, e.g. Virginia or VA (the whole state plus remote jobs open anywhere in the US); or US for the whole country'
- name: radius_miles
in: query
required: false
schema:
type: integer
enum:
- 10
- 25
- 30
- 50
- 100
description: Miles
- name: min_pay
in: query
required: false
schema:
type: number
description: Annual, or hourly if under 300
- name: employment_type
in: query
required: false
schema:
type: string
enum:
- full_time
- part_time
- contract
- seasonal
- temporary
description: Type
- name: remote_only
in: query
required: false
schema:
type: integer
description: 1 for remote jobs only
- name: posted_within_days
in: query
required: false
schema:
type: integer
enum:
- 1
- 3
- 7
- 14
- 30
description: Days
- name: title_exclude
in: query
required: false
schema:
type: string
description: Comma-separated words; jobs whose title contains any of them are left out
- name: sort
in: query
required: false
schema:
type: string
enum:
- new
- pay
- near
description: 'Default: best match'
- name: page
in: query
required: false
schema:
type: integer
minimum: 1
description: 25 jobs a page; pass next_page from the previous response
responses:
'200':
description: Jobs
'400':
description: No what/where
'429':
description: 'Rate limited: 30 searches an hour from one address. The body carries retry_after_seconds (also the Retry-After header) and paid_api.same_search, this search ready to run on /api/v1/jobs.php with a key (free trial key for the first 2,000 jobs).'
tags:
- Free, no key
/api/job.php:
get:
operationId: getJob
summary: One job posting in full
description: 'The employer''s posting text, requirement facts, pay, any sign-on bonus the posting offers (sign_on_bonus: amount, up_to, the employer''s words), benefits, open/closed, apply link.'
parameters:
- name: job_id
in: query
required: false
schema:
type: integer
description: From searchLiveJobs
- name: url
in: query
required: false
schema:
type: string
description: Posting URL
responses:
'200':
description: Posting
'404':
description: Not found
'429':
description: Rate limited
tags:
- Free, no key
/api/jobs-save.php:
post:
operationId: saveSearch
summary: Email the person new jobs for a search, daily
description: Sends one email to the person's own address. Their click starts a daily email of new matching jobs (still live on employers' own careers sites) and creates their free account if needed; a caller cannot complete that step. Send only with the person's consent. Employer-account addresses are refused.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
properties:
email:
type: string
format: email
what:
type: string
where:
type: string
radius_miles:
type: integer
enum:
- 10
- 25
- 30
- 50
- 100
employment_type:
type: string
enum:
- full_time
- part_time
- contract
- seasonal
- temporary
remote_only:
type: boolean
responses:
'202':
description: Email sent
'400':
description: Bad input
'429':
description: Rate limited
tags:
- Free, no key
/api/hiring-signals.php:
get:
operationId: hiringSignals
summary: 'Hiring Signals, free view: roles not filling and roles reposted'
description: For recruiters and staffing firms. How many live roles have been open at least 3x longer than that same employer usually takes to close a role (stuck), and how many roles employers took down and put back up in the last 30 days (reposts), nationally or for one state and one industry, with named examples (stated pay, top of $60K or more). Read from employers' own careers sites, daily. The full row-level list is GET /api/v1/signals.php with an X-API-Key; the answer carries that call with the same filters.
parameters:
- name: state
in: query
required: false
schema:
type: string
description: Two-letter US state, a state name, or US (default)
- name: industry
in: query
required: false
schema:
type: string
description: healthcare_clinical, software, engineering_hardware, finance_accounting, sales, skilled_trade, operations, admin_support, customer_service, retail_food, education, marketing, legal, data_or_analytics, hr_recruiting, science_lab - or plain words
- name: min_pay
in: query
required: false
schema:
type: number
description: Only roles whose stated pay tops out at least this (annual, or hourly if under 300); roles with no stated pay are kept
responses:
'200':
description: Counts, examples and the full-list API call
'422':
description: Not a US state, or an unknown industry
'429':
description: Rate limited; retry_after_seconds in the body and the Retry-After header
tags:
- Free, no key
/api/job-openings-index.php:
get:
operationId: jobOpeningsIndex
summary: 'The Job Openings Index: open US job postings, daily'
description: 'Open US job postings measured every day from employers'' own careers sites and published the next morning: the index (base 2026-09-04 = 100), its 7-day average, its change over a day, a week and 28 days, the share of postings put up and taken down in the last week, the latest JOLTS month for comparison, and the daily series. CC BY 4.0.'
parameters:
- name: days
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 120
description: Days of the series to return (default 30)
responses:
'200':
description: The index
'503':
description: The file is being republished; retry_after_seconds
tags:
- Free, no key
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: 'Your vh_... key. Free trial (2,000 credits; 1 credit = 1 job returned), then $3.95 per 1,000: https://veritahire.com/verified-jobs-feed/'