{
  "openapi": "3.0.1",
  "info": {
    "title": "ATS Job Change Feed - Greenhouse & Lever",
    "description": "Monitor Greenhouse and Lever job boards and get only what changed since your last run: new, updated, and removed postings, each corroborated by a content hash. You pay per change, and unchanged rows are free.",
    "version": "0.1",
    "x-build-id": "1UidIdLh1iEpbiNrH"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/dstyx~ats-job-feed-actor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-dstyx-ats-job-feed-actor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/dstyx~ats-job-feed-actor/runs": {
      "post": {
        "operationId": "runs-sync-dstyx-ats-job-feed-actor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/dstyx~ats-job-feed-actor/run-sync": {
      "post": {
        "operationId": "run-sync-dstyx-ats-job-feed-actor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "companies": {
            "title": "Companies",
            "type": "array",
            "description": "Start here when you know the employer but not its ATS. Each name is looked up on Greenhouse first, then Lever, Ashby, Workable, Recruitee, Rippling, Breezy HR, Teamtailor, BambooHR, Manatal, Dover, Gem, Occupop, and iCIMS, in that order. A pasted careers-page URL also works. Names found on none are listed in RUN_SUMMARY under `unresolved_companies`, never billed. If you know the platform or its board address, use that platform's field below instead.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "first_run_mode": {
            "title": "First run: snapshot or silent baseline",
            "enum": [
              "emit_all_as_new",
              "baseline_only"
            ],
            "type": "string",
            "description": "Choose this before your first run. 'emit_all_as_new' returns every open job tagged 'new' and bills for each. 'baseline_only' returns nothing, records the baseline, and starts reporting real changes on the next run.",
            "default": "emit_all_as_new"
          },
          "title_keywords": {
            "title": "Job title contains any of",
            "type": "array",
            "description": "Case-insensitive substrings. A job is kept if its title contains at least one. Leave empty for no title filter.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "greenhouse_boards": {
            "title": "Companies on Greenhouse",
            "type": "array",
            "description": "Company board tokens from Greenhouse job board URLs. For https://boards.greenhouse.io/airbnb the token is 'airbnb'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "lever_boards": {
            "title": "Companies on Lever",
            "type": "array",
            "description": "Company slugs from Lever job board URLs. For https://jobs.lever.co/spotify the slug is 'spotify'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "ashby_boards": {
            "title": "Companies on Ashby",
            "type": "array",
            "description": "Company slugs from Ashby job board URLs. For https://jobs.ashbyhq.com/linear the slug is 'linear'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "workable_boards": {
            "title": "Companies on Workable",
            "type": "array",
            "description": "Account slugs from Workable job board URLs. For https://apply.workable.com/blueground the slug is 'blueground'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "recruitee_boards": {
            "title": "Companies on Recruitee",
            "type": "array",
            "description": "Company slugs from Recruitee job board URLs. For https://bunq.recruitee.com the slug is 'bunq'. Recruitee publishes a real update timestamp, so changes on these boards are corroborated rather than hash-only.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "rippling_boards": {
            "title": "Companies on Rippling",
            "type": "array",
            "description": "Company slugs from Rippling job board URLs. For https://ats.rippling.com/rippling/jobs the slug is 'rippling'. Rippling publishes no timestamps and no description, so only title, department, location and URL are watched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "breezy_boards": {
            "title": "Companies on Breezy HR",
            "type": "array",
            "description": "Company slugs from Breezy job board URLs. For https://acme.breezy.hr the slug is 'acme'. Breezy's feed carries no description, so body-text edits are not visible on these boards.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "teamtailor_boards": {
            "title": "Companies on Teamtailor",
            "type": "array",
            "description": "Career-site subdomains from Teamtailor URLs. For https://career.teamtailor.com the slug is 'career'. Note this is often not the company name, so naming it here is more reliable than the automatic lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "smartrecruiters_boards": {
            "title": "Companies on SmartRecruiters",
            "type": "array",
            "description": "Company identifiers from SmartRecruiters job board URLs. For https://jobs.smartrecruiters.com/BoschGroup the id is 'BoschGroup', and it is case-sensitive. SmartRecruiters answers an unknown id with an empty list rather than an error, so a board that returns no jobs is reported as a failed fetch instead of a board-wide removal - which means a genuine close-out of every job is never reported. Not covered by the automatic company lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "jobsoid_boards": {
            "title": "Companies on Jobsoid",
            "type": "array",
            "description": "Career-site subdomains from Jobsoid boards. For https://valueit.jobsoid.com enter 'valueit'. Jobsoid returns an empty success for both an unknown tenant and a real board with no open jobs, so an empty response is reported as a failed fetch instead of a board-wide removal - which means a genuine close-out of every job is never reported. Not covered by the automatic company lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "occupop_boards": {
            "title": "Companies on Occupop",
            "type": "array",
            "description": "Company keys from Occupop careers pages. For the Flogas careers page enter 'flogas'. A real board with no openings stays distinguishable from an unknown key, so full close-outs are reported safely. Occupop is also tried at the end of automatic company-name lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "bamboohr_boards": {
            "title": "Companies on BambooHR",
            "type": "array",
            "description": "Company slugs from BambooHR careers URLs. For https://scribd.bamboohr.com/careers the slug is 'scribd'. BambooHR publishes no timestamps and no description, so only title, department, location and employment type are watched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "personio_boards": {
            "title": "Companies on Personio",
            "type": "array",
            "description": "Company subdomains from Personio job board URLs. For https://acme.jobs.personio.de the slug is 'acme'. Personio rate-limits unknown subdomains rather than returning an error, so it is not covered by the automatic company lookup and must be named here.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "manatal_boards": {
            "title": "Companies on Manatal",
            "type": "array",
            "description": "Career-page slugs from Manatal career pages. For https://www.careers-page.com/manatal the slug is 'manatal'. Manatal publishes no timestamps at all, so only title, department, location and employment type are watched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "jobvite_boards": {
            "title": "Companies on Jobvite",
            "type": "array",
            "description": "Company slugs from Jobvite career sites. For https://jobs.jobvite.com/nutanix the slug is 'nutanix'. Jobvite is read from its public careers board, which is HTML rather than a JSON feed, so a page redesign can break parsing - the actor refuses a partial board rather than reporting the missing jobs as removed. Jobvite publishes no timestamps, no descriptions and no departments, so title, location and the URL are what is watched, and jobs with many locations show a summary such as \"3 Locations\". A slug that is not a Jobvite customer answers 403 rather than 404, which is why Jobvite is not covered by the automatic company lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "polymer_boards": {
            "title": "Companies on Polymer",
            "type": "array",
            "description": "Organization slugs from Polymer job boards. For https://jobs.polymer.co/pirate-wires the slug is 'pirate-wires'. Polymer publishes no update timestamp, so a change is detected from the posting's own fields; descriptions are not fetched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "dover_boards": {
            "title": "Companies on Dover",
            "type": "array",
            "description": "Board slugs from Dover job boards. For https://app.dover.com/jobs/dover the slug is 'dover'. Dover publishes both a creation and an update timestamp, so changes are corroborated rather than resting on the content hash alone.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "pinpoint_boards": {
            "title": "Companies on Pinpoint",
            "type": "array",
            "description": "Career-site subdomains from Pinpoint job boards. For https://ogier.pinpointhq.com enter 'ogier'. The subdomain is usually not the company name (Pinpoint's own board is 'workwithus'), which is one reason Pinpoint is not covered by the automatic company lookup; the other is that many unused Pinpoint subdomains serve demo postings, so a guessed name can return jobs that do not exist. Pinpoint publishes no timestamp of any kind, so changes rest on the content hash alone. A role advertised in several locations is several postings here, each with its own application page, so each is tracked - and closed - separately.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "gem_boards": {
            "title": "Companies on Gem",
            "type": "array",
            "description": "Board slugs from Gem job boards. For https://jobs.gem.com/retool enter 'retool'. The slug is case-sensitive, so keep the exact spelling your board URL uses. Gem publishes a first-published date but no update timestamp, so changes rest on the content hash. Postings the employer has unlisted from its public board are excluded.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "adp_boards": {
            "title": "Companies on ADP MyJobs",
            "type": "array",
            "description": "Career-site slugs from ADP MyJobs boards. For https://myjobs.adp.com/merakeycareers/cx/job-listing enter 'merakeycareers'. The slug is the career-site address rather than the company name, which is why ADP is not covered by the automatic company lookup. ADP serves every public requisition belonging to the employer behind that career site, so an employer running several career sites returns the same jobs on each. ADP publishes a posting date but no update timestamp, so changes rest on the content hash.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "traffit_boards": {
            "title": "Companies on Traffit",
            "type": "array",
            "description": "Traffit tenant names. For https://xkom.traffit.com/career/ enter 'xkom' - the full career-page address works too. **Rebaseline warning:** the tenant name and full URL are both accepted, but keep the exact form you first use. Switching forms creates a different board identity and reports every open job as new. Traffit answers an unknown tenant with a temporary-error page rather than a not-found, so a mistyped tenant is reported as a failed fetch and cannot be found by the automatic company lookup. Traffit publishes a publication date but no update timestamp, so changes rest on the content hash.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "recruiterflow_boards": {
            "title": "Companies on Recruiterflow",
            "type": "array",
            "description": "Careers-page slugs from Recruiterflow boards. For https://recruiterflow.com/hirelatam/jobs enter 'hirelatam'. The slug is the agency's chosen careers path rather than the company name ('searchforce-careers', or a long generated id), and unused slugs can serve demo postings, which is why Recruiterflow is not covered by the automatic company lookup. Recruiterflow publishes an opening date but no update timestamp, so changes rest on the content hash.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "phenom_boards": {
            "title": "Career sites on Phenom",
            "type": "array",
            "description": "Career-site hostnames or HTTPS career URLs from Phenom boards. For https://careers.example.com/us/en/search-results enter 'careers.example.com'. The actor always monitors that host's default public external board; pasted locale, search, category, and job paths do not narrow it. Hostname and URL spellings are the same board, so changing between them does not rebaseline it. A Phenom hostname cannot be inferred from a company name, so add it here rather than using automatic lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "join_boards": {
            "title": "Companies on JOIN",
            "type": "array",
            "description": "Enter the company slug from https://join.com/companies/{slug}, or paste that public company or job URL. JOIN uses an opaque numeric company ID internally; the actor reads it from the public company page before walking every five-job API page. Equivalent slug and URL spellings share a baseline. JOIN cannot be resolved safely from a company name, so add it here rather than using automatic lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "icims_boards": {
            "title": "Career sites on iCIMS",
            "type": "array",
            "description": "Paste a public iCIMS careers URL or enter its hostname, for example 'uscareers-msci.icims.com'. The actor reads the public embedded search view and verifies every advertised page before reporting a board. Equivalent URL and hostname spellings share one baseline. iCIMS has no stable update timestamp or listing description, so title, location, category, employment type and URL are watched. An unknown iCIMS subdomain answers 404, so a bare company name can be looked up automatically.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "jazzhr_boards": {
            "title": "Career pages on JazzHR",
            "type": "array",
            "description": "Enter a JazzHR career-page slug or paste its public URL. For https://projectx.applytojob.com/apply enter 'projectx'. The actor reads the complete public HTML listing. A nonexistent slug redirects to JazzHR's marketing site, so it is reported as a failed fetch rather than an empty board; JazzHR cannot be found safely from a company name. Listings provide no stable timestamps or descriptions, so title, location, and URL are watched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "factorial_boards": {
            "title": "Career pages on Factorial",
            "type": "array",
            "description": "Paste a public Factorial careers URL or enter its full hostname, for example 'aldesa.factorial.es'. The regional domain is part of the board identity, so a company slug alone is not enough and Factorial is not covered by automatic company lookup. Equivalent root, embedded-list, and job-page URLs on the same hostname share one baseline. The actor reads the complete server-rendered listing and verifies Factorial's page identity before reporting a board. Listings provide no stable timestamps or descriptions, so title, location, team, contract type, remote status, and URL are watched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "paylocity_boards": {
            "title": "Career pages on Paylocity",
            "type": "array",
            "description": "Paste a public Paylocity Jobs/All careers URL or enter its board GUID. For https://recruiting.paylocity.com/Recruiting/Jobs/All/e4878719-8343-49e2-b88a-e434f3557389/DOC-Maintenance-Inc the GUID is 'e4878719-8343-49e2-b88a-e434f3557389'; the trailing title is cosmetic, so both forms share one baseline. Paylocity cannot be inferred from a company name because the GUID is opaque and an unknown one redirects to a 200 error page. The actor validates the board-specific embedded listing before reporting changes. Listings provide a posting date, department, location, and remote flag, but no update timestamp or full description.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "avature_boards": {
            "title": "Career portals on Avature",
            "type": "array",
            "description": "Paste an Avature public job-search or job-detail URL, for example 'https://careers.avature.net/en_US/main/SearchJobs'. The portal path is part of the board identity: one host can publish several career portals, so equivalent search and job-page URLs under the same portal share one baseline. The actor reads every server-rendered listing page and verifies the portal's published result range and total before reporting changes. Avature cannot be inferred safely from a company name, so add its public URL here rather than using automatic lookup. Listings provide no stable update timestamp or full description, so title, location, department, and URL are watched.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "successfactors_boards": {
            "title": "Career sites on SAP SuccessFactors",
            "type": "array",
            "description": "Paste the public SuccessFactors career-site URL or enter its hostname, for example 'jobs.csiro.au' or 'careers.nemetschek.com/Bluebeam'. The actor reads the public search results and verifies every advertised page before reporting a board. A shared SuccessFactors host can serve several brands under different paths, so retain a brand path when your careers URL contains one; changing it monitors a different board and its first run follows your first-run setting. SuccessFactors cannot be inferred safely from a company name, so add it here rather than using automatic lookup. Listings do not provide a stable update timestamp or description, so changes are detected from the public title, location, and URL.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "oracle_boards": {
            "title": "Career sites on Oracle Cloud HCM",
            "type": "array",
            "description": "Enter host/SiteNumber, such as 'ebwh.fa.us2.oraclecloud.com/CX_1002', or paste its standard HTTPS Candidate Experience URL containing /sites/CX_1002. The site is required: different sites on one tenant are separate boards. Locale, job paths, and search filters do not narrow the monitored site. Equivalent URL and host/SiteNumber spellings share one baseline; changing the host or SiteNumber selects a different board and its first run follows your first-run setting. Vanity domains, custom site names, and fragment-based legacy URLs require the standard Oracle tenant URL and SiteNumber. Automatic company lookup cannot infer them.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "eightfold_boards": {
            "title": "Career sites on Eightfold",
            "type": "array",
            "description": "Enter the career-site host and its published group domain as 'host/domain', for example 'paypal.eightfold.ai/paypal.com'. You can also paste an HTTPS Eightfold career URL when it includes '?domain=paypal.com'. Both parts identify the board: one Eightfold host can serve several domains, and vanity hosts such as careers.micron.com are supported. Equivalent pair and URL spellings share one baseline. The actor detects both current PCS-X and older public Eightfold feeds. Unknown domains can answer 403 or 404; failed fetches preserve the baseline so they can never report a false board-wide removal. Eightfold cannot be inferred safely from a company name, so add it here rather than using automatic lookup.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "taleo_boards": {
            "title": "Career sections on Oracle Taleo",
            "type": "array",
            "description": "Paste a public Taleo career-section URL, such as 'https://textron.taleo.net/careersection/textron/jobsearch.ftl', or enter 'tenant/section', such as 'textron/textron'. Both parts identify the board: one Taleo tenant can publish several career sections. Equivalent URL and tenant/section spellings share one baseline. The actor derives Taleo's opaque portal number and configured result columns from the public search page, then verifies every advertised API page. Taleo cannot be inferred safely from a company name, so add it here rather than using automatic lookup. Listings provide a posting date but no update timestamp or description.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "comeet_boards": {
            "title": "Companies on Comeet",
            "type": "array",
            "description": "Comeet boards, written as '<uid>:<token>' - for example '54.007:45715B315B38AE22B8D051A0A457D051E61'. Both values are printed in the employer's own careers page: open it, view source, and look for the uid and token handed to the Comeet embed. A Comeet board is two values rather than a slug, which is why it is not covered by the automatic company lookup. **Rebaseline warning:** both '<uid>:<token>' and '<uid>/<token>' are accepted, but keep the exact form you first use. Switching forms creates a different stored board identity and reports every open job as new. Comeet publishes a real per-posting update timestamp, so changes there are corroborated by two independent signals rather than one.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "workday_boards": {
            "title": "Companies on Workday",
            "type": "array",
            "description": "Workday career sites. Paste the career-site URL - for https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite enter 'nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite'. The numbered wd* host is part of the address and cannot be guessed from the company name, which is why the URL is asked for rather than a slug, and why Workday is not covered by the automatic company lookup. **Rebaseline warning:** a pasted URL and the documented shorthand are both accepted, but keep the exact form you first use. Switching forms creates a different board identity and reports every open job as new. Workday publishes no usable timestamp, no description and only a location summary ('4 Locations'), so title, that summary, employment type, remote type and the URL are what is watched. Some career sites cap their own result count at 2,000 even when the board is larger; the actor detects that from the site's own category counts and reads the board one category at a time so it is still tracked in full, which makes those boards slower to read.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "zoho_boards": {
            "title": "Companies on Zoho Recruit",
            "type": "array",
            "description": "Zoho Recruit organizations. For https://acme.zohorecruit.com/jobs/Careers enter 'acme', or 'acme/Careers'. An organization can publish several career pages and each is a separate board, so add the page name when it is not the default 'Careers'. **Rebaseline warning:** both 'acme' and 'acme/Careers' are accepted for the default page, but keep the exact form you first use. Switching forms creates a different board identity and reports every open job as new. Filled roles that the career site still displays are excluded. Zoho publishes an opening date but no update timestamp, so changes rest on the content hash.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "ukg_boards": {
            "title": "Companies on UKG Pro Recruiting (UltiPro)",
            "type": "array",
            "description": "UKG job boards. Paste the career-site URL - for https://recruiting2.ultipro.com/ASH1002AF/JobBoard/20c06009-60fe-480c-8ce5-da3e9df145b9 enter 'recruiting2.ultipro.com/ASH1002AF/20c06009-60fe-480c-8ce5-da3e9df145b9'. The host, the company code and the board id are three separate values and none can be guessed from a company name, which is why the URL is asked for and why UKG is not covered by the automatic company lookup. **Rebaseline warning:** a pasted URL and the documented shorthand are both accepted, but keep the exact form you first use. Switching forms creates a different board identity and reports every open job as new. UKG publishes a real posting date but no update timestamp, and no remote/on-site flag that could be read reliably.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "bullhorn_boards": {
            "title": "Companies on Bullhorn",
            "type": "array",
            "description": "Bullhorn job boards, as 'swimlane/corp token' - for example '70/A4VPG0'. Pasting the API URL your careers page calls also works: 'public-rest70.bullhornstaffing.com/rest-services/A4VPG0'. Both values are published by the careers page itself, but neither can be guessed from a company name, which is why Bullhorn is not covered by the automatic company lookup. **Rebaseline warning:** the API URL and 'swimlane/corp token' forms are both accepted, but keep the exact form you first use. Switching forms creates a different board identity and reports every open job as new. Deleted and unpublished job orders are excluded. Bullhorn publishes both a creation and an update timestamp, so changes are corroborated rather than resting on the content hash alone. It publishes no public job page, so each job links to the vendor's own public record for it.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "exclude_title_keywords": {
            "title": "Job title does NOT contain",
            "type": "array",
            "description": "Case-insensitive substrings. A job is dropped if its title contains any of these. Applied before the include filter.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "locations": {
            "title": "Location contains any of",
            "type": "array",
            "description": "Case-insensitive substrings matched against the job's locations.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "departments": {
            "title": "Department or team contains any of",
            "type": "array",
            "description": "Case-insensitive substrings. Note: enabling this makes Greenhouse requests heavier, because Greenhouse only returns department data on its detailed payload.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "remote_only": {
            "title": "Remote jobs only",
            "type": "boolean",
            "description": "Keep only postings the source explicitly marks remote. Jobs with no remote signal are excluded rather than guessed at.",
            "default": false
          },
          "emit_unchanged": {
            "title": "Also emit unchanged jobs",
            "type": "boolean",
            "description": "Include jobs that did not change. Never billed as a change event. Turns this into a full dump plus change labels.",
            "default": false
          },
          "include_description": {
            "title": "Include job description",
            "type": "boolean",
            "description": "Add the plain-text description to each output record. Makes Greenhouse responses substantially larger.",
            "default": false
          },
          "hash_description": {
            "title": "Detect description changes",
            "type": "boolean",
            "description": "Fold the description into the change hash so description edits count as updates. Increases sensitivity and request size. Changing this resets your baseline.",
            "default": false
          },
          "detect_timestamp_only": {
            "title": "Report vendor-timestamp-only updates (noisy)",
            "type": "boolean",
            "description": "Report a job as 'updated' when the vendor's updated_at advanced but nothing in the content hash changed. Off by default: measured on real Greenhouse boards, this signal is dominated by occasional bulk re-stamps that touch nearly every job at once with no visible change - each would be billed as an update. To catch description edits, enable 'Detect description changes' instead. Greenhouse only: Lever, Ashby and Workable publish no updated_at, so their changes are always detected by content hash.",
            "default": false
          },
          "state_store_name": {
            "title": "State store name",
            "type": "string",
            "description": "Named key-value store holding your baseline between runs. Must be a named store: Apify gives every run a fresh default store, so a baseline there would never survive.",
            "default": "ats-job-feed-state"
          },
          "state_key": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Pin the baseline to a fixed key. By default the key reflects your hashing options only, so adding a board keeps every other board's history while changing what is hashed starts a clean baseline."
          },
          "reset_state": {
            "title": "Reset baseline",
            "type": "boolean",
            "description": "Discard the stored baseline and treat this run as a first run.",
            "default": false
          },
          "removal_alarm_ratio": {
            "title": "Mass-removal alarm threshold",
            "minimum": 0.01,
            "maximum": 1,
            "type": "number",
            "description": "Fraction of a board's tracked jobs that vanishing in one run is treated as suspicious rather than real. Guards against a truncated but successful response wiping your feed.",
            "default": 0.5
          },
          "suppress_mass_removals": {
            "title": "Withhold suspicious mass removals",
            "type": "boolean",
            "description": "When the alarm trips, keep the baseline and emit no removals for that board, so a genuine mass close-out is reported only once a second run corroborates it.",
            "default": true
          },
          "max_concurrency": {
            "title": "Max concurrent board requests",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "These are free public endpoints; keep this polite.",
            "default": 5
          },
          "request_timeout": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 180,
            "type": "integer",
            "description": "Per-request timeout for a single board fetch.",
            "default": 30
          },
          "max_retries": {
            "title": "Max retries per board",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Retries use exponential backoff with jitter and honor Retry-After.",
            "default": 4
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}