{
  "data": {
    "id": "8VGgLzspVLnGioOxo",
    "actId": "6HsKvw9VT0JJhsrtu",
    "userId": "zq8lKbpLzTjGDayPC",
    "startedAt": "2026-10-18T04:55:36.520Z",
    "finishedAt": "2026-10-18T04:56:17.415Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 40806,
      "runTimeSecs": 40.806,
      "computeUnits": 0.04534,
      "imageSizeBytes": 3243412480
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "GK9YjZRyQZVzOdoH5",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"ZipRecruiter Jobs with Full Description Extractor Input\",\n  \"description\": \"Search ZipRecruiter by keyword and location, or paste search and job URLs. Returns each job's full description plus salary, company, location, workplace and apply details.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"startUrls\": {\n      \"title\": \"ZipRecruiter URLs\",\n      \"type\": \"array\",\n      \"description\": \"ZipRecruiter search URLs (filters in the URL are honored, e.g. `https://www.ziprecruiter.com/jobs-search?search=software+engineer&location=New+York%2C+NY`) or individual job links like `https://www.ziprecruiter.com/c/Company/Job/Title/-in-City,ST?jid=...`.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"default\": [],\n      \"prefill\": [\n        \"https://www.ziprecruiter.com/jobs-search?search=software+engineer&location=New+York%2C+NY\"\n      ]\n    },\n    \"searchQueries\": {\n      \"title\": \"Search queries\",\n      \"type\": \"array\",\n      \"description\": \"Job keywords to search, e.g. `registered nurse`, `software engineer`. Every query is searched in every location below.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"default\": []\n    },\n    \"locations\": {\n      \"title\": \"Locations\",\n      \"type\": \"array\",\n      \"description\": \"Cities, states or `United States` for a national search. Leave empty to search the whole United States. Every query is searched in every location.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"default\": []\n    },\n    \"companyName\": {\n      \"title\": \"Company name\",\n      \"type\": \"string\",\n      \"description\": \"Only jobs from one company, e.g. `Visa`. The name is resolved on ZipRecruiter. Leave Search queries empty to browse all of the company's jobs.\",\n      \"editor\": \"textfield\"\n    },\n    \"jobType\": {\n      \"title\": \"Job type\",\n      \"type\": \"string\",\n      \"description\": \"Employment-type filter, applied to keyword searches.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"any\",\n        \"full_time\",\n        \"part_time\",\n        \"contract\",\n        \"contract_to_hire\",\n        \"temporary\",\n        \"as_needed\",\n        \"other\",\n        \"internship\"\n      ],\n      \"enumTitles\": [\n        \"Any\",\n        \"Full-time\",\n        \"Part-time\",\n        \"Contract\",\n        \"Contract to hire\",\n        \"Temporary\",\n        \"As needed\",\n        \"Other\",\n        \"Internship\"\n      ],\n      \"default\": \"any\"\n    },\n    \"workplace\": {\n      \"title\": \"Workplace type\",\n      \"type\": \"string\",\n      \"description\": \"Work-arrangement filter (remote includes jobs that offer a remote option).\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"any\",\n        \"remote\",\n        \"hybrid\",\n        \"onsite\"\n      ],\n      \"enumTitles\": [\n        \"Any\",\n        \"Remote\",\n        \"Hybrid\",\n        \"On-site\"\n      ],\n      \"default\": \"any\"\n    },\n    \"remoteOnly\": {\n      \"title\": \"Remote only (legacy)\",\n      \"type\": \"boolean\",\n      \"description\": \"Kept for older tasks: same as setting Workplace type to `Remote`.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"experienceLevels\": {\n      \"title\": \"Experience levels\",\n      \"type\": \"array\",\n      \"description\": \"Restrict to one or more seniority levels. Empty = no filter.\",\n      \"editor\": \"select\",\n      \"items\": {\n        \"type\": \"string\",\n        \"enum\": [\n          \"no_experience\",\n          \"junior\",\n          \"mid\",\n          \"senior\"\n        ],\n        \"enumTitles\": [\n          \"No experience\",\n          \"Junior\",\n          \"Mid\",\n          \"Senior\"\n        ]\n      },\n      \"default\": []\n    },\n    \"daysPosted\": {\n      \"title\": \"Posted within (days)\",\n      \"type\": \"integer\",\n      \"description\": \"Only jobs posted within the last N days. 0 = any time.\",\n      \"minimum\": 0,\n      \"maximum\": 30,\n      \"default\": 0\n    },\n    \"radiusMiles\": {\n      \"title\": \"Search radius (miles)\",\n      \"type\": \"integer\",\n      \"description\": \"Distance around the location. 0 = ZipRecruiter's default.\",\n      \"minimum\": 0,\n      \"maximum\": 100,\n      \"default\": 0\n    },\n    \"salaryMin\": {\n      \"title\": \"Minimum salary (annual USD)\",\n      \"type\": \"integer\",\n      \"description\": \"Lower bound of the pay range: only jobs whose advertised annual pay reaches at least this amount. 0 = no lower bound.\",\n      \"minimum\": 0,\n      \"maximum\": 10000000,\n      \"default\": 0\n    },\n    \"salaryMax\": {\n      \"title\": \"Maximum salary (annual USD)\",\n      \"type\": \"integer\",\n      \"description\": \"Upper bound of the pay range: only jobs whose advertised annual pay stays at or below this amount. 0 = no upper bound.\",\n      \"minimum\": 0,\n      \"maximum\": 10000000,\n      \"default\": 0\n    },\n    \"quickApplyOnly\": {\n      \"title\": \"1-Click Apply only\",\n      \"type\": \"boolean\",\n      \"description\": \"Only jobs that can be applied to on ZipRecruiter with 1-Click Apply.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"fetchDescriptions\": {\n      \"title\": \"Fetch full descriptions\",\n      \"type\": \"boolean\",\n      \"description\": \"When on (recommended), each job's detail data and full description are fetched — the actor's core feature. Turn off for faster, cheaper runs with search-card fields only.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"maxItems\": {\n      \"title\": \"Max items\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum number of job postings to return across all searches.\",\n      \"minimum\": 1,\n      \"maximum\": 10000,\n      \"default\": 50,\n      \"prefill\": 3\n    },\n    \"maxSearches\": {\n      \"title\": \"Max searches\",\n      \"type\": \"integer\",\n      \"description\": \"Cap on the number of query × location combinations when using Search queries (each combination is one search).\",\n      \"minimum\": 1,\n      \"maximum\": 100,\n      \"default\": 100\n    }\n  },\n  \"required\": []\n}",
    "readme": "# ZipRecruiter Jobs with Full Description Extractor\n\nScrape **ZipRecruiter** job postings with their **complete description text** — not just the search-card snippet. Search by keyword across as many locations as you need, paste any search or job URL, apply ZipRecruiter's own filters (job type, workplace, experience, posted date, salary, 1-Click Apply), and get one flat row per posting with salary, company profile, benefits, workplace type, posting dates and apply links.\n\n## What this actor does\n\n- **Full descriptions:** every job's complete description text and HTML, fetched per posting — the search results page only shows a teaser.\n- **Two ways to start:** keyword queries × locations, or any ZipRecruiter search URL / job URL / company page URL you already have.\n- **Company-scoped search:** set `companyName` (or paste a `/co/<company>/Jobs` URL) to get only that employer's postings — combine it with a keyword or leave the queries empty to browse everything the company has open.\n- **ZipRecruiter's own filters:** employment type, remote / hybrid / on-site, experience level, posted within N days, search radius, minimum salary, 1-Click Apply only.\n- **Rich per-job data:** structured salary (min / max, interval, currency, annualized values, provided vs estimated), benefits, workplace types, poster dates, company size / industry / website / headquarters, external apply links.\n- **Cards-only mode:** switch off `fetchDescriptions` for faster runs with search-card fields only.\n- **Empty fields are omitted** — a value ZipRecruiter does not show for a job is left out of that row rather than sent as `null`.\n\n## Output per job\n\nIdentity:\n\n- `type` — always `job_ziprecruiter`\n- `id`, `listingKey` — ZipRecruiter's stable listing key for the posting\n- `jid` — ZipRecruiter's job (open seat) id, matching the `jid=` in job URLs\n- `matchId` — ZipRecruiter's internal match id\n- `url` — canonical job posting URL\n- `title` — job title\n\nCompany:\n\n- `company`, `companyId`, `companyUrl`, `companyLogo`\n- `companySize`, `companyIndustries[]`, `companyWebsite`, `companyFoundedYear`, `companyHqLocation`\n\nLocation:\n\n- `location` — display location, e.g. `Chicago, IL`\n- `city`, `state`, `country`, `countryCode`, `postalCode`, `county`\n- `workplaceTypes[]` — `Remote`, `Hybrid`, `On-site`, `Remote optional`\n- `isRemote`, `isHybrid`\n\nPay:\n\n- `salary` — the salary text shown on the posting, e.g. `$34 - $41.56/hr`\n- `salaryMin`, `salaryMax` — numeric bounds in the given period\n- `salaryPeriod` — `hour`, `day`, `week`, `month` or `year`\n- `salaryCurrency` — e.g. `USD`\n- `salaryMinAnnual`, `salaryMaxAnnual` — annualized bounds\n- `salarySource` — `provided`, `parsed` or `estimated` (estimated pay is flagged, never mixed with real numbers)\n\nDetails:\n\n- `description` — full description as plain text\n- `descriptionHtml` — the same description as HTML\n- `descriptionFetchFailed` — `true` when a job's detail data could not be fetched; the row is kept from search-card data\n- `employmentTypes[]` — e.g. `Full-time`, `Contract`\n- `benefits[]` — e.g. `Medical`, `Dental`, `Paid time off`\n- `postedAt`, `rollingPostedAt` — ISO 8601 timestamps\n- `postedAgo` — human label, e.g. `3 days ago`\n- `isActive` — whether the listing is active\n- `educationLevels[]`, `experienceMonths`\n- `shortDescription` — search-card teaser\n\nApplying & sharing:\n\n- `applyUrl` — apply link; for off-site applications this is the external apply URL\n- `applyType` — `external`, `quick-apply` or `internal`\n- `directApply` — `true` when 1-Click Apply is available\n- `shareUrl` — short share link\n\nMetadata:\n\n- `inputUrl` — the search URL (or job URL) that produced this row\n- `searchQuery` — the keyword that produced this row\n- `scrapedAt` — ISO 8601 timestamp\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `startUrls` | Array of strings | – | ZipRecruiter search URLs or job URLs. Filters already in a search URL are honored. |\n| `searchQueries` | Array of strings | – | Keywords to search, e.g. `registered nurse`. Each query is searched in every location. |\n| `locations` | Array of strings | – | Cities, states or `United States`. Empty = whole United States. |\n| `companyName` | String | – | Only jobs from this company (resolved on ZipRecruiter). Works with or without Search queries; company page URLs in `startUrls` do the same. |\n| `jobType` | String (select) | `any` | `any`, `full_time`, `part_time`, `contract`, `contract_to_hire`, `temporary`, `as_needed`, `other`, `internship` |\n| `workplace` | String (select) | `any` | `any`, `remote`, `hybrid`, `onsite` |\n| `remoteOnly` | Boolean | `false` | Legacy shortcut for `workplace: \"remote\"` |\n| `experienceLevels` | Multi-select | – | `no_experience`, `junior`, `mid`, `senior` |\n| `daysPosted` | Integer | `0` | Posted within the last N days (0–30). 0 = any time. |\n| `radiusMiles` | Integer | `0` | Search radius around the location (0–100 miles). 0 = default. |\n| `salaryMin` | Integer | `0` | Lower bound of the pay range: only jobs whose annual pay reaches at least this amount. 0 = no lower bound. |\n| `salaryMax` | Integer | `0` | Upper bound of the pay range: only jobs whose annual pay stays at or below this amount. 0 = no upper bound. |\n| `quickApplyOnly` | Boolean | `false` | Only jobs with 1-Click Apply |\n| `fetchDescriptions` | Boolean | `true` | Off = cards-only mode (faster; no full description) |\n| `maxItems` | Integer | `50` | Maximum jobs to return (1–10000) |\n| `maxSearches` | Integer | `100` | Cap on query × location combinations |\n\n### Example: keyword search with filters\n\n```json\n{\n    \"searchQueries\": [\"registered nurse\"],\n    \"locations\": [\"Chicago, IL\"],\n    \"jobType\": \"full_time\",\n    \"daysPosted\": 7,\n    \"maxItems\": 50\n}\n```\n\n### Example: remote senior roles in several states\n\n```json\n{\n    \"searchQueries\": [\"data engineer\", \"analytics engineer\"],\n    \"locations\": [\"Texas\", \"Florida\"],\n    \"workplace\": \"remote\",\n    \"experienceLevels\": [\"senior\"],\n    \"salaryMin\": 120000,\n    \"maxItems\": 200\n}\n```\n\n### Example: a search URL you already built\n\n```json\n{\n    \"startUrls\": [\n        \"https://www.ziprecruiter.com/jobs-search?search=fire+alarm+technician&location=New+York%2C+NY&days=7\"\n    ],\n    \"maxItems\": 100\n}\n```\n\n### Example: enrich specific job links\n\n```json\n{\n    \"startUrls\": [\n        \"https://www.ziprecruiter.com/c/Company/Job/Title/-in-Chicago,IL?jid=abcdef1234567890\"\n    ],\n    \"fetchDescriptions\": true\n}\n```\n\n## Use cases\n\n- **Talent intelligence:** follow hiring volume and role mix for a company, city or industry over time.\n- **Compensation research:** aggregate `salaryMin` / `salaryMax` / `salaryMinAnnual` by title, state and workplace type; separate provided pay from estimates with `salarySource`.\n- **Recruiting pipelines:** build clean candidate-facing lists with real apply links (`applyUrl`, `directApply`).\n- **Skills and text mining:** run NLP or skill extraction over the complete description, not a teaser.\n- **Remote-work tracking:** monitor `workplaceTypes` mixes nationwide or per employer.\n- **Job-board products:** keep an internal board fresh with scheduled runs and deduplicate on `jid`.\n\n## FAQ\n\n**Do I need a ZipRecruiter account, cookies or a proxy?**\nNo. The actor reads public job data only and configures its own proxy automatically — there is nothing to set up. It deliberately fetches a small data payload per job instead of downloading each job page, which keeps runs fast and light.\n\n**Why do some rows have no salary, and how does the salary range filter work?**\nZipRecruiter only publishes pay for part of its listings. When the employer does not disclose pay and ZipRecruiter cannot parse it from the text, the salary fields are simply absent from that row instead of being guessed; when ZipRecruiter shows an estimated range, the numbers are omitted and `salarySource` is `estimated`. `salaryMin` and `salaryMax` map to ZipRecruiter's own bounds — a job is kept only when its advertised annual pay reaches `salaryMin` (when set) and stays at or below `salaryMax` (when set). Jobs without any disclosed pay may still appear, because the source does not know their pay and cannot filter them out.\n\n**Can I get results in a specific order (newest first, highest paid)?**\nNo — ZipRecruiter's public search does not expose a sort order; results always arrive in ZipRecruiter's own relevance order. Use `daysPosted` to restrict recency, or sort the dataset yourself after the run (for example by `postedAt` or `salaryMaxAnnual`).\n\n**Why are there no GPS coordinates?**\nZipRecruiter's public job data does not include latitude/longitude. The actor delivers `city`, `state`, `postalCode`, `county`, `countryCode` and the display location, which geocode accurately in any mapping tool.\n\n**Which countries are supported?**\nUnited States and Canada (Canadian jobs appear on ziprecruiter.com with Canadian locations). The United Kingdom and Ireland run separate ZipRecruiter sites with their own legacy job pages; this actor covers the US/Canada data source.\n\n**What does `descriptionFetchFailed: true` mean, and can I skip descriptions?**\nIt means the job's detail data could not be fetched (for example, the site asked for verification mid-run); the row is still delivered from search-card data and flagged so you can re-run those jobs later. Rows that load fine but genuinely have no description are not flagged. To skip detail fetching entirely, set `fetchDescriptions` to `false` — you get search-card fields only (title, company, location, pay, workplace, posting date, apply link), which is significantly faster.\n\n**How do I get only one company's jobs?**\nSet `companyName` (for example `Visa`) and either add keywords to `searchQueries` or leave them empty to browse all of that company's open roles. Pasting a company page URL such as `https://www.ziprecruiter.com/co/Visa/Jobs` into `startUrls` works the same way. The company name is resolved on ZipRecruiter before the search runs; if it cannot be found, the actor says so in the status message and falls back to a normal keyword search when you provided one.\n\n**How many results can one search return, and why can the same job appear twice later?**\nZipRecruiter caps a single search at about 10,000 results; for broader coverage, split your topic into several queries or locations. Within a single run the actor deduplicates by ZipRecruiter's own job id, so a job found by several of your searches is only delivered once. If you run the same search again later, ZipRecruiter has re-ranked and reposted listings in the meantime, so some rows may differ.\n\n**What does `applyType: \"external\"` mean?**\nThe application continues on the employer's own site. `applyUrl` points to that flow. `quick-apply` means the job supports ZipRecruiter's 1-Click Apply, and `internal` means the application is completed on ZipRecruiter.\n\n**Is this affiliated with ZipRecruiter?**\nNo. This actor is an independent tool that reads ZipRecruiter's public job data and is not affiliated with or endorsed by ZipRecruiter.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "ziprecruiter-jobs-with-full-description-extractor",
      "title": "ZipRecruiter Jobs with Full Description Extractor",
      "description": "Search ZipRecruiter by keyword and location, or paste search and job URLs, and get each job's full description text alongside salary, company, workplace, location and apply details.",
      "version": "1.0",
      "buildTag": "latest",
      "defaultRunOptions": {
        "build": "latest",
        "timeoutSecs": 3600,
        "memoryMbytes": 4096
      },
      "minMemoryMbytes": 4096,
      "maxMemoryMbytes": 8192,
      "meta": {
        "templateId": "python-playwright"
      },
      "input": {
        "title": "ZipRecruiter Jobs with Full Description Extractor Input",
        "description": "Search ZipRecruiter by keyword and location, or paste search and job URLs. Returns each job's full description plus salary, company, location, workplace and apply details.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "startUrls": {
            "title": "ZipRecruiter URLs",
            "type": "array",
            "description": "ZipRecruiter search URLs (filters in the URL are honored, e.g. `https://www.ziprecruiter.com/jobs-search?search=software+engineer&location=New+York%2C+NY`) or individual job links like `https://www.ziprecruiter.com/c/Company/Job/Title/-in-City,ST?jid=...`.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "default": [],
            "prefill": [
              "https://www.ziprecruiter.com/jobs-search?search=software+engineer&location=New+York%2C+NY"
            ]
          },
          "searchQueries": {
            "title": "Search queries",
            "type": "array",
            "description": "Job keywords to search, e.g. `registered nurse`, `software engineer`. Every query is searched in every location below.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "locations": {
            "title": "Locations",
            "type": "array",
            "description": "Cities, states or `United States` for a national search. Leave empty to search the whole United States. Every query is searched in every location.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "companyName": {
            "title": "Company name",
            "type": "string",
            "description": "Only jobs from one company, e.g. `Visa`. The name is resolved on ZipRecruiter. Leave Search queries empty to browse all of the company's jobs.",
            "editor": "textfield"
          },
          "jobType": {
            "title": "Job type",
            "type": "string",
            "description": "Employment-type filter, applied to keyword searches.",
            "editor": "select",
            "enum": [
              "any",
              "full_time",
              "part_time",
              "contract",
              "contract_to_hire",
              "temporary",
              "as_needed",
              "other",
              "internship"
            ],
            "enumTitles": [
              "Any",
              "Full-time",
              "Part-time",
              "Contract",
              "Contract to hire",
              "Temporary",
              "As needed",
              "Other",
              "Internship"
            ],
            "default": "any"
          },
          "workplace": {
            "title": "Workplace type",
            "type": "string",
            "description": "Work-arrangement filter (remote includes jobs that offer a remote option).",
            "editor": "select",
            "enum": [
              "any",
              "remote",
              "hybrid",
              "onsite"
            ],
            "enumTitles": [
              "Any",
              "Remote",
              "Hybrid",
              "On-site"
            ],
            "default": "any"
          },
          "remoteOnly": {
            "title": "Remote only (legacy)",
            "type": "boolean",
            "description": "Kept for older tasks: same as setting Workplace type to `Remote`.",
            "default": false,
            "prefill": false
          },
          "experienceLevels": {
            "title": "Experience levels",
            "type": "array",
            "description": "Restrict to one or more seniority levels. Empty = no filter.",
            "editor": "select",
            "items": {
              "type": "string",
              "enum": [
                "no_experience",
                "junior",
                "mid",
                "senior"
              ],
              "enumTitles": [
                "No experience",
                "Junior",
                "Mid",
                "Senior"
              ]
            },
            "default": []
          },
          "daysPosted": {
            "title": "Posted within (days)",
            "type": "integer",
            "description": "Only jobs posted within the last N days. 0 = any time.",
            "minimum": 0,
            "maximum": 30,
            "default": 0
          },
          "radiusMiles": {
            "title": "Search radius (miles)",
            "type": "integer",
            "description": "Distance around the location. 0 = ZipRecruiter's default.",
            "minimum": 0,
            "maximum": 100,
            "default": 0
          },
          "salaryMin": {
            "title": "Minimum salary (annual USD)",
            "type": "integer",
            "description": "Lower bound of the pay range: only jobs whose advertised annual pay reaches at least this amount. 0 = no lower bound.",
            "minimum": 0,
            "maximum": 10000000,
            "default": 0
          },
          "salaryMax": {
            "title": "Maximum salary (annual USD)",
            "type": "integer",
            "description": "Upper bound of the pay range: only jobs whose advertised annual pay stays at or below this amount. 0 = no upper bound.",
            "minimum": 0,
            "maximum": 10000000,
            "default": 0
          },
          "quickApplyOnly": {
            "title": "1-Click Apply only",
            "type": "boolean",
            "description": "Only jobs that can be applied to on ZipRecruiter with 1-Click Apply.",
            "default": false,
            "prefill": false
          },
          "fetchDescriptions": {
            "title": "Fetch full descriptions",
            "type": "boolean",
            "description": "When on (recommended), each job's detail data and full description are fetched — the actor's core feature. Turn off for faster, cheaper runs with search-card fields only.",
            "default": true,
            "prefill": true
          },
          "maxItems": {
            "title": "Max items",
            "type": "integer",
            "description": "Maximum number of job postings to return across all searches.",
            "minimum": 1,
            "maximum": 10000,
            "default": 50,
            "prefill": 3
          },
          "maxSearches": {
            "title": "Max searches",
            "type": "integer",
            "description": "Cap on the number of query × location combinations when using Search queries (each combination is one search).",
            "minimum": 1,
            "maximum": 100,
            "default": 100
          }
        },
        "required": []
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "ZipRecruiter Jobs with Full Description Extractor Output",
        "description": "Dataset of ZipRecruiter job postings with title, company, location, salary, workplace and employment types, full description text, and apply details.",
        "type": "object",
        "properties": {
          "jobs": {
            "type": "string",
            "title": "ZipRecruiter Jobs",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# ZipRecruiter Jobs with Full Description Extractor\n\nScrape **ZipRecruiter** job postings with their **complete description text** — not just the search-card snippet. Search by keyword across as many locations as you need, paste any search or job URL, apply ZipRecruiter's own filters (job type, workplace, experience, posted date, salary, 1-Click Apply), and get one flat row per posting with salary, company profile, benefits, workplace type, posting dates and apply links.\n\n## What this actor does\n\n- **Full descriptions:** every job's complete description text and HTML, fetched per posting — the search results page only shows a teaser.\n- **Two ways to start:** keyword queries × locations, or any ZipRecruiter search URL / job URL / company page URL you already have.\n- **Company-scoped search:** set `companyName` (or paste a `/co/<company>/Jobs` URL) to get only that employer's postings — combine it with a keyword or leave the queries empty to browse everything the company has open.\n- **ZipRecruiter's own filters:** employment type, remote / hybrid / on-site, experience level, posted within N days, search radius, minimum salary, 1-Click Apply only.\n- **Rich per-job data:** structured salary (min / max, interval, currency, annualized values, provided vs estimated), benefits, workplace types, poster dates, company size / industry / website / headquarters, external apply links.\n- **Cards-only mode:** switch off `fetchDescriptions` for faster runs with search-card fields only.\n- **Empty fields are omitted** — a value ZipRecruiter does not show for a job is left out of that row rather than sent as `null`.\n\n## Output per job\n\nIdentity:\n\n- `type` — always `job_ziprecruiter`\n- `id`, `listingKey` — ZipRecruiter's stable listing key for the posting\n- `jid` — ZipRecruiter's job (open seat) id, matching the `jid=` in job URLs\n- `matchId` — ZipRecruiter's internal match id\n- `url` — canonical job posting URL\n- `title` — job title\n\nCompany:\n\n- `company`, `companyId`, `companyUrl`, `companyLogo`\n- `companySize`, `companyIndustries[]`, `companyWebsite`, `companyFoundedYear`, `companyHqLocation`\n\nLocation:\n\n- `location` — display location, e.g. `Chicago, IL`\n- `city`, `state`, `country`, `countryCode`, `postalCode`, `county`\n- `workplaceTypes[]` — `Remote`, `Hybrid`, `On-site`, `Remote optional`\n- `isRemote`, `isHybrid`\n\nPay:\n\n- `salary` — the salary text shown on the posting, e.g. `$34 - $41.56/hr`\n- `salaryMin`, `salaryMax` — numeric bounds in the given period\n- `salaryPeriod` — `hour`, `day`, `week`, `month` or `year`\n- `salaryCurrency` — e.g. `USD`\n- `salaryMinAnnual`, `salaryMaxAnnual` — annualized bounds\n- `salarySource` — `provided`, `parsed` or `estimated` (estimated pay is flagged, never mixed with real numbers)\n\nDetails:\n\n- `description` — full description as plain text\n- `descriptionHtml` — the same description as HTML\n- `descriptionFetchFailed` — `true` when a job's detail data could not be fetched; the row is kept from search-card data\n- `employmentTypes[]` — e.g. `Full-time`, `Contract`\n- `benefits[]` — e.g. `Medical`, `Dental`, `Paid time off`\n- `postedAt`, `rollingPostedAt` — ISO 8601 timestamps\n- `postedAgo` — human label, e.g. `3 days ago`\n- `isActive` — whether the listing is active\n- `educationLevels[]`, `experienceMonths`\n- `shortDescription` — search-card teaser\n\nApplying & sharing:\n\n- `applyUrl` — apply link; for off-site applications this is the external apply URL\n- `applyType` — `external`, `quick-apply` or `internal`\n- `directApply` — `true` when 1-Click Apply is available\n- `shareUrl` — short share link\n\nMetadata:\n\n- `inputUrl` — the search URL (or job URL) that produced this row\n- `searchQuery` — the keyword that produced this row\n- `scrapedAt` — ISO 8601 timestamp\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `startUrls` | Array of strings | – | ZipRecruiter search URLs or job URLs. Filters already in a search URL are honored. |\n| `searchQueries` | Array of strings | – | Keywords to search, e.g. `registered nurse`. Each query is searched in every location. |\n| `locations` | Array of strings | – | Cities, states or `United States`. Empty = whole United States. |\n| `companyName` | String | – | Only jobs from this company (resolved on ZipRecruiter). Works with or without Search queries; company page URLs in `startUrls` do the same. |\n| `jobType` | String (select) | `any` | `any`, `full_time`, `part_time`, `contract`, `contract_to_hire`, `temporary`, `as_needed`, `other`, `internship` |\n| `workplace` | String (select) | `any` | `any`, `remote`, `hybrid`, `onsite` |\n| `remoteOnly` | Boolean | `false` | Legacy shortcut for `workplace: \"remote\"` |\n| `experienceLevels` | Multi-select | – | `no_experience`, `junior`, `mid`, `senior` |\n| `daysPosted` | Integer | `0` | Posted within the last N days (0–30). 0 = any time. |\n| `radiusMiles` | Integer | `0` | Search radius around the location (0–100 miles). 0 = default. |\n| `salaryMin` | Integer | `0` | Lower bound of the pay range: only jobs whose annual pay reaches at least this amount. 0 = no lower bound. |\n| `salaryMax` | Integer | `0` | Upper bound of the pay range: only jobs whose annual pay stays at or below this amount. 0 = no upper bound. |\n| `quickApplyOnly` | Boolean | `false` | Only jobs with 1-Click Apply |\n| `fetchDescriptions` | Boolean | `true` | Off = cards-only mode (faster; no full description) |\n| `maxItems` | Integer | `50` | Maximum jobs to return (1–10000) |\n| `maxSearches` | Integer | `100` | Cap on query × location combinations |\n\n### Example: keyword search with filters\n\n```json\n{\n    \"searchQueries\": [\"registered nurse\"],\n    \"locations\": [\"Chicago, IL\"],\n    \"jobType\": \"full_time\",\n    \"daysPosted\": 7,\n    \"maxItems\": 50\n}\n```\n\n### Example: remote senior roles in several states\n\n```json\n{\n    \"searchQueries\": [\"data engineer\", \"analytics engineer\"],\n    \"locations\": [\"Texas\", \"Florida\"],\n    \"workplace\": \"remote\",\n    \"experienceLevels\": [\"senior\"],\n    \"salaryMin\": 120000,\n    \"maxItems\": 200\n}\n```\n\n### Example: a search URL you already built\n\n```json\n{\n    \"startUrls\": [\n        \"https://www.ziprecruiter.com/jobs-search?search=fire+alarm+technician&location=New+York%2C+NY&days=7\"\n    ],\n    \"maxItems\": 100\n}\n```\n\n### Example: enrich specific job links\n\n```json\n{\n    \"startUrls\": [\n        \"https://www.ziprecruiter.com/c/Company/Job/Title/-in-Chicago,IL?jid=abcdef1234567890\"\n    ],\n    \"fetchDescriptions\": true\n}\n```\n\n## Use cases\n\n- **Talent intelligence:** follow hiring volume and role mix for a company, city or industry over time.\n- **Compensation research:** aggregate `salaryMin` / `salaryMax` / `salaryMinAnnual` by title, state and workplace type; separate provided pay from estimates with `salarySource`.\n- **Recruiting pipelines:** build clean candidate-facing lists with real apply links (`applyUrl`, `directApply`).\n- **Skills and text mining:** run NLP or skill extraction over the complete description, not a teaser.\n- **Remote-work tracking:** monitor `workplaceTypes` mixes nationwide or per employer.\n- **Job-board products:** keep an internal board fresh with scheduled runs and deduplicate on `jid`.\n\n## FAQ\n\n**Do I need a ZipRecruiter account, cookies or a proxy?**\nNo. The actor reads public job data only and configures its own proxy automatically — there is nothing to set up. It deliberately fetches a small data payload per job instead of downloading each job page, which keeps runs fast and light.\n\n**Why do some rows have no salary, and how does the salary range filter work?**\nZipRecruiter only publishes pay for part of its listings. When the employer does not disclose pay and ZipRecruiter cannot parse it from the text, the salary fields are simply absent from that row instead of being guessed; when ZipRecruiter shows an estimated range, the numbers are omitted and `salarySource` is `estimated`. `salaryMin` and `salaryMax` map to ZipRecruiter's own bounds — a job is kept only when its advertised annual pay reaches `salaryMin` (when set) and stays at or below `salaryMax` (when set). Jobs without any disclosed pay may still appear, because the source does not know their pay and cannot filter them out.\n\n**Can I get results in a specific order (newest first, highest paid)?**\nNo — ZipRecruiter's public search does not expose a sort order; results always arrive in ZipRecruiter's own relevance order. Use `daysPosted` to restrict recency, or sort the dataset yourself after the run (for example by `postedAt` or `salaryMaxAnnual`).\n\n**Why are there no GPS coordinates?**\nZipRecruiter's public job data does not include latitude/longitude. The actor delivers `city`, `state`, `postalCode`, `county`, `countryCode` and the display location, which geocode accurately in any mapping tool.\n\n**Which countries are supported?**\nUnited States and Canada (Canadian jobs appear on ziprecruiter.com with Canadian locations). The United Kingdom and Ireland run separate ZipRecruiter sites with their own legacy job pages; this actor covers the US/Canada data source.\n\n**What does `descriptionFetchFailed: true` mean, and can I skip descriptions?**\nIt means the job's detail data could not be fetched (for example, the site asked for verification mid-run); the row is still delivered from search-card data and flagged so you can re-run those jobs later. Rows that load fine but genuinely have no description are not flagged. To skip detail fetching entirely, set `fetchDescriptions` to `false` — you get search-card fields only (title, company, location, pay, workplace, posting date, apply link), which is significantly faster.\n\n**How do I get only one company's jobs?**\nSet `companyName` (for example `Visa`) and either add keywords to `searchQueries` or leave them empty to browse all of that company's open roles. Pasting a company page URL such as `https://www.ziprecruiter.com/co/Visa/Jobs` into `startUrls` works the same way. The company name is resolved on ZipRecruiter before the search runs; if it cannot be found, the actor says so in the status message and falls back to a normal keyword search when you provided one.\n\n**How many results can one search return, and why can the same job appear twice later?**\nZipRecruiter caps a single search at about 10,000 results; for broader coverage, split your topic into several queries or locations. Within a single run the actor deduplicates by ZipRecruiter's own job id, so a job found by several of your searches is only delivered once. If you run the same search again later, ZipRecruiter has re-ranked and reposted listings in the meantime, so some rows may differ.\n\n**What does `applyType: \"external\"` mean?**\nThe application continues on the employer's own site. `applyUrl` points to that flow. `quick-apply` means the job supports ZipRecruiter's 1-Click Apply, and `internal` means the application is completed on ZipRecruiter.\n\n**Is this affiliated with ZipRecruiter?**\nNo. This actor is an independent tool that reads ZipRecruiter's public job data and is not affiliated with or endorsed by ZipRecruiter.\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "ZipRecruiter Jobs",
          "fields": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "description": "Record type (`job_ziprecruiter`)"
              },
              "id": {
                "type": "string",
                "description": "Stable ZipRecruiter listing key"
              },
              "listingKey": {
                "type": "string",
                "description": "Stable ZipRecruiter listing key"
              },
              "matchId": {
                "type": "string",
                "description": "ZipRecruiter match id"
              },
              "jid": {
                "type": "string",
                "description": "ZipRecruiter job (open seat) id"
              },
              "url": {
                "type": "string",
                "description": "Canonical job posting URL"
              },
              "title": {
                "type": "string",
                "description": "Job title"
              },
              "company": {
                "type": "string",
                "description": "Hiring company name"
              },
              "companyId": {
                "type": "string",
                "description": "ZipRecruiter company id"
              },
              "companyUrl": {
                "type": "string",
                "description": "Company jobs page URL"
              },
              "companyLogo": {
                "type": "string",
                "description": "Company logo image URL"
              },
              "location": {
                "type": "string",
                "description": "Display location"
              },
              "city": {
                "type": "string",
                "description": "City"
              },
              "state": {
                "type": "string",
                "description": "Two-letter state code"
              },
              "country": {
                "type": "string",
                "description": "Country name"
              },
              "countryCode": {
                "type": "string",
                "description": "Country code"
              },
              "postalCode": {
                "type": "string",
                "description": "Postal code"
              },
              "county": {
                "type": "string",
                "description": "County"
              },
              "workplaceTypes": {
                "type": "array",
                "description": "Workplace types (Remote, Hybrid, On-site, Remote optional)"
              },
              "isRemote": {
                "type": "boolean",
                "description": "Whether the job offers remote work"
              },
              "isHybrid": {
                "type": "boolean",
                "description": "Whether the job is hybrid"
              },
              "employmentTypes": {
                "type": "array",
                "description": "Employment types (Full-time, Part-time, ...)"
              },
              "benefits": {
                "type": "array",
                "description": "Listed benefits"
              },
              "salary": {
                "type": "string",
                "description": "Salary text as shown on ZipRecruiter"
              },
              "salaryMin": {
                "type": "number",
                "description": "Minimum pay per salaryPeriod"
              },
              "salaryMax": {
                "type": "number",
                "description": "Maximum pay per salaryPeriod"
              },
              "salaryPeriod": {
                "type": "string",
                "description": "hour / day / week / month / year"
              },
              "salaryCurrency": {
                "type": "string",
                "description": "Currency code, e.g. USD"
              },
              "salarySource": {
                "type": "string",
                "description": "provided / parsed / estimated"
              },
              "salaryMinAnnual": {
                "type": "number",
                "description": "Annualized minimum pay"
              },
              "salaryMaxAnnual": {
                "type": "number",
                "description": "Annualized maximum pay"
              },
              "postedAt": {
                "type": "string",
                "description": "ISO 8601 posting timestamp"
              },
              "rollingPostedAt": {
                "type": "string",
                "description": "ISO 8601 rolling posting timestamp"
              },
              "postedAgo": {
                "type": "string",
                "description": "Human recency label, e.g. `3 days ago`"
              },
              "isActive": {
                "type": "boolean",
                "description": "Whether the listing is active"
              },
              "description": {
                "type": "string",
                "description": "Full job description text"
              },
              "descriptionHtml": {
                "type": "string",
                "description": "Full job description HTML"
              },
              "descriptionFetchFailed": {
                "type": "boolean",
                "description": "True when the full description could not be fetched"
              },
              "applyUrl": {
                "type": "string",
                "description": "Apply URL (external apply flow when available)"
              },
              "applyType": {
                "type": "string",
                "description": "external / quick-apply / internal"
              },
              "directApply": {
                "type": "boolean",
                "description": "True when 1-Click Apply is available"
              },
              "shareUrl": {
                "type": "string",
                "description": "Short share URL"
              },
              "companySize": {
                "type": "string",
                "description": "Company size band"
              },
              "companyIndustries": {
                "type": "array",
                "description": "Company industries"
              },
              "companyWebsite": {
                "type": "string",
                "description": "Company website"
              },
              "companyFoundedYear": {
                "type": "string",
                "description": "Company founding year"
              },
              "companyHqLocation": {
                "type": "string",
                "description": "Company headquarters"
              },
              "educationLevels": {
                "type": "array",
                "description": "Education levels mentioned"
              },
              "experienceMonths": {
                "type": "integer",
                "description": "Months of experience mentioned"
              },
              "shortDescription": {
                "type": "string",
                "description": "Search-card description snippet"
              },
              "inputUrl": {
                "type": "string",
                "description": "Search URL (or job URL) that produced the record"
              },
              "searchQuery": {
                "type": "string",
                "description": "Keyword that produced the record"
              },
              "scrapedAt": {
                "type": "string",
                "description": "ISO 8601 scrape timestamp"
              },
              "validThrough": {
                "type": "string",
                "description": "Expiry date when exposed by the source"
              }
            }
          },
          "views": {
            "overview": {
              "title": "Overview",
              "transformation": {
                "fields": [
                  "title",
                  "company",
                  "city",
                  "state",
                  "salary",
                  "isRemote",
                  "url"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "title": {
                    "label": "Title",
                    "format": "text"
                  },
                  "company": {
                    "label": "Company",
                    "format": "text"
                  },
                  "city": {
                    "label": "City",
                    "format": "text"
                  },
                  "state": {
                    "label": "State",
                    "format": "text"
                  },
                  "salary": {
                    "label": "Salary",
                    "format": "text"
                  },
                  "isRemote": {
                    "label": "Remote",
                    "format": "boolean"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  }
                }
              }
            },
            "detailed": {
              "title": "Detailed Results",
              "transformation": {
                "fields": [
                  "id",
                  "jid",
                  "title",
                  "company",
                  "companyUrl",
                  "location",
                  "city",
                  "state",
                  "workplaceTypes",
                  "employmentTypes",
                  "isRemote",
                  "isHybrid",
                  "salary",
                  "salaryMin",
                  "salaryMax",
                  "salaryPeriod",
                  "salaryCurrency",
                  "postedAt",
                  "applyUrl",
                  "url",
                  "scrapedAt"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "id": {
                    "label": "ID",
                    "format": "text"
                  },
                  "jid": {
                    "label": "JID",
                    "format": "text"
                  },
                  "title": {
                    "label": "Title",
                    "format": "text"
                  },
                  "company": {
                    "label": "Company",
                    "format": "text"
                  },
                  "companyUrl": {
                    "label": "Company URL",
                    "format": "link"
                  },
                  "location": {
                    "label": "Location",
                    "format": "text"
                  },
                  "city": {
                    "label": "City",
                    "format": "text"
                  },
                  "state": {
                    "label": "State",
                    "format": "text"
                  },
                  "workplaceTypes": {
                    "label": "Workplace",
                    "format": "text"
                  },
                  "employmentTypes": {
                    "label": "Employment",
                    "format": "text"
                  },
                  "isRemote": {
                    "label": "Remote",
                    "format": "boolean"
                  },
                  "isHybrid": {
                    "label": "Hybrid",
                    "format": "boolean"
                  },
                  "salary": {
                    "label": "Salary",
                    "format": "text"
                  },
                  "salaryMin": {
                    "label": "Min",
                    "format": "number"
                  },
                  "salaryMax": {
                    "label": "Max",
                    "format": "number"
                  },
                  "salaryPeriod": {
                    "label": "Period",
                    "format": "text"
                  },
                  "salaryCurrency": {
                    "label": "Currency",
                    "format": "text"
                  },
                  "postedAt": {
                    "label": "Posted",
                    "format": "text"
                  },
                  "applyUrl": {
                    "label": "Apply",
                    "format": "link"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  },
                  "scrapedAt": {
                    "label": "Scraped at",
                    "format": "text"
                  }
                }
              }
            }
          }
        }
      }
    },
    "buildNumber": "1.0.2",
    "imageDigest": "9ece63f4c2f6d94597c511b4410178f824d258da9404b55cf1783c528c431ff2",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.04534
    }
  }
}