{
  "title": "Greenhouse Jobs Scraper",
  "type": "object",
  "schemaVersion": 1,
  "properties": {
    "boards": {
      "title": "Greenhouse boards",
      "type": "array",
      "description": "One entry per company. Paste the board token or the full board URL - both work. The token is the path segment in https://job-boards.greenhouse.io/<token> or https://boards.greenhouse.io/<token> (for example 'figma'). Embed URLs of the form .../embed/job_board?for=<token> are parsed too. Tokens are case-insensitive. A token with no Greenhouse board returns HTTP 404 and is reported per board rather than failing the run.",
      "editor": "stringList",
      "default": [
        "figma",
        "dropbox",
        "reddit"
      ],
      "prefill": [
        "figma",
        "dropbox",
        "reddit"
      ],
      "sectionCaption": "1 · Choose Greenhouse boards",
      "sectionDescription": "Supply board tokens or supported board URLs; non-Greenhouse boards are outside this Actor's scope."
    },
    "includeContent": {
      "title": "Include full job description",
      "type": "boolean",
      "description": "Keep the full job description as clean plain text (contentText) plus a short excerpt (contentExcerpt). Greenhouse returns descriptions as escaped HTML; this Actor unescapes and strips it. Turn this off for a much smaller dataset - the department and office fields are unaffected.",
      "editor": "checkbox",
      "default": true,
      "sectionCaption": "2 · Choose details and filters",
      "sectionDescription": "Full descriptions can increase dataset size; department names are set by the employer."
    },
    "departmentFilter": {
      "title": "Only these departments",
      "type": "array",
      "description": "Optional. Keep only postings whose Greenhouse department contains one of these strings, for example 'Engineering' or 'Design'. Matching is case-insensitive and partial. Leave empty for every department. Department names are set by each employer, so run once without a filter to see the names a board actually uses.",
      "editor": "stringList"
    },
    "maxResultsPerBoard": {
      "title": "Maximum postings per board",
      "type": "integer",
      "description": "Upper bound on rows saved for each board. Postings are sorted newest-updated first, so a low cap keeps the freshest roles. Greenhouse returns a whole board in one request, so raising this costs almost nothing in time - a 900-posting board is a single response.",
      "editor": "number",
      "default": 200,
      "minimum": 1,
      "sectionCaption": "3 · Bound this run",
      "sectionDescription": "Postings are capped per board and constrained by the shared run budget."
    },
    "maxRunSeconds": {
      "title": "Run time budget (seconds)",
      "type": "integer",
      "description": "Wall-clock budget for the crawl. When it is reached the Actor stops cleanly, keeps everything already saved, and logs which boards it did not reach - instead of being killed with a failed run. Raise it when you pass a long list of boards.",
      "editor": "number",
      "default": 240,
      "minimum": 30
    },
    "onlyNewSinceLastRun": {
      "title": "Only postings new since the last run",
      "type": "boolean",
      "description": "Save only matching postings not successfully saved by a previous monitor run. IDs are retained in the named greenhouse-jobs-baseline store. The first run returns matching postings within your limits; capped or filtered-out jobs remain eligible later. A run with no new matching jobs succeeds with an empty dataset. Avoid concurrent monitor runs for the same board.",
      "editor": "checkbox",
      "default": false,
      "sectionCaption": "4 · Optional new-posting history",
      "sectionDescription": "First enabled runs establish saved IDs. Use one writer per board."
    }
  },
  "description": "Choose public Greenhouse employer boards and a per-employer result cap. Keep new-postings-only mode off for your first sample, then review source coverage before setting up a recurring run."
}
