{
  "openapi": "3.0.1",
  "info": {
    "title": "ATS Jobs Hiring Radar: Greenhouse, Lever, Ashby, Time-to-Fill",
    "description": "Scrape ATS jobs from Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee and Personio via their official public APIs, then monitor hiring: new and closed roles with days-to-fill, stale roles, hiring surges and your own keyword signals. No API keys, no proxies. 100 free job rows per run.",
    "version": "0.1",
    "x-build-id": "pzzVhv8ikOqZFReqD"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/rayla~ats-hiring-radar/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-rayla-ats-hiring-radar",
        "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/rayla~ats-hiring-radar/runs": {
      "post": {
        "operationId": "runs-sync-rayla-ats-hiring-radar",
        "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/rayla~ats-hiring-radar/run-sync": {
      "post": {
        "operationId": "run-sync-rayla-ats-hiring-radar",
        "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",
        "required": [
          "companies"
        ],
        "properties": {
          "companies": {
            "title": "Companies",
            "type": "array",
            "description": "One entry per company. Accepted forms: `greenhouse:gitlab`, `lever:palantir`, `ashby:notion`, `smartrecruiters:BoschGroup`, `recruitee:tellent`, `personio:personio`; a board URL such as https://boards.greenhouse.io/gitlab or https://jobs.ashbyhq.com/notion; or a plain company domain such as gitlab.com (the ATS is auto-detected and cached). SmartRecruiters identifiers are case-sensitive. Workable (`workable:slug`) is recognised but not enabled yet. Up to Max companies entries.",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "extract",
              "monitor"
            ],
            "type": "string",
            "description": "`extract` is stateless: it reads and writes no state, returns every open job on every run, one snapshot per company computed from that run only (isBaselineRun true; deltas, closures and time-to-fill null) and only rule_match and leadership_hire signals. `monitor` returns every job on the first (baseline) run and afterwards only new jobs plus closures, trends and signals computed from the history kept in the State store.",
            "default": "monitor"
          },
          "emitJobs": {
            "title": "Emit job rows",
            "type": "boolean",
            "description": "Write one dataset row per job (recordType `job`). Turn off to receive only company snapshots and signals.",
            "default": true
          },
          "includeDescription": {
            "title": "Include description text",
            "type": "boolean",
            "description": "Include the plain-text job description in each job row (truncated to Max description characters). Rules on the description field still run when this is off.",
            "default": true
          },
          "maxDescriptionChars": {
            "title": "Max description characters",
            "minimum": 200,
            "maximum": 20000,
            "type": "integer",
            "description": "Truncate descriptionText to this many characters.",
            "default": 4000
          },
          "maxJobsPerCompany": {
            "title": "Max jobs per company",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Hard cap on job rows per company per run. A board that reaches the cap is truncated: its snapshot has capped true and scanComplete false, closure detection and trends are skipped to avoid false closures and surges, and roles that leave the truncated window are dropped from the state after max(2 x Stale after (days), 120) days without a closure.",
            "default": 1000
          },
          "maxCompanies": {
            "title": "Max companies",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "Hard cap on companies processed per run.",
            "default": 500
          },
          "filters": {
            "title": "Job filters",
            "type": "object",
            "description": "Applied to job rows and job-level signals before billing; company snapshots always describe the whole board. Keys: titleKeywords[], excludeTitleKeywords[], functions[] (engineering, sales, marketing, product_design, customer, finance_legal, people, operations, other), seniorities[] (intern, junior, mid, senior, staff, director, executive), countries[] (ISO-2 codes), remoteTypes[] (remote, hybrid, onsite), postedWithinDays (integer). Empty arrays and null mean no filter."
          },
          "staleDays": {
            "title": "Stale after (days)",
            "minimum": 7,
            "maximum": 365,
            "type": "integer",
            "description": "A role open at least this many days (from the ATS first-published date, or the date it was first seen) is flagged stale and counted in staleShare and hardToFillFunctions.",
            "default": 60
          },
          "surgeThresholdPct": {
            "title": "Surge / contraction threshold (%)",
            "minimum": 5,
            "maximum": 500,
            "type": "integer",
            "description": "Percentage change in open roles versus the stored snapshot closest to 30 days ago that raises a hiring_surge (increase) or hiring_contraction (decrease) signal.",
            "default": 25
          },
          "rules": {
            "title": "Signal rules",
            "type": "array",
            "description": "Custom rules evaluated against each job (new jobs only in monitor mode after the baseline). Each item: { id, field: title|description|department|location, pattern: JavaScript regex source (JSON-escaped: write \\\\b for a word boundary, because a single \\b in JSON is a backspace character), flags?: 'i' | 'u' | 'iu' }. Each match emits a `signal` row of type rule_match with the matched snippet as evidence. Invalid patterns produce a rule_error row, never a failed run."
          },
          "signalTypes": {
            "title": "Built-in signal types",
            "uniqueItems": true,
            "type": "array",
            "description": "Which built-in signals to emit. Each fired signal is billed as one `signal` event; nothing is billed when no signal fires.",
            "items": {
              "type": "string",
              "enum": [
                "rule_match",
                "job_closed",
                "stale_role",
                "hiring_surge",
                "hiring_contraction",
                "new_function",
                "new_country",
                "leadership_hire"
              ],
              "enumTitles": [
                "Rule match",
                "Job closed (with days to close)",
                "Stale role",
                "Hiring surge",
                "Hiring contraction",
                "New function hired for",
                "New country hired in",
                "Leadership hire (director+)"
              ]
            },
            "default": [
              "rule_match",
              "job_closed",
              "stale_role",
              "hiring_surge",
              "hiring_contraction",
              "new_function",
              "new_country",
              "leadership_hire"
            ]
          },
          "stateStoreName": {
            "title": "State store name",
            "pattern": "^[a-zA-Z0-9-]{3,63}$",
            "type": "string",
            "description": "Named key-value store (on your account) that keeps per-company history between runs. Use a different name per watchlist, schedule or client.",
            "default": "ats-hiring-radar-state"
          },
          "resetState": {
            "title": "Reset state",
            "type": "boolean",
            "description": "Delete stored history for the listed companies before this run (the run becomes a new baseline for them).",
            "default": false
          },
          "webhookUrl": {
            "title": "Signal webhook URL",
            "pattern": "^https://.+",
            "type": "string",
            "description": "Optional HTTPS endpoint that receives fired signals in batches (JSON array of up to 100 signals) during the run. Bodies are signed with HMAC-SHA256 in the x-hiring-radar-signature header when Webhook secret is set. Apify's own run-finished webhooks remain available as usual."
          },
          "webhookSecret": {
            "title": "Webhook secret",
            "type": "string",
            "description": "Secret used to sign webhook bodies (sha256=<hex HMAC of the raw body>). Leave empty to send unsigned batches."
          },
          "concurrency": {
            "title": "Concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Companies processed in parallel. Lever is always serialised at 1 request per second (its robots.txt asks for Crawl-delay 1); other ATS hosts allow at most 4 concurrent requests.",
            "default": 8
          },
          "debugLog": {
            "title": "Debug logging",
            "type": "boolean",
            "description": "Log every HTTP request with status, size and timing.",
            "default": false
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}