{"openapi":"3.1.0","info":{"title":"Puesto Jobs API","description":"Public REST API for searching and retrieving job listings. Authenticate with a secret API key (`sk_...`) sent as a bearer token.","version":"1.0.0"},"servers":[{"url":"/"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Provide your secret API key (prefixed `sk_`) as a bearer token: `Authorization: Bearer sk_...`."}},"schemas":{"JsonValue":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"$ref":"#/components/schemas/JsonValue"}},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/JsonValue"}}]}}},"security":[{"bearerAuth":[]}],"tags":[{"name":"Jobs","description":"Search and retrieve job listings."},{"name":"Changes","description":"Poll the append-only job change feed."},{"name":"Meta","description":"Controlled vocabulary values for filter parameters."},{"name":"Locations","description":"Country and state lookup values for location filters."}],"paths":{"/api/v1/openapi.json":{"get":{"operationId":"getApiV1OpenapiJson","tags":["Meta"],"summary":"Get the OpenAPI specification","description":"Returns the public OpenAPI 3.1 document describing every endpoint, as JSON. Use it to generate typed clients, import the API into explorers like Postman or Bruno, or point AI agents and tooling at the API. Publicly accessible — no API key required.","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/jobs":{"get":{"operationId":"getApiV1Jobs","tags":["Jobs"],"summary":"Search jobs","description":"Search the public job catalog with cursor-based pagination. Returns a page of job summaries and a `next_cursor` for the following page. Add `q` for full-text search (Google-style: quoted `\"phrases\"`, `OR`, `-exclusion`; a pure-exclusion query is rejected). Implicit AND binds tighter than `OR` and a `-term` attaches only to its adjacent group, so `\"machine learning\" OR \"data scientist\" -senior` means `A OR (B AND NOT senior)` and can still return Senior ML titles; to exclude everywhere, distribute the term: `\"machine learning\" -senior OR \"data scientist\" -senior`. By default `q` matches the job title only (precise — best for common role terms like `developer`/`engineer`, which otherwise match description boilerplate); pass `q_scope=full` to also search the description (broader reach — best for niche skills or tools named only in the requirements text). A phrase query under `q_scope=full` combined with very narrow filters (a small country, a rare language) can hit the search timeout; the default title scope is immune, so prefer it for phrase precision. `q` composes as a filter with the standard sorts: `sort=posted_at` (default) and `sort=first_seen_at` are descending keyset sorts with unbounded cursor pagination, applying `q` as a filter over the newest-first keyset. Symbol-bearing tech tokens (`c++`, `c#`, `.net`) are matched as a title substring rather than full-text (they collapse under English tokenization); a mixed query such as `python c++` still runs as full-text. If a full-text search matches nothing, one title-substring fallback runs automatically and the response is flagged `fuzzy: true`. `q` respects the default 90-day freshness window unless a date filter is supplied. A well-formed but overly broad `q` that exceeds the search time budget returns 422 (narrow the query); a malformed `q` (too complex, or only exclusions) returns 400.","parameters":[{"name":"title","in":"query","required":false,"description":"Case-insensitive substring match on the job title (3-200 characters).","schema":{"type":"string","minLength":3,"maxLength":200}},{"name":"q","in":"query","required":false,"description":"Full-text search across the job. Google-style syntax: quoted `\"exact phrase\"`, `OR`, and `-term` exclusion (a query that is ONLY exclusions is rejected with 400). Operator precedence: implicit AND binds tighter than `OR`, and a `-term` attaches only to its adjacent group — so `\"machine learning\" OR \"data scientist\" -senior` parses as `A OR (B AND NOT senior)` and CAN still return Senior ML titles. To exclude a term everywhere, distribute it across each branch: `\"machine learning\" -senior OR \"data scientist\" -senior`. By default `q` matches the job TITLE only (precise — best for common role terms); pass `q_scope=full` to also search the description. Phrase queries under `q_scope=full` combined with very narrow filters (a small country, a rare language) can hit the search timeout; the default title scope is immune, so prefer it for phrase precision. `q` composes as a filter with the standard `sort`/`cursor` pagination (newest-first over the matches) and respects the default 90-day freshness window unless a date filter is given. Symbol-bearing tech tokens (`c++`, `c#`, `.net`) are matched as a title substring instead of full-text (they collapse under English tokenization). If a full-text search yields no rows a single title-substring fallback runs and its results are flagged `fuzzy: true`.","schema":{"type":"string","minLength":2,"maxLength":200}},{"name":"q_scope","in":"query","required":false,"description":"Which fields `q` searches. `title` (default) matches the job title only — precise, best for common role terms (e.g. `developer`, `engineer`), which otherwise match description boilerplate. `full` also searches the description — broader reach, best for niche skills or tools that appear only in the requirements text (a language or framework not named in the title). Only affects results when `q` is set (ignored otherwise).","schema":{"default":"title","type":"string","enum":["title","full"]}},{"name":"country","in":"query","required":false,"description":"Filter by ISO 3166-1 alpha-2 country code(s). Repeat the parameter or comma-separate values (e.g. `country=us,de`). A job matches if it is tagged with any of the given countries. Up to 20 values; case-insensitive.","style":"form","explode":true,"schema":{"maxItems":20,"type":"array","items":{"type":"string","minLength":2,"maxLength":2}}},{"name":"state","in":"query","required":false,"description":"Filter by state / region reference code(s). Repeat the parameter or comma-separate values (e.g. `state=CA,NY`). A job matches if it is tagged with any of the given regions. Up to 20 values; case-insensitive.","style":"form","explode":true,"schema":{"maxItems":20,"type":"array","items":{"type":"string"}}},{"name":"city","in":"query","required":false,"description":"Case-insensitive substring match on the city name.","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"workplace","in":"query","required":false,"description":"Filter by workplace arrangement.","schema":{"type":"string","enum":["remote","hybrid","onsite"]}},{"name":"employment_type","in":"query","required":false,"description":"Filter by employment type.","schema":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]}},{"name":"level","in":"query","required":false,"description":"Filter by seniority level.","schema":{"type":"string","enum":["intern","entry","mid","senior","staff","lead","executive"]}},{"name":"language","in":"query","required":false,"description":"Filter by ISO 639-1 language code (2 letters, case-insensitive).","schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"salary_min","in":"query","required":false,"description":"Keep jobs whose stated salary range reaches at least this amount. Jobs that state only a minimum (no maximum) match when that minimum is at least this value.","schema":{"type":"number","minimum":0}},{"name":"salary_max","in":"query","required":false,"description":"Keep jobs whose stated salary range starts at or below this amount.","schema":{"type":"number","minimum":0}},{"name":"salary_currency","in":"query","required":false,"description":"Filter by ISO 4217 currency code (3 letters, case-insensitive).","schema":{"type":"string","minLength":3,"maxLength":3}},{"name":"has_salary","in":"query","required":false,"description":"When `true`, return only jobs that specify a salary; when `false`, only jobs without a salary.","schema":{"type":"boolean"}},{"name":"company_id","in":"query","required":false,"description":"Filter by the numeric company id.","schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"description":"Filter by listing status. `open` (default) returns active listings; `closed` returns delisted ones.","schema":{"default":"open","type":"string","enum":["open","closed"]}},{"name":"posted_since","in":"query","required":false,"description":"Only jobs posted at or after this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`). When none of `posted_since`, `posted_until`, or `first_seen_since` are provided and `status` is `open`, results default to the last 90 days.","schema":{"type":"string","format":"date-time"}},{"name":"posted_until","in":"query","required":false,"description":"Only jobs posted at or before this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`).","schema":{"type":"string","format":"date-time"}},{"name":"first_seen_since","in":"query","required":false,"description":"Only jobs first seen at or after this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`).","schema":{"type":"string","format":"date-time"}},{"name":"sort","in":"query","required":false,"description":"Sort field for the descending keyset pagination. Defaults to `posted_at`. A full-text `q` composes with either sort as a filter.","schema":{"default":"posted_at","type":"string","enum":["posted_at","first_seen_at"]}},{"name":"limit","in":"query","required":false,"description":"Maximum number of jobs to return. Defaults to 100; values above 500 are clamped to 500.","schema":{"default":100,"type":"integer","exclusiveMinimum":0}},{"name":"cursor","in":"query","required":false,"description":"Opaque pagination cursor taken from a previous response `next_cursor`. Must be used with the same `sort` value that produced it.","schema":{"type":"string"}},{"name":"description","in":"query","required":false,"description":"Include the job description in each result: `off` (default, omitted), `text` (markdown as `description_md`), or `html` (`description_html`).","schema":{"default":"off","type":"string","enum":["off","text","html"]}}],"responses":{"200":{"description":"A page of matching jobs.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","description":"Numeric job id."},"source_id":{"type":"integer","description":"Numeric source id."},"company_id":{"type":"integer","description":"Numeric company id."},"external_job_id":{"type":"string","description":"The job id assigned by the job's original source."},"url":{"type":"string","description":"Canonical URL of the job listing."},"apply_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Direct apply URL, or null."},"title":{"type":"string","description":"Job title."},"location_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Raw location string from the source, or null."},"locations_raw":{"$ref":"#/components/schemas/JsonValue"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Human-readable location display string in the posting's original order; may lead with a region label while `country_code` reflects the primary country; or null."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"City, or null."},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Region / state, or null."},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Postal code, or null."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country code, or null."},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Latitude, or null."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Longitude, or null."},"usa":{"type":"boolean","description":"Whether the job is located in the United States."},"country_codes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country codes the job is tagged with, or null."},"admin1_refs":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"First-level administrative division refs, or null."},"workplace":{"anyOf":[{"type":"string","enum":["remote","hybrid","onsite"]},{"type":"null"}],"description":"Workplace arrangement (remote / hybrid / onsite), or null."},"employment_type":{"anyOf":[{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},{"type":"null"}],"description":"Employment type, or null."},"level":{"anyOf":[{"type":"string","enum":["intern","entry","mid","senior","staff","lead","executive"]},{"type":"null"}],"description":"Seniority level, or null."},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 639-1 language code, or null."},"salary_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Raw salary string from the source, or null."},"salary_min":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum of the stated salary range, or null."},"salary_max":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum of the stated salary range, or null."},"salary_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 4217 salary currency code, or null."},"salary_period":{"anyOf":[{"type":"string","enum":["year","month","week","day","hour"]},{"type":"null"}],"description":"Salary period (e.g. year, hour), or null."},"posted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job was posted as an ISO-8601 date-time string, or null."},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job expires as an ISO-8601 date-time string, or null."},"content_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Content hash used for change detection, or null."},"first_seen_at":{"type":"string","description":"When the job was first seen as an ISO-8601 date-time string."},"closed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job was delisted (null for open jobs) as an ISO-8601 date-time string, or null."},"created_at":{"type":"string","description":"When the job record was created as an ISO-8601 date-time string."},"updated_at":{"type":"string","description":"When the job record was last updated as an ISO-8601 date-time string."},"description_md":{"description":"Markdown job description. Present only when `description=text`.","anyOf":[{"type":"string"},{"type":"null"}]},"description_html":{"description":"HTML job description. Present only when `description=html`.","anyOf":[{"type":"string"},{"type":"null"}]},"company":{"anyOf":[{"type":"object","properties":{"id":{"type":"integer","description":"Numeric company id."},"name":{"type":"string","description":"Company display name."},"website_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company website URL, or null."},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company logo URL, or null."}},"required":["id","name","website_url","logo_url"],"description":"Condensed company summary attached to each job."},{"type":"null"}],"description":"Company summary, or null when unknown."}},"required":["id","source_id","company_id","external_job_id","url","apply_url","title","location_raw","locations_raw","location","city","region","postal_code","country_code","latitude","longitude","usa","country_codes","admin1_refs","workplace","employment_type","level","language","salary_raw","salary_min","salary_max","salary_currency","salary_period","posted_at","expires_at","content_hash","first_seen_at","closed_at","created_at","updated_at","company"],"description":"A job listing as returned by the list endpoint."},"description":"The page of matching jobs."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Cursor for the next page, or null when there are no more results. Pass it as `cursor` on the next request with the same `sort`."},"limit":{"type":"integer","description":"The effective page size applied to this response."},"fuzzy":{"description":"Present and `true` only when the full-text query matched no jobs and these results come from the title-substring fallback lane. Absent otherwise.","type":"boolean"}},"required":["data","next_cursor","limit"],"description":"A cursor-paginated page of job listings."}}}},"400":{"description":"Invalid query parameters, pagination cursor, or `q` search query.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"422":{"description":"The `q` search query is well-formed but too broad and exceeded the search time budget — narrow it.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}},"/api/v1/jobs/count":{"get":{"operationId":"getApiV1JobsCount","tags":["Jobs"],"summary":"Count jobs","description":"Count the jobs matching a filter set. Accepts the same filters as Search jobs (pagination, sorting, and description knobs are ignored) and returns only the total. The default 90-day freshness window applies identically to the count. A single-country count uses the job's primary country and can be slightly lower than the number of results Search jobs returns for the same filter (jobs listing that country as a secondary location are excluded); multi-country filters count by any-listed-country, matching search exactly. Supplying `q` counts full-text matches with the same syntax, scope tiers, symbol-token handling, and guardrails as Search jobs (a broad `q` may return 422; a malformed `q`, 400). A `q` count uses any-listed-country semantics, so with a single-country filter it counts by any-listed-country (matching search), not the primary-country fast path used without `q`.","parameters":[{"name":"title","in":"query","required":false,"description":"Case-insensitive substring match on the job title (3-200 characters).","schema":{"type":"string","minLength":3,"maxLength":200}},{"name":"q","in":"query","required":false,"description":"Full-text search across the job. Google-style syntax: quoted `\"exact phrase\"`, `OR`, and `-term` exclusion (a query that is ONLY exclusions is rejected with 400). Operator precedence: implicit AND binds tighter than `OR`, and a `-term` attaches only to its adjacent group — so `\"machine learning\" OR \"data scientist\" -senior` parses as `A OR (B AND NOT senior)` and CAN still return Senior ML titles. To exclude a term everywhere, distribute it across each branch: `\"machine learning\" -senior OR \"data scientist\" -senior`. By default `q` matches the job TITLE only (precise — best for common role terms); pass `q_scope=full` to also search the description. Phrase queries under `q_scope=full` combined with very narrow filters (a small country, a rare language) can hit the search timeout; the default title scope is immune, so prefer it for phrase precision. `q` composes as a filter with the standard `sort`/`cursor` pagination (newest-first over the matches) and respects the default 90-day freshness window unless a date filter is given. Symbol-bearing tech tokens (`c++`, `c#`, `.net`) are matched as a title substring instead of full-text (they collapse under English tokenization). If a full-text search yields no rows a single title-substring fallback runs and its results are flagged `fuzzy: true`.","schema":{"type":"string","minLength":2,"maxLength":200}},{"name":"q_scope","in":"query","required":false,"description":"Which fields `q` searches. `title` (default) matches the job title only — precise, best for common role terms (e.g. `developer`, `engineer`), which otherwise match description boilerplate. `full` also searches the description — broader reach, best for niche skills or tools that appear only in the requirements text (a language or framework not named in the title). Only affects results when `q` is set (ignored otherwise).","schema":{"default":"title","type":"string","enum":["title","full"]}},{"name":"country","in":"query","required":false,"description":"Filter by ISO 3166-1 alpha-2 country code(s). Repeat the parameter or comma-separate values (e.g. `country=us,de`). A job matches if it is tagged with any of the given countries. Up to 20 values; case-insensitive.","style":"form","explode":true,"schema":{"maxItems":20,"type":"array","items":{"type":"string","minLength":2,"maxLength":2}}},{"name":"state","in":"query","required":false,"description":"Filter by state / region reference code(s). Repeat the parameter or comma-separate values (e.g. `state=CA,NY`). A job matches if it is tagged with any of the given regions. Up to 20 values; case-insensitive.","style":"form","explode":true,"schema":{"maxItems":20,"type":"array","items":{"type":"string"}}},{"name":"city","in":"query","required":false,"description":"Case-insensitive substring match on the city name.","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"workplace","in":"query","required":false,"description":"Filter by workplace arrangement.","schema":{"type":"string","enum":["remote","hybrid","onsite"]}},{"name":"employment_type","in":"query","required":false,"description":"Filter by employment type.","schema":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]}},{"name":"level","in":"query","required":false,"description":"Filter by seniority level.","schema":{"type":"string","enum":["intern","entry","mid","senior","staff","lead","executive"]}},{"name":"language","in":"query","required":false,"description":"Filter by ISO 639-1 language code (2 letters, case-insensitive).","schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"salary_min","in":"query","required":false,"description":"Keep jobs whose stated salary range reaches at least this amount. Jobs that state only a minimum (no maximum) match when that minimum is at least this value.","schema":{"type":"number","minimum":0}},{"name":"salary_max","in":"query","required":false,"description":"Keep jobs whose stated salary range starts at or below this amount.","schema":{"type":"number","minimum":0}},{"name":"salary_currency","in":"query","required":false,"description":"Filter by ISO 4217 currency code (3 letters, case-insensitive).","schema":{"type":"string","minLength":3,"maxLength":3}},{"name":"has_salary","in":"query","required":false,"description":"When `true`, return only jobs that specify a salary; when `false`, only jobs without a salary.","schema":{"type":"boolean"}},{"name":"company_id","in":"query","required":false,"description":"Filter by the numeric company id.","schema":{"type":"integer"}},{"name":"status","in":"query","required":false,"description":"Filter by listing status. `open` (default) returns active listings; `closed` returns delisted ones.","schema":{"default":"open","type":"string","enum":["open","closed"]}},{"name":"posted_since","in":"query","required":false,"description":"Only jobs posted at or after this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`). When none of `posted_since`, `posted_until`, or `first_seen_since` are provided and `status` is `open`, results default to the last 90 days.","schema":{"type":"string","format":"date-time"}},{"name":"posted_until","in":"query","required":false,"description":"Only jobs posted at or before this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`).","schema":{"type":"string","format":"date-time"}},{"name":"first_seen_since","in":"query","required":false,"description":"Only jobs first seen at or after this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`).","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"The total number of matching jobs.","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","description":"Total number of jobs matching the supplied filters."}},"required":["count"],"description":"The total count of jobs matching a filter set."}}}},"400":{"description":"Invalid query parameters or `q` search query.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"422":{"description":"The `q` search query is well-formed but too broad and exceeded the search time budget — narrow it.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}},"/api/v1/changes":{"get":{"operationId":"getApiV1Changes","tags":["Changes"],"summary":"List job changes","description":"Poll the append-only feed of job change events for incremental sync. Pages forward by a monotonic integer `cursor`; omit the cursor to replay the full history from the beginning (initial sync). Always pass the returned `next_cursor` back on the next poll. When `has_more` is true, keep paging immediately; when false, poll again on your own interval. Set `include=job` to embed the current job record (descriptions omitted) with each change. Use `since` (an ISO-8601 timestamp with offset) as a convenience alternative to `cursor` for starting the feed at a point in time; it is mutually exclusive with a non-zero `cursor`. Snapshot filters (`level`, `workplace`, `employment_type`, `country`, `company_id`, `has_salary`) use before-OR-after matching: an event is delivered if the job matched the filter before the change or after it — so you also see jobs leaving your scope (e.g. filtering `level=senior` still delivers the event where a job moves out of the senior level). Different filter dimensions are ANDed together. The `changed_fields` attribution filter delivers only events that changed at least one of the named content fields; `created` events carry no field-level attribution and are always delivered.","parameters":[{"name":"cursor","in":"query","required":false,"description":"Resume the feed after this change id. Omit to replay the full history from the beginning. Always pass back the `next_cursor` from the previous response. Mutually exclusive with `since` (a non-zero `cursor` alongside `since` is rejected).","schema":{"default":"0","type":"string","pattern":"^\\d+$"}},{"name":"types","in":"query","required":false,"description":"Filter to specific change kinds. Repeat the parameter or comma-separate values (e.g. `types=created,closed`). A change matches if it is any of the given kinds.","style":"form","explode":true,"schema":{"maxItems":4,"type":"array","items":{"type":"string","enum":["created","updated","closed","reopened"]}}},{"name":"level","in":"query","required":false,"description":"Filter by seniority level. Repeat the parameter or comma-separate values. Matches before-OR-after: an event is delivered if the job was at any of these levels before the change or is at one after it (jobs leaving your scope are still delivered).","style":"form","explode":true,"schema":{"maxItems":7,"type":"array","items":{"type":"string","enum":["intern","entry","mid","senior","staff","lead","executive"]}}},{"name":"workplace","in":"query","required":false,"description":"Filter by workplace arrangement. Repeat the parameter or comma-separate values. Matches before-OR-after: delivered if the job matched any of these before the change or matches one after it.","style":"form","explode":true,"schema":{"maxItems":3,"type":"array","items":{"type":"string","enum":["remote","hybrid","onsite"]}}},{"name":"employment_type","in":"query","required":false,"description":"Filter by employment type. Repeat the parameter or comma-separate values. Matches before-OR-after: delivered if the job matched any of these before the change or matches one after it.","style":"form","explode":true,"schema":{"maxItems":5,"type":"array","items":{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]}}},{"name":"country","in":"query","required":false,"description":"Filter by ISO 3166-1 alpha-2 country code(s). Repeat the parameter or comma-separate values (e.g. `country=us,de`). Up to 20 values; case-insensitive. Matches before-OR-after: delivered if the job was tagged with any of these countries before the change or matches its current location.","style":"form","explode":true,"schema":{"maxItems":20,"type":"array","items":{"type":"string","minLength":2,"maxLength":2}}},{"name":"company_id","in":"query","required":false,"description":"Filter to changes for jobs belonging to this numeric company id.","schema":{"type":"integer"}},{"name":"has_salary","in":"query","required":false,"description":"When `true`, deliver events where the job had a salary before the change OR has one after it; when `false`, the inverse. Matches before-OR-after state.","schema":{"type":"boolean"}},{"name":"changed_fields","in":"query","required":false,"description":"Attribution filter: deliver only events that changed at least one of these content fields. Repeat the parameter or comma-separate values (e.g. `changed_fields=salary_min,salary_max`). `created` events are always delivered (they have no field-level attribution).","style":"form","explode":true,"schema":{"maxItems":27,"type":"array","items":{"type":"string","enum":["closed_at","title","url","apply_url","description_html","description_md","location_raw","locations_raw","location","city","region","postal_code","country_code","latitude","longitude","usa","workplace","employment_type","level","language","salary_raw","salary_min","salary_max","salary_currency","salary_period","posted_at","expires_at"]}}},{"name":"since","in":"query","required":false,"description":"Start the feed at this ISO-8601 timestamp, including a UTC offset (e.g. `2024-01-01T00:00:00+00:00`). A convenience alternative to `cursor` for starting from a point in time; resolved to a cursor server-side. Mutually exclusive with a non-zero `cursor`.","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of changes to return. Defaults to 100; values above 500 are clamped to 500.","schema":{"default":100,"type":"integer","exclusiveMinimum":0}},{"name":"include","in":"query","required":false,"description":"When set to `job`, attach the current job record (descriptions omitted) to each change.","schema":{"type":"string","enum":["job"]}}],"responses":{"200":{"description":"A page of change events.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","description":"Monotonic change id. Use it as the `cursor` to resume the feed after this event."},"job_id":{"type":"integer","description":"Numeric id of the job that changed."},"change_type":{"type":"string","enum":["created","updated","closed","reopened"],"description":"The kind of change: `created`, `updated`, `closed`, or `reopened`."},"changed_at":{"type":"string","description":"When the change was recorded as an ISO-8601 date-time string."},"changed_fields":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"The content fields that changed on this event, in canonical order. Null on `created` events (which carry no field-level attribution)."},"job":{"description":"The current job record (descriptions omitted). Present only when `include=job`; null if the job record is unavailable.","anyOf":[{"type":"object","properties":{"id":{"type":"integer","description":"Numeric job id."},"source_id":{"type":"integer","description":"Numeric source id."},"company_id":{"type":"integer","description":"Numeric company id."},"external_job_id":{"type":"string","description":"The job id assigned by the job's original source."},"url":{"type":"string","description":"Canonical URL of the job listing."},"apply_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Direct apply URL, or null."},"title":{"type":"string","description":"Job title."},"location_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Raw location string from the source, or null."},"locations_raw":{"$ref":"#/components/schemas/JsonValue"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Human-readable location display string in the posting's original order; may lead with a region label while `country_code` reflects the primary country; or null."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"City, or null."},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Region / state, or null."},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Postal code, or null."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country code, or null."},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Latitude, or null."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Longitude, or null."},"usa":{"type":"boolean","description":"Whether the job is located in the United States."},"country_codes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country codes the job is tagged with, or null."},"admin1_refs":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"First-level administrative division refs, or null."},"workplace":{"anyOf":[{"type":"string","enum":["remote","hybrid","onsite"]},{"type":"null"}],"description":"Workplace arrangement (remote / hybrid / onsite), or null."},"employment_type":{"anyOf":[{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},{"type":"null"}],"description":"Employment type, or null."},"level":{"anyOf":[{"type":"string","enum":["intern","entry","mid","senior","staff","lead","executive"]},{"type":"null"}],"description":"Seniority level, or null."},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 639-1 language code, or null."},"salary_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Raw salary string from the source, or null."},"salary_min":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum of the stated salary range, or null."},"salary_max":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum of the stated salary range, or null."},"salary_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 4217 salary currency code, or null."},"salary_period":{"anyOf":[{"type":"string","enum":["year","month","week","day","hour"]},{"type":"null"}],"description":"Salary period (e.g. year, hour), or null."},"posted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job was posted as an ISO-8601 date-time string, or null."},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job expires as an ISO-8601 date-time string, or null."},"content_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Content hash used for change detection, or null."},"first_seen_at":{"type":"string","description":"When the job was first seen as an ISO-8601 date-time string."},"closed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job was delisted (null for open jobs) as an ISO-8601 date-time string, or null."},"created_at":{"type":"string","description":"When the job record was created as an ISO-8601 date-time string."},"updated_at":{"type":"string","description":"When the job record was last updated as an ISO-8601 date-time string."},"description_md":{"description":"Markdown job description. Present only when `description=text`.","anyOf":[{"type":"string"},{"type":"null"}]},"description_html":{"description":"HTML job description. Present only when `description=html`.","anyOf":[{"type":"string"},{"type":"null"}]},"company":{"anyOf":[{"type":"object","properties":{"id":{"type":"integer","description":"Numeric company id."},"name":{"type":"string","description":"Company display name."},"website_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company website URL, or null."},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company logo URL, or null."}},"required":["id","name","website_url","logo_url"],"description":"Condensed company summary attached to each job."},{"type":"null"}],"description":"Company summary, or null when unknown."}},"required":["id","source_id","company_id","external_job_id","url","apply_url","title","location_raw","locations_raw","location","city","region","postal_code","country_code","latitude","longitude","usa","country_codes","admin1_refs","workplace","employment_type","level","language","salary_raw","salary_min","salary_max","salary_currency","salary_period","posted_at","expires_at","content_hash","first_seen_at","closed_at","created_at","updated_at","company"],"description":"A job listing as returned by the list endpoint."},{"type":"null"}]}},"required":["id","job_id","change_type","changed_at","changed_fields"],"description":"A single entry in the append-only job change feed."},"description":"The page of change events, ordered by ascending `id`."},"next_cursor":{"type":"string","description":"ALWAYS present — pass it back as `cursor` on the next poll. Echoes your cursor when no new events are available."},"has_more":{"type":"boolean","description":"Whether more events may be immediately available. Keep paging while true."},"limit":{"type":"integer","description":"The effective page size applied to this response."}},"required":["data","next_cursor","has_more","limit"],"description":"A cursor-paginated page of job change events."}}}},"400":{"description":"Invalid query parameters.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}},"/api/v1/meta/vocab":{"get":{"operationId":"getApiV1MetaVocab","tags":["Meta"],"summary":"List vocabulary values","description":"Enumerate the accepted values for each enum-backed filter parameter (and the `salary_period` field). Use these to build filter UIs without hard-coding values.","responses":{"200":{"description":"The controlled vocabulary values.","content":{"application/json":{"schema":{"type":"object","properties":{"workplace":{"readOnly":true,"description":"Accepted values for the `workplace` filter.","type":"array","items":{"type":"string"}},"employment_type":{"readOnly":true,"description":"Accepted values for the `employment_type` filter.","type":"array","items":{"type":"string"}},"level":{"readOnly":true,"description":"Accepted values for the `level` filter.","type":"array","items":{"type":"string"}},"salary_period":{"readOnly":true,"description":"Possible values of the `salary_period` field on a job (no filter parameter).","type":"array","items":{"type":"string"}},"status":{"readOnly":true,"description":"Accepted values for the `status` filter.","type":"array","items":{"type":"string"}}},"required":["workplace","employment_type","level","salary_period","status"],"description":"Controlled vocabulary values for the enum filter parameters."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}},"/api/v1/locations/countries":{"get":{"operationId":"getApiV1LocationsCountries","tags":["Locations"],"summary":"List countries","description":"List every country available as a `country` filter value. Each `code` is the exact two-letter value the jobs `country` filter accepts.","responses":{"200":{"description":"The available countries.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"ISO 3166-1 alpha-2 country code (2-letter uppercase) — the exact `country` filter value."},"name":{"type":"string","description":"Country display name."},"slug":{"type":"string","description":"URL-safe country slug."}},"required":["code","name","slug"],"description":"A country available as a `country` filter value."},"description":"All countries available as `country` filter values."}},"required":["data"],"description":"The list of countries usable as location filters."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}},"/api/v1/locations/states":{"get":{"operationId":"getApiV1LocationsStates","tags":["Locations"],"summary":"List states","description":"List the states / admin-1 regions of a country available as `state` filter values. Each `code` (e.g. `US-CA`) is the exact value the jobs `state` filter accepts.","parameters":[{"name":"country","in":"query","required":true,"description":"ISO 3166-1 alpha-2 country code to list regions for (2 letters, case-insensitive).","schema":{"type":"string","minLength":2,"maxLength":2}}],"responses":{"200":{"description":"The available states / regions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"The exact `state` filter value (e.g. `US-CA`), formatted `<COUNTRY>-<ADMIN1>`."},"admin1_code":{"type":"string","description":"First-level administrative division code (e.g. `CA`)."},"name":{"type":"string","description":"State / region display name."},"slug":{"type":"string","description":"URL-safe state / region slug."}},"required":["code","admin1_code","name","slug"],"description":"A state / admin-1 region available as a `state` filter value."},"description":"The states / regions of the requested country usable as `state` filter values."}},"required":["data"],"description":"The list of states / regions usable as location filters."}}}},"400":{"description":"Invalid or missing country parameter.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}},"/api/v1/jobs/{id}":{"get":{"operationId":"getApiV1JobsById","tags":["Jobs"],"summary":"Get a job by id","description":"Retrieve a single job by its numeric id, including its company and resolved locations. Closed jobs remain retrievable.","parameters":[{"name":"id","in":"path","required":true,"description":"The numeric job id.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"The requested job.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer","description":"Numeric job id."},"source_id":{"type":"integer","description":"Numeric source id."},"company_id":{"type":"integer","description":"Numeric company id."},"external_job_id":{"type":"string","description":"The job id assigned by the job's original source."},"url":{"type":"string","description":"Canonical URL of the job listing."},"apply_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Direct apply URL, or null."},"title":{"type":"string","description":"Job title."},"location_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Raw location string from the source, or null."},"locations_raw":{"$ref":"#/components/schemas/JsonValue"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Human-readable location display string in the posting's original order; may lead with a region label while `country_code` reflects the primary country; or null."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"City, or null."},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Region / state, or null."},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Postal code, or null."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country code, or null."},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Latitude, or null."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Longitude, or null."},"usa":{"type":"boolean","description":"Whether the job is located in the United States."},"country_codes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country codes the job is tagged with, or null."},"admin1_refs":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"First-level administrative division refs, or null."},"workplace":{"anyOf":[{"type":"string","enum":["remote","hybrid","onsite"]},{"type":"null"}],"description":"Workplace arrangement (remote / hybrid / onsite), or null."},"employment_type":{"anyOf":[{"type":"string","enum":["full_time","part_time","contract","temporary","internship"]},{"type":"null"}],"description":"Employment type, or null."},"level":{"anyOf":[{"type":"string","enum":["intern","entry","mid","senior","staff","lead","executive"]},{"type":"null"}],"description":"Seniority level, or null."},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 639-1 language code, or null."},"salary_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Raw salary string from the source, or null."},"salary_min":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum of the stated salary range, or null."},"salary_max":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum of the stated salary range, or null."},"salary_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 4217 salary currency code, or null."},"salary_period":{"anyOf":[{"type":"string","enum":["year","month","week","day","hour"]},{"type":"null"}],"description":"Salary period (e.g. year, hour), or null."},"posted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job was posted as an ISO-8601 date-time string, or null."},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job expires as an ISO-8601 date-time string, or null."},"content_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Content hash used for change detection, or null."},"first_seen_at":{"type":"string","description":"When the job was first seen as an ISO-8601 date-time string."},"closed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the job was delisted (null for open jobs) as an ISO-8601 date-time string, or null."},"created_at":{"type":"string","description":"When the job record was created as an ISO-8601 date-time string."},"updated_at":{"type":"string","description":"When the job record was last updated as an ISO-8601 date-time string."},"description_md":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Markdown job description, or null."},"description_html":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"HTML job description, or null."},"company":{"anyOf":[{"type":"object","properties":{"id":{"type":"integer","description":"Numeric company id."},"name":{"type":"string","description":"Company display name."},"website_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company website URL, or null."},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company logo URL, or null."},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Industry label, or null."},"size_range":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Employee headcount range, or null."},"founded_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Year the company was founded, or null."},"is_agency":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the company is a staffing agency, or null."},"linkedin_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"LinkedIn company identifier, or null."},"created_at":{"type":"string","description":"When the company record was created as an ISO-8601 date-time string."},"updated_at":{"type":"string","description":"When the company record was last updated as an ISO-8601 date-time string."}},"required":["id","name","website_url","logo_url","industry","size_range","founded_year","is_agency","linkedin_id","created_at","updated_at"],"description":"Full company record."},{"type":"null"}],"description":"Full company record, or null when unknown."},"locations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","description":"Numeric location id."},"kind":{"type":"string","description":"Location granularity (e.g. city, region)."},"name":{"type":"string","description":"Location name."},"slug":{"type":"string","description":"URL-safe location slug."},"ascii_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ASCII-normalized location name, or null."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country code, or null."},"country_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Country name, or null."},"admin1_code":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"First-level administrative division code, or null."},"admin1_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"First-level administrative division name, or null."},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Latitude, or null."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Longitude, or null."},"population":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Population, or null."},"geonames_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"GeoNames identifier, or null."},"created_at":{"type":"string","description":"When the location record was created as an ISO-8601 date-time string."}},"required":["id","kind","name","slug","ascii_name","country_code","country_name","admin1_code","admin1_name","latitude","longitude","population","geonames_id","created_at"],"description":"A resolved location associated with a job."},"description":"Resolved locations associated with the job."}},"required":["id","source_id","company_id","external_job_id","url","apply_url","title","location_raw","locations_raw","location","city","region","postal_code","country_code","latitude","longitude","usa","country_codes","admin1_refs","workplace","employment_type","level","language","salary_raw","salary_min","salary_max","salary_currency","salary_period","posted_at","expires_at","content_hash","first_seen_at","closed_at","created_at","updated_at","description_md","description_html","company","locations"],"description":"A single job listing with its company and resolved locations."}}}},"400":{"description":"The job id is not a positive integer.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"404":{"description":"No job exists with the given id.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}}},"429":{"description":"Rate limit exceeded for the account. Retry after the interval in the `Retry-After` header.","content":{"application/problem+json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"A URI reference identifying the problem type."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"description":"A human-readable explanation specific to this occurrence.","type":"string"},"errors":{"description":"Per-field validation errors, when applicable.","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The offending field path."},"message":{"type":"string","description":"What was wrong with the field."}},"required":["field","message"]}}},"required":["type","title","status"],"description":"An RFC-7807 `application/problem+json` error response."}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"string"}}}}}}}}}