API reference
Every endpoint, every filter.
Base URL https://praxyjobs.com/v1. The machine-readable version of this page is the OpenAPI spec, served unchanged by the running API and checked against its routes in CI.
Conventions
- Access is explicit. The ten-job preview and stats are public evaluation surfaces. Production endpoints require an active subscription-backed API key.
- 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/previewKeyless product-evaluation sample capped at ten open jobs. It has no cursor and omits production-only descriptions, lifecycle feeds, and company exports.
| param | type | notes |
|---|---|---|
| ai_work_arrangement | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| city | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| country | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| employment_type | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| posted_since | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| q | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| source | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/jobs/searchHybrid keyword search over the corpus. All filters combine with AND.
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" \
-H "X-API-Key: $PRAXY_JOBS_KEY"| param | type | notes |
|---|---|---|
| ai_work_arrangement | enum | remote · hybrid · on_site · unknown (LLM-derived work arrangement). |
| city | string | City name match over derived locations. |
| company | string | Company / organization name match. |
| company_domain | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| country | csv | ISO 3166-1 alpha-2 codes, comma-separated (e.g. US,DE,IN). |
| cursor | string | Opaque keyset cursor from next_cursor. No offset paging. |
| employment_type | csv | FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER, PER_DIEM, OTHER. |
| exclude_duplicates | boolean | Collapse cross-location duplicates to one representative per group (default false). |
| experience_level | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| 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. |
| has_salary | boolean | true returns only jobs with salary data. |
| include_description | boolean | Returns full description_text — requires an active subscription-backed X-API-Key. |
| include_unresolved | boolean | Include jobs from companies whose display identity is still unresolved (opaque tenant IDs). Hidden by default so default surfaces stay clean. |
| language | string | Posting language, ISO 639-1 (e.g. en, de). |
| limit | int | 1–1000, default 100. |
| posted_before | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| posted_since | date-time | ISO-8601 timestamp with a UTC offset; filters on posting/first-seen recency. |
| q | string | Free-text search over title, company, and description. |
| remote | enum | only · exclude. |
| salary_currency | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| salary_max_lte | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| salary_min_gte | number | Minimum salary floor (≥ 0). |
| salary_period | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| 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. |
| skill_cluster | csv | Skill-cluster tags, comma-separated. |
| source | csv | One or more of the 53 canonical source codes, comma-separated — see /sources. |
| status | enum | open (default) · closed · all. |
| title | string | Title filter with a boolean grammar — see below. Case-insensitive substring terms. |
| 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. |
/v1/jobs/searchTyped JSON search for boolean keyword trees, facets, or an opt-in semantic query for current Growth and Scale accounts. Semantic mode searches open jobs, caps results at 100, and does not accept facets or cursor pagination. Keyword cursors remain bound to the original request and fail closed on filter drift.
/v1/jobs/exportSubscription-backed bulk export in CSV, NDJSON, or Parquet. CSV and NDJSON use bounded numbered parts; Parquet is returned as one spooled artifact. Description columns require a plan that explicitly includes them.
| param | type | notes |
|---|---|---|
| columns | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| country | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| exclude_duplicates | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| format | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| part | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| posted_since | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| source | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| status | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/jobs/{job_key}One job by stable key for an active subscription-backed X-API-Key. The payload includes full description_text. Supports include_unresolved.
| param | type | notes |
|---|---|---|
| include_unresolved | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/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.
| param | type | notes |
|---|---|---|
| country | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| cursor | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| export | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| include_unresolved | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| min_open_jobs | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| source | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/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.
| param | type | notes |
|---|---|---|
| include_unresolved | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/companies/{company_key}/jobsAll jobs at one company. status open (default) · closed · all, plus limit/cursor.
| param | type | notes |
|---|---|---|
| cursor | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| include_unresolved | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| status | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/statsPublic corpus statistics: totals, per-source and per-country counts, career-family coverage, enrichment coverage, freshness percentiles, and optional per-source description, posting-date, and salary fill rates with refresh cadence and last-sweep time. The same measured values our own pages render — unavailable fields stay unavailable rather than being inferred from global totals.
/v1/analytics/companies/{company_key}/posting-velocityPaid, measured comparison of a company's first-observed openings across equal current and prior windows. The response includes the underlying weekly series and evidence boundary; it is a source-observation count, not a demand forecast.
| param | type | notes |
|---|---|---|
| window_days | int | 1–365 days, default 30. The prior comparison window has the same length. |
/v1/analytics/time-to-fillPaid posting-duration proxy from first observation to definitive source closure, filterable by source, country, career family, or company. It does not claim a confirmed hire, and sparse samples return an explicit insufficient-data result instead of a guessed estimate.
| param | type | notes |
|---|---|---|
| company_key | string | One stable company key. |
| country | enum | One ISO 3166-1 alpha-2 country code. |
| family | enum | One canonical career-family code. |
| source | enum | One canonical ATS source code. |
| window_days | int | 1–365 days, default 90. |
/v1/analytics/state-of-hiringPublic quarterly report of first-observed posting volume and audited duration signals by ATS, country, and career family. Current quarters are labelled partial and never projected forward.
| param | type | notes |
|---|---|---|
| quarter | string | UTC calendar quarter as YYYY-Q1 through YYYY-Q4. Omit for the latest completed quarter. |
/v1/data-quality/currentThe latest retained, measured data-quality artifact. It is served only when a complete worker-produced report is available; missing computation is never replaced with inferred quality 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.
| param | type | notes |
|---|---|---|
| country | csv | ISO 3166-1 alpha-2 codes. |
| cursor | string | Opaque keyset cursor from next_cursor. |
| description_format | enum | none (default) · text — text returns full descriptions in the feed. |
| domain | csv | Company domains. |
| exclude_duplicates | boolean | Collapse cross-location duplicates to one representative per group. |
| exclude_source | csv | Exclude canonical ATS source codes. |
| first_seen_gte | date-time | Fixed lower boundary; pairs with cursors for exactly-once consumption. |
| limit | int | 1–1000, default 100. |
| organization | csv | Company names. |
| source | csv | Include canonical ATS source codes. |
| time_frame | enum | 1h · 6h · 24h (default) · 7d · 31d. |
| title | string | Same boolean grammar as search. |
/v1/feed/active/countA credit-free count for the active-feed filters. Use it to size a pull before requesting job records.
| param | type | notes |
|---|---|---|
| country | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| domain | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| exclude_duplicates | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| exclude_source | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| first_seen_gte | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| organization | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| source | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| time_frame | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| title | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/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.
| param | type | notes |
|---|---|---|
| cursor | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| time_frame | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/feed/modifiedField-level changes in the window — which fields changed, plus the updated job. Params: time_frame, limit, cursor.
| param | type | notes |
|---|---|---|
| cursor | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| time_frame | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/feed/changesDurable, sequence-ordered upsert and tombstone events. Persist next_seq only after processing the page, then pass it back as since_seq to resume after an arbitrarily long consumer gap.
| param | type | notes |
|---|---|---|
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| since_seq | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/datasetsScale-only index of verified, immutable active-corpus snapshots. Dataset access is a flat plan entitlement and does not consume per-job API credits.
/v1/datasets/{snapshot_date}One dated snapshot manifest with short-lived signed Parquet part URLs, columns, row counts, and a single explicit expiry time.
/v1/destinationsList the authenticated Scale account's outbound Postgres and webhook destinations. Secret connection settings are never returned.
/v1/destinationsCreate a disabled outbound destination. Enabling is a separate explicit operation, and each account has a bounded destination count.
/v1/destinations/{destination_id}Read one redacted destination configuration and its delivery state.
/v1/destinations/{destination_id}Update destination metadata or replace its stored secret configuration. Mutations fail with a retryable conflict while delivery is in progress.
/v1/destinations/{destination_id}Soft-delete an idle destination. A successful deletion returns no body.
/v1/destinations/{destination_id}/enableEnable delivery and clear the destination's consecutive-failure count.
/v1/destinations/{destination_id}/disablePause future delivery without deleting destination metadata or run history.
/v1/destinations/{destination_id}/runsRecent delivery runs with bounded, redacted reports and explicit source and destination acknowledgement counts.
| param | type | notes |
|---|---|---|
| limit | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/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/billing/webhookSigned billing-provider callback used to activate and update subscriptions. Duplicate event IDs are idempotent; unsigned payloads are rejected.
/v1/billing/claimExchange the single-use checkout claim token for an activated API key after the subscription webhook completes. Responses are never cached.
/v1/billing/portalCreate a hosted billing-portal session for the authenticated paid account.
/v1/keysCompatibility-only credential issuance retained for older clients. Body: {"email": "…"}. While paid enforcement is active, this credential does not unlock production REST endpoints; evaluate with /v1/jobs/preview and /v1/stats, then subscribe for production access.
/v1/account/usageCurrent plan, billing-period allowance, aggregate consumption, daily usage, and recent authenticated activity for the paid account behind the key.
/v1/account/keysList non-secret metadata for every key in the current paid account, including labels, four-character hints, status, and last use. Raw key material is never returned by this endpoint.
/v1/account/keysCreate another account key with an optional label. The raw key is returned exactly once and shares the subscription's allowance with sibling keys.
/v1/account/keys/rotateStage a replacement key without revoking the current one. Test the replacement, then revoke the old key explicitly.
/v1/account/keys/{key_id}Revoke an account-owned key. The last active key cannot be revoked, preventing accidental account lockout.
/v1/usage/dailyPer-day request and returned-job usage for your own account over up to 90 days. Requires an approved service key. Params: date_from, date_to.
| param | type | notes |
|---|---|---|
| date_from | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
| date_to | query | See the machine-readable OpenAPI contract for bounds and allowed values. |
/v1/sitemapsDeterministic sitemap feed: 256 job-key segments with counts and last-modified stamps. This is what builds our own sitemap.
/v1/sitemaps/{segment_id}Active deduplicated job keys and honest last-modified timestamps for one deterministic sitemap segment.