{
  "openapi": "3.0.1",
  "info": {
    "title": "Hiring Signals & ATS Jobs Scraper — Greenhouse, Lever, Ashby",
    "description": "Hiring signals from company career pages: new, removed and changed roles per company, plus normalized job postings from Greenhouse, Lever, Ashby, SmartRecruiters, Workable, 7 more ATSs, USAJOBS and any careers page with JobPosting markup. Pay per job and signal.",
    "version": "0.3",
    "x-build-id": "LOZPvAJwbNCwPEKut"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/owlabee~job-postings-api/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-owlabee-job-postings-api",
        "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/owlabee~job-postings-api/runs": {
      "post": {
        "operationId": "runs-sync-owlabee-job-postings-api",
        "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/owlabee~job-postings-api/run-sync": {
      "post": {
        "operationId": "run-sync-owlabee-job-postings-api",
        "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": {
          "boards": {
            "title": "Job boards",
            "uniqueItems": true,
            "type": "array",
            "description": "Company job boards to scrape, one per line. Use `provider:boardId` (greenhouse:stripe, lever:spotify, ashby:openai, smartrecruiters:Visa, workable:acme, rippling:acme, gem:acme, breezy:acme, teamtailor:acme, personio:acme, manatal:acme, jobscore:acme), paste the public board URL (boards.greenhouse.io/<token>, job-boards.greenhouse.io/<token>, jobs.lever.co/<company>, jobs.ashbyhq.com/<org>, careers.smartrecruiters.com/<Company>, apply.workable.com/<subdomain>, ats.rippling.com/<slug>/jobs, jobs.gem.com/<slug>, <company>.breezy.hr, <company>.teamtailor.com, <company>.jobs.personio.de, careers-page.com/<slug>, careers.jobscore.com/careers/<company>), or paste the company's own careers URL (for example https://www.example.com/careers): the Actor fetches that page once, detects the Greenhouse, Lever, Ashby, SmartRecruiters or Workable board behind it and scrapes it like any other board. The careers page fetch is charged as one board request; a page with no detectable board becomes one ATS_NOT_DETECTED error item unless `extendedDetection` is on. Also: `usajobs:<agency code>` (for example usajobs:VA) for US federal jobs with your own USAJOBS API key, and `jsonld:<careers URL>` to read a site's schema.org JobPosting markup directly.",
            "items": {
              "type": "string"
            }
          },
          "companyPreset": {
            "title": "Company preset",
            "enum": [
              "ai-labs",
              "developer-tools",
              "fintech"
            ],
            "type": "string",
            "description": "Optional curated list of verified company boards added to `boards` (duplicates by provider and board id are merged): `ai-labs` (AI labs and model companies), `developer-tools` (developer tools and cloud infrastructure) or `fintech` (fintech and crypto). Each list has 50 or more boards verified against the public job-board APIs; the companies and the verification date are listed in the README and docs/presets.md."
          },
          "extendedDetection": {
            "title": "Extended careers-page detection",
            "type": "boolean",
            "description": "Off by default (careers URLs behave exactly as before). When on, a careers URL with no Greenhouse, Lever, Ashby, SmartRecruiters or Workable board is also checked for a Rippling, Gem, Breezy HR, Teamtailor, Personio, Manatal or JobScore board, and if there is none, the site's own schema.org JobPosting markup is read: from the careers page itself, from the job pages it links, or from job URLs in the site's sitemap. robots.txt is honored (a disallowed site becomes a ROBOTS_DISALLOWED error item), pages are fetched one at a time, and job pages are not charged, only the job records they yield (sitemaps are board requests). Workday, Oracle and SuccessFactors sites are not read.",
            "default": false
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "jobs",
              "signals"
            ],
            "type": "string",
            "description": "`jobs` writes one normalized record per open job. `signals` compares each board with its previous snapshot (stored in the key-value store named below) and writes new-role, removed-role, title-changed and location-changed records plus one per-board summary. The first signals run for a board is a baseline and writes job records instead.",
            "default": "jobs"
          },
          "includeDescription": {
            "title": "Include job description",
            "type": "boolean",
            "description": "Add `descriptionText` (HTML converted to plain text, trimmed to 3,000 characters). Greenhouse, Lever, Ashby, Gem, Teamtailor, Personio, Manatal, JobScore, USAJOBS and JobPosting markup return descriptions in the same request; SmartRecruiters and Workable need one extra request per job, so large boards take longer. Rippling and Breezy HR listings carry no description.",
            "default": false
          },
          "maxJobsPerBoard": {
            "title": "Max jobs per board",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "Upper bound on job records (and snapshot size) per board. Boards that exceed it are marked `truncated` and removed-role signals are suppressed for them so a partial fetch never looks like mass closures.",
            "default": 2000
          },
          "stateStoreName": {
            "title": "State store name",
            "pattern": "^[a-zA-Z0-9-]{1,63}$",
            "type": "string",
            "description": "Named key-value store that holds the previous snapshot of each board for signals mode. Use a different name per schedule or customer to keep baselines separate.",
            "default": "ats-hiring-signals-state"
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "pattern": "^https?://.+",
            "type": "string",
            "description": "If set, the Actor POSTs one JSON payload at the end of the run with per-board summaries and counts. Delivery failures are logged, never fatal."
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many boards are fetched in parallel. Requests to the same provider host are additionally rate-limited to about 2 per second.",
            "default": 5
          },
          "maxSecondsPerBoard": {
            "title": "Max seconds per board",
            "minimum": 30,
            "maximum": 3600,
            "type": "integer",
            "description": "Time budget for one board (all pages and detail requests). A board that has produced nothing for 60 seconds, or uses up this budget, is cut off: the jobs already fetched are kept and the board is marked truncated (TIME_BUDGET); with nothing fetched it becomes one error item.",
            "default": 900
          },
          "usajobsApiKey": {
            "title": "USAJOBS API key",
            "type": "string",
            "description": "Your own free USAJOBS Search API key (request one at developer.usajobs.gov), needed only for `usajobs:<agency code>` boards. It is sent only to data.usajobs.gov in the Authorization-Key header, never logged or written to the output. OPM's terms do not allow sharing a key, so the Actor never ships one."
          },
          "usajobsEmail": {
            "title": "USAJOBS registration email",
            "pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$",
            "type": "string",
            "description": "The email address your USAJOBS API key was registered with. USAJOBS requires it as the User-Agent of every request; it is sent only to data.usajobs.gov."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}