{
  "openapi": "3.0.1",
  "info": {
    "title": "Live Greenhouse Jobs API — Filters, Change Tracking, Ghost Jobs",
    "description": "Scrape a company's live Greenhouse board and filter server-side so you pay only for matches: skills, remote, salary floor, employment type, seniority. Per-run change feed tags each role new, changed, open or closed — authoritative ghost-job detection, not a resold snapshot. No keys. Pay per result.",
    "version": "0.1",
    "x-build-id": "2fa7sxaReLIam4r1v"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/greyridge-signals~greenhouse-jobs-live/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-greyridge-signals-greenhouse-jobs-live",
        "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/greyridge-signals~greenhouse-jobs-live/runs": {
      "post": {
        "operationId": "runs-sync-greyridge-signals-greenhouse-jobs-live",
        "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/greyridge-signals~greenhouse-jobs-live/run-sync": {
      "post": {
        "operationId": "run-sync-greyridge-signals-greenhouse-jobs-live",
        "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": "One entry per company. Each may be:\n• a domain — stripe.com (the Greenhouse board slug is auto-detected)\n• a bare board slug — stripe\n• an explicit greenhouse:token — greenhouse:gitlab\n\nThe full live board is pulled for each company so the change-feed can diff the complete current set. Leave this empty and turn on \"Use maintained roster\" to pull a broad live feed without listing companies yourself.",
            "items": {
              "type": "string"
            }
          },
          "useRoster": {
            "title": "Use maintained roster (no company list needed)",
            "type": "boolean",
            "description": "Pull from the built-in, live-verified roster of Greenhouse boards — so you get a broad current feed WITHOUT supplying a company list. The roster is continuously re-verified and pruned (dead boards removed, live ones kept), which is the capability a resold 'all of Greenhouse' database charges for. Combine with your own Companies to run both. Off by default.",
            "default": false
          },
          "rosterLimit": {
            "title": "Roster size cap",
            "minimum": 0,
            "type": "integer",
            "description": "When Use maintained roster is on, cap how many boards to pull, richest-first (boards with the most open roles). 0 = all boards in the roster. Only applies to roster boards, not your own Companies.",
            "default": 0
          },
          "rosterFilter": {
            "title": "Roster filter",
            "type": "string",
            "description": "When Use maintained roster is on, keep only roster boards whose company name or token contains this text (case-insensitive). Leave blank for the whole roster."
          },
          "includeClosed": {
            "title": "Include closed / ghost jobs",
            "type": "boolean",
            "description": "Also emit roles that were present on the previous run but are gone now (status=closed). This is the ghost-job signal — on by default; it is the feature a resold-database feed cannot provide.",
            "default": true
          },
          "includeSalary": {
            "title": "Include normalized salary",
            "type": "boolean",
            "description": "Parse each role's pay-transparency range from the live board and return a normalized salary object {min, max, currency, period, annualized}. On by default. Greenhouse exposes no structured salary field, so this is a maintained call-time parse of the employer's own disclosed range — not a resold estimate.",
            "default": true
          },
          "includeCompany": {
            "title": "Include company enrichment",
            "type": "boolean",
            "description": "Attach a per-job company block: display name, resolved primary domain, email provider (from MX), SaaS/tech stack (from DNS), domain age and registrar (from RDAP). Resolved once per board and reused across every role (keyless, no extra per-job cost). The domain is never a blind guess — it is either the custom careers host on the board's own apply URL, or a candidate whose live homepage actually names the company; otherwise the domain is null. Off by default.",
            "default": false
          },
          "includeCompanyVerify": {
            "title": "Verify company domain via homepage",
            "type": "boolean",
            "description": "When company enrichment is on and the board has no custom careers domain, probe candidate domains and keep one only if its live homepage references the company (a few small requests per board). Turn off to rely solely on the authoritative careers-URL signal. On by default.",
            "default": true
          },
          "includeDescription": {
            "title": "Include full description",
            "type": "boolean",
            "description": "Also return the job description (larger output; off by default). Format is controlled by Description format.",
            "default": false
          },
          "descriptionType": {
            "title": "Description format",
            "enum": [
              "text",
              "html"
            ],
            "type": "string",
            "description": "Plain text (cleaned) or raw HTML. Only applies when Include full description is on.",
            "default": "text"
          },
          "maxItemsPerCompany": {
            "title": "Max live rows per company",
            "minimum": 0,
            "type": "integer",
            "description": "Cap the number of LIVE rows (new/changed/open) returned per company. 0 = no cap. Closed/ghost rows are additional and not capped by this.",
            "default": 0
          },
          "firstRunNewAsOpen": {
            "title": "First run: label everything 'open'",
            "type": "boolean",
            "description": "On the very first run of a board (no prior snapshot), label every role 'open' instead of 'new' so you do not get a one-time flood of 'new'. Subsequent runs always diff normally.",
            "default": false
          },
          "ghostDays": {
            "title": "Ghost-job age threshold (days)",
            "minimum": 0,
            "type": "integer",
            "description": "Age in days at which a still-OPEN role is flagged a ghost-job candidate (ghost_candidate=true) — an evergreen listing the employer keeps posted without actively filling. Uses the longest of: how long we have continuously observed the role open (days_open), the board's own posted_at age, corroborated by a stale updated_at. 0 = use the default (60). This is the stale-but-open ghost signal, distinct from is_ghost (a role that vanished).",
            "default": 60
          },
          "skills": {
            "title": "Filter: skills",
            "type": "array",
            "description": "Keep only roles whose parsed requirements include these skills (e.g. Python, Go, Kubernetes). Needs Include full description on. Only matching rows are returned and billed. Match mode is controlled by Skills match.",
            "items": {
              "type": "string"
            }
          },
          "skillsMatch": {
            "title": "Skills match",
            "enum": [
              "any",
              "all"
            ],
            "type": "string",
            "description": "any = keep a role if it has at least one of the listed skills (default). all = require every listed skill.",
            "default": "any"
          },
          "remote": {
            "title": "Filter: remote only",
            "type": "boolean",
            "description": "When set, keep only remote roles (or, if unset in the UI, no work-model filter is applied). Derived from the parsed location work-model."
          },
          "workplace": {
            "title": "Filter: work model",
            "type": "array",
            "description": "Keep only these work models: remote, hybrid, onsite. Leave empty for all.",
            "items": {
              "type": "string"
            }
          },
          "employmentType": {
            "title": "Filter: employment type",
            "type": "array",
            "description": "Keep only these canonical employment types: full_time, part_time, contract, temporary, internship. Leave empty for all.",
            "items": {
              "type": "string"
            }
          },
          "seniority": {
            "title": "Filter: seniority (exact)",
            "type": "array",
            "description": "Keep only these exact levels: intern, junior, mid, senior, lead, staff, principal, director, executive. Leave empty for all.",
            "items": {
              "type": "string"
            }
          },
          "seniorityMin": {
            "title": "Filter: minimum seniority",
            "type": "string",
            "description": "Keep roles at this level or more senior (e.g. 'senior' keeps senior/lead/staff/principal/director/executive). Leave blank for no floor."
          },
          "salaryMin": {
            "title": "Filter: minimum salary (annualized)",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only roles whose annualized disclosed compensation clears this floor. Roles with no disclosed pay are excluded (they cannot prove they clear it). 0 = no floor.",
            "default": 0
          },
          "salaryCurrency": {
            "title": "Filter: salary currency",
            "type": "string",
            "description": "Restrict the minimum-salary filter to a currency code (e.g. USD, EUR, GBP). Leave blank to accept any currency."
          },
          "country": {
            "title": "Filter: country",
            "type": "array",
            "description": "Keep only roles in these ISO country codes (e.g. US, CA, GB). Leave empty for all.",
            "items": {
              "type": "string"
            }
          },
          "excludeGhost": {
            "title": "Filter: exclude ghost jobs",
            "type": "boolean",
            "description": "Drop likely-evergreen ghost_candidate roles for a clean, actively-hiring feed. Our ghost signal is authoritative (from the change-feed age), not a marketing claim."
          },
          "ghostOnly": {
            "title": "Filter: only ghost jobs",
            "type": "boolean",
            "description": "Return ONLY the likely-ghost roles (ghost-job intelligence). Mutually exclusive with Exclude ghost jobs."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}