Skip to content

Job Postings API

Job search and on-demand posting detail across LinkedIn, Ashby, Greenhouse, and Lever. Workflow is two-step: call search-jobs first, then pass the result’s id AND source_url to get-posting. Search is single-source only: source must name exactly one of linkedin, ashby, greenhouse, or lever; omitted defaults to linkedin. LinkedIn fetches live upstream data; Ashby, Greenhouse, and Lever search from service-refreshed local stores and detail serves the stored snapshot first with live fallback on cache miss.

Inspect every route, parameter, and response schema straight from your agent:

Terminal window
agent-data docs f9a6ec16-0bfd-44d8-b3ee-073776745ee7

Call any route below by its slug:

Terminal window
agent-data call f9a6ec16-0bfd-44d8-b3ee-073776745ee7 <route-slug> [--param value ...]
Route slugMethod & pathDescription
statusGET /v1/statusOpaque service-health probe for this listing. Returns &#123;"status": "ok"&#125; when the service is healthy and &#123;"status": "degraded"&#125; when recent fetches have been failing at a high r…
search-jobsPOST /v1/search-jobsSingle-source job search. Every request targets exactly one source: linkedin, ashby, greenhouse, lever. If source is omitted the API defaults to linkedin. This route never fan…
get-postingGET /v1/postings/{posting_id}Fetch one job posting detail. Requires BOTH posting_id AND the original source_url from a search-jobs result — they must be from the same row. If source is omitted, the AP…

GET /v1/status

Opaque service-health probe for this listing. Returns &#123;"status": "ok"&#125; when the service is healthy and &#123;"status": "degraded"&#125; when recent fetches have been failing at a high rate. Use this before invoking the data routes, but note that health is a single global in-process rolling window across all sources — not a per-source readiness signal. The response is intentionally opaque: it never exposes implementation details (proxies, impersonation, per-tier counts). A fresh Lambda is ok by default. This route does not consume the upstream fetch budget.

Terminal window
agent-data call f9a6ec16-0bfd-44d8-b3ee-073776745ee7 status

Full REST reference — parameters, schemas, and curl →

POST /v1/search-jobs

Single-source job search. Every request targets exactly one source: linkedin, ashby, greenhouse, lever. If source is omitted the API defaults to linkedin. This route never fans out across multiple sources. LinkedIn searches live upstream; Ashby, Greenhouse, and Lever search the service-refreshed local postings store. Returns up to limit summary rows matching the keywords (+ optional location) query. Each row carries an id (format jp_&lt;12-hex&gt;) AND a source_url — keep BOTH; you’ll need them as a pair when calling get-posting. Use fields=id,title,company_name (comma-separated) to request a subset of fields and reduce response size. Allowed fields: [‘capture_method’, ‘company_name’, ‘department_name’, ‘detail_available’, ‘employment_type’, ‘id’, ‘is_remote’, ‘location_display’, ‘missing_fields’, ‘posted_at’, ‘published_at’, ‘salary_display’, ‘search_status’, ‘source’, ‘source_id’, ‘source_url’, ‘staleness_status’, ‘team_name’, ‘title’, ‘workplace_type’]. Errors: 422 validation_error (param fails type/range validation; details[].loc identifies the field); 400 validation_error (fields= or source= violates the request contract); 503 upstream_unavailable (the chosen upstream source failed, retryable:true — caller decides backoff).

Terminal window
agent-data call f9a6ec16-0bfd-44d8-b3ee-073776745ee7 search-jobs --keywords <keywords> [--location New York] [--limit <limit>] [--fields <fields>] [--source <source>]
ParameterInTypeRequiredDescription
keywordsquerystringyesSearch query terms. Required.
locationquerystring | nullnoOptional location filter, e.g. New York. Accepts a city, state/region, or country (names, common aliases like NYC/SF, ISO codes like US/GBR, and native spellings like München all resolve via GeoNames). linkedin: forwa…
limitqueryinteger, min: 1, max: 100, default: 20noMaximum number of results to return (1-100).
fieldsquerystring | nullnoOptional comma-separated list of fields to include per row. Allowed: [‘capture_method’, ‘company_name’, ‘department_name’, ‘detail_available’, ‘employment_type’, ‘id’, ‘is_remote’, ‘location_display’, ‘missing_fields’,…
sourcequerystring | nullnoSingle source to search. Allowed: linkedin, ashby, greenhouse, lever. Omitted defaults to linkedin. Comma-separated or repeated values are rejected with 400 validation_error; this route never fans out across sources.

Full REST reference — parameters, schemas, and curl →

GET /v1/postings/{posting_id}

Fetch one job posting detail. Requires BOTH posting_id AND the original source_url from a search-jobs result — they must be from the same row. If source is omitted, the API infers the source from source_url for Ashby (*.ashbyhq.com), Greenhouse (*.greenhouse.io or ?gh_jid=), and Lever (jobs.lever.co). Otherwise it defaults to LinkedIn. Workday URLs (*.myworkdayjobs.com / *.myworkdaysite.com) are not currently supported and return 400 validation_error. Ashby, Greenhouse, and Lever detail serves the stored snapshot first with live fallback on cache miss; LinkedIn fetches live upstream detail. Response includes description_markdown (HTML-converted markdown), employment_type, and missing_fields[] listing any fields that couldn’t be extracted. application_url is intentionally not exposed (unreliable on LinkedIn guest pages). Use fields=id,title,description_markdown to request a subset. Allowed fields: [‘address_structured’, ‘apply_url’, ‘capture_method’, ‘company_name’, ‘compensation_structured’, ‘department_name’, ‘description_markdown’, ‘description_plain’, ‘employment_type’, ‘id’, ‘is_listed’, ‘is_remote’, ‘location_display’, ‘missing_fields’, ‘posted_at’, ‘published_at’, ‘salary_display’, ‘secondary_locations’, ‘source’, ‘source_id’, ‘source_url’, ‘staleness_status’, ‘team_name’, ‘title’, ‘workplace_type’]. Errors: 422 validation_error (missing or invalid source_url); 400 validation_error (posting_id/source_url mismatch or another request-contract error, not retryable); 503 upstream_unavailable (detail fetch failed, retryable:true).

Terminal window
agent-data call f9a6ec16-0bfd-44d8-b3ee-073776745ee7 get-posting --posting_id <posting_id> --source_url <source_url> [--source <source>] [--fields <fields>]
ParameterInTypeRequiredDescription
posting_idpathstringyesThe id returned by search-jobs for the row you want to enrich. Keep it paired with the row’s source_url.
source_urlquerystringyesThe exact source_url from the matching search-jobs result row. Must form a valid pair with posting_id (both come from the same row). Mismatched pair returns 400 validation_error.
sourcequerystring | nullnoOptional single-source override. Allowed: linkedin, ashby, greenhouse, lever. If omitted, the API infers from source_url for *.ashbyhq.com, *.greenhouse.io, ?gh_jid=, and jobs.lever.co; otherwise it defaults t…
fieldsquerystring | nullnoOptional comma-separated list of fields to include. Allowed: [‘address_structured’, ‘apply_url’, ‘capture_method’, ‘company_name’, ‘compensation_structured’, ‘department_name’, ‘description_markdown’, ‘description_plain…

Full REST reference — parameters, schemas, and curl →

Prefer plain HTTP? The Job Postings API REST reference documents every operation with full request/response schemas and ready-to-run curl and agent-data CLI examples.