API reference
Every endpoint, every filter.
Base URL https://praxyjobs.com/v1. The machine-readable version of this page is the OpenAPI spec, generated from the running API.
Conventions
- Unknown means omitted. Fields the source didn't publish are dropped from the payload, never nulled-in or guessed. (Structured locations are the one exception: their keys are always present and honestly nullable.)
- Every job carries its receipt:
source,source_slug,source_endpoint, anddirectory_verified_at. - Cursor pagination. Pass
next_cursorback ascursor; it's absent on the last page. - Errors are problem+json (RFC 9457) with a 4xx/5xx status; 429s include Retry-After.
- Successful responses carry
X-RateLimit-*headers andX-Praxy-Schema-Version.
/v1/jobs/searchHybrid keyword search over the corpus. All filters combine with AND.
| param | type | notes |
|---|---|---|
| q | string | Free-text search over title, company, and description. |
| title | string | Title filter with a boolean grammar — see below. Case-insensitive substring terms. |
| family | csv | Career-family codes, comma-separated: engineering, data_ai_analytics, product_strategy, design_research, go_to_market, business_operations, finance_risk, people_talent, legal_policy, administration, general_professional, unknown. |
| skill_cluster | csv | Skill-cluster tags, comma-separated. |
| country | csv | ISO 3166-1 alpha-2 codes, comma-separated (e.g. US,DE,IN). |
| city | string | City name match over derived locations. |
| source | csv | ATS source codes, comma-separated — the 38 codes listed on /sources (e.g. greenhouse,lever,workday). |
| posted_since | date-time | ISO-8601 timestamp with a UTC offset; filters on posting/first-seen recency. |
| has_salary | boolean | true returns only jobs with salary data. |
| salary_min_gte | number | Minimum salary floor (≥ 0). |
| employment_type | csv | FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER, PER_DIEM, OTHER. |
| ai_work_arrangement | enum | remote · hybrid · on_site · unknown (LLM-derived work arrangement). |
| language | string | Posting language, ISO 639-1 (e.g. en, de). |
| company | string | Company / organization name match. |
| remote | enum | only · exclude. |
| status | enum | open (default) · closed · all. |
| visa_sponsorship | boolean | Tri-state, derived only from explicit statements in the posting: true matches jobs that explicitly offer sponsorship, false matches jobs that explicitly rule it out. Postings that say nothing stay unknown and match neither — silence is never coerced into an answer. |
| security_clearance | boolean | true matches jobs whose posting explicitly requires a security clearance. false means “not known to require a clearance” — it includes postings that don't mention one. |
| exclude_duplicates | boolean | Collapse cross-location duplicates to one representative per group (default false). |
| include_description | boolean | Returns full description_text — requires a valid X-API-Key. Without a key you still get description_snippet. |
| include_unresolved | boolean | Include jobs from companies whose display identity is still unresolved (opaque tenant IDs). Hidden by default so default surfaces stay clean. |
| limit | int | 1–1000, default 100. |
| cursor | string | Opaque keyset cursor from next_cursor. No offset paging. |
The title grammar
title accepts an OR of AND groups with negation — precedence ! then & then |, no parentheses. Each term is a case-insensitive substring.
# senior or staff, engineer, not manager
title=senior & engineer & !manager | staff & engineer & !manager
# URL-encoded in practice:
curl "https://praxyjobs.com/v1/jobs/search?title=senior%20%26%20engineer%20%26%20!manager&limit=5"/v1/jobs/{job_key}One job by stable key. With a valid X-API-Key the payload includes full description_text; anonymous callers get the snippet. Supports include_unresolved.
/v1/companiesThe verified company directory. Filters: source, country, min_open_jobs, plus limit/cursor. With export=jsonl (key required) it streams the full catalog as newline-delimited JSON instead of paging.
/v1/companies/{company_key}Company profile: validated boards (platforms), hiring velocity, office network, department rollups, work-mode distribution, and open positions — every derived field labeled with its source and confidence.
/v1/companies/{company_key}/jobsAll jobs at one company. status open (default) · closed · all, plus limit/cursor.
/v1/statsPublic corpus statistics: totals, per-source and per-country counts, career-family coverage, enrichment coverage, freshness percentiles. The same numbers our own pages render — live counts, not claims.
/v1/feed/activeNewly indexed jobs by time window, oldest-first with keyset cursors — poll at window cadence and you never see the same job twice. /v1/feed/active/count returns just the count for the same filters.
| param | type | notes |
|---|---|---|
| time_frame | enum | 1h · 6h · 24h (default) · 7d · 31d. |
| source / exclude_source | csv | Include or exclude ATS source codes. |
| country | csv | ISO 3166-1 alpha-2 codes. |
| organization | csv | Company names. |
| domain | csv | Company domains. |
| title | string | Same boolean grammar as search. |
| description_format | enum | none (default) · text — text returns full descriptions in the feed. |
| first_seen_gte | date-time | Fixed lower boundary; pairs with cursors for exactly-once consumption. |
| exclude_duplicates | boolean | Collapse cross-location duplicates to one representative per group. |
| limit / cursor | — | 1–1000 + keyset cursor, as everywhere. |
/v1/feed/expiredJobs that closed in the window, with closed_at and a close reason (removed_from_board · board_dead · expired_by_source). Params: time_frame, limit, cursor.
/v1/feed/modifiedField-level changes in the window — which fields changed, plus the updated job. Params: time_frame, limit, cursor.
/v1/billing/checkoutCreate a hosted subscription checkout. Body: {"email": "…", "plan": "growth", "return_url": "https://praxyjobs.com/checkout/return"}. Returns a Dodo-hosted checkout URL. Access stays pending until the signed subscription webhook has activated the account.
/v1/usage/dailyPer-day request and returned-job usage for your own account over up to 90 days. Requires an active subscription-backed key. Params: date_from, date_to.
/v1/sitemapsDeterministic sitemap feed: 256 job-key segments with counts and last-modified stamps; /v1/sitemaps/{segment_id} lists each segment's jobs. This is what builds our own sitemap.