{
  "openapi": "3.0.1",
  "info": {
    "title": "ATS Jobs API: Greenhouse, Lever, Ashby & More",
    "description": "Live open jobs straight from 7 ATS public job-board APIs (Greenhouse, Lever, Ashby, SmartRecruiters, Workable, Recruitee, Personio). Normalized schema, salary from structured fields, and new/closed job tracking between runs. No scraping, no proxies.",
    "version": "0.2",
    "x-build-id": "oa6m8lAPqLUiGGZuO"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/foresighted_sunset~ats-jobs-api/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-foresighted_sunset-ats-jobs-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/foresighted_sunset~ats-jobs-api/runs": {
      "post": {
        "operationId": "runs-sync-foresighted_sunset-ats-jobs-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/foresighted_sunset~ats-jobs-api/run-sync": {
      "post": {
        "operationId": "run-sync-foresighted_sunset-ats-jobs-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": {
          "companies": {
            "title": "Companies (careers URLs, websites or ats:token)",
            "type": "array",
            "description": "One per line. Careers URLs are auto-detected (https://jobs.lever.co/spotify, https://boards.greenhouse.io/airbnb, https://jobs.ashbyhq.com/ramp, https://apply.workable.com/skroutz, https://bunq.recruitee.com, https://ottonova.jobs.personio.de, https://jobs.smartrecruiters.com/BoschGroup). Or use ats:token (greenhouse:stripe, lever:eu/acme, ashby:ramp, smartrecruiters:BoschGroup, workable:skroutz, recruitee:bunq, personio:ottonova). A bare token (stripe) is probed across all supported ATS. A company website or custom careers page (acme.com, careers.acme.com) is fetched politely (robots.txt respected) to find the ATS embed, following up to 2 careers links. Add |Name to set the company name: lever:spotify|Spotify. Leave empty and set a dataset below to enrich rows from another Actor. With no companies and no dataset, a 3-company demo runs.",
            "items": {
              "type": "string"
            }
          },
          "outputLevel": {
            "title": "Output level",
            "enum": [
              "jobs",
              "companies"
            ],
            "type": "string",
            "description": "\"companies\" gives one hiring-signal row per company: open jobs, posted in last 30 days, departments, locations, remote and salary share, salary span, median days open, ghost-job counts, and new/closed since last run. Defaults to \"companies\" when a dataset is enriched, otherwise \"jobs\"."
          },
          "datasetId": {
            "title": "Enrich a dataset (dataset ID)",
            "type": "string",
            "description": "ID of an Apify dataset whose rows contain a company website, domain or careers URL (e.g. the output of a Google Maps, lead or company-list Actor). Each row gets the company's ATS and hiring signals. Rows without a usable field are skipped and counted in OUTPUT."
          },
          "companyFields": {
            "title": "Company field(s)",
            "type": "array",
            "description": "Field(s) holding the website, domain or careers URL, checked in order (dot paths allowed, e.g. company.website). Empty = auto: careersUrl, jobsUrl, website, websiteUrl, companyWebsite, domain, url…",
            "items": {
              "type": "string"
            }
          },
          "passthroughFields": {
            "title": "Fields to copy from each row",
            "type": "array",
            "description": "Copied into inputRow on each output row so you can join results back. Empty = the field used plus name/title/id/placeId/domain/website when present.",
            "items": {
              "type": "string"
            }
          },
          "enrichItems": {
            "title": "Rows to enrich (JSON, optional)",
            "type": "array",
            "description": "Instead of a dataset, paste rows directly, e.g. [{\"name\":\"Acme\",\"website\":\"https://acme.com\"}]."
          },
          "maxEnrichRows": {
            "title": "Max rows to enrich",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "Rows read from the dataset. Duplicate companies are looked up once.",
            "default": 1000
          },
          "includeNotFoundRows": {
            "title": "Output rows with no ATS found",
            "type": "boolean",
            "description": "Company level only. When off, companies with no supported ATS are listed in OUTPUT only (not in the dataset).",
            "default": false
          },
          "followCareersLinks": {
            "title": "Follow careers links on websites",
            "type": "boolean",
            "description": "When a website has no ATS embed, open up to 2 careers/jobs links on the same site (or /careers and /jobs). robots.txt is respected for every page.",
            "default": true
          },
          "keywords": {
            "title": "Keywords (any)",
            "type": "array",
            "description": "Keep jobs whose title contains any of these (case-insensitive).",
            "items": {
              "type": "string"
            }
          },
          "keywordsInDescription": {
            "title": "Also match keywords in description",
            "type": "boolean",
            "description": "Search the job description too (SmartRecruiters descriptions are not available for filtering).",
            "default": false
          },
          "excludeKeywords": {
            "title": "Exclude title keywords",
            "type": "array",
            "description": "Drop jobs whose title contains any of these, e.g. senior, intern.",
            "items": {
              "type": "string"
            }
          },
          "locations": {
            "title": "Locations (any)",
            "type": "array",
            "description": "Substring match on locations or ISO country codes, e.g. Berlin, Germany, US. Use \"remote\" to also accept remote jobs.",
            "items": {
              "type": "string"
            }
          },
          "remoteOnly": {
            "title": "Remote only",
            "type": "boolean",
            "description": "Keep only jobs marked remote by the ATS or with Remote in their location.",
            "default": false
          },
          "workplaceTypes": {
            "title": "Workplace types",
            "type": "array",
            "description": "Any of: remote, hybrid, onsite, unknown.",
            "items": {
              "type": "string"
            }
          },
          "departments": {
            "title": "Departments / teams (any)",
            "type": "array",
            "description": "Substring match on department or team, e.g. Engineering, Sales.",
            "items": {
              "type": "string"
            }
          },
          "employmentTypes": {
            "title": "Employment types",
            "type": "array",
            "description": "Any of: full_time, part_time, contract, intern, temporary, other, unknown.",
            "items": {
              "type": "string"
            }
          },
          "postedAfter": {
            "title": "Posted after",
            "type": "string",
            "description": "A date (2026-10-01) or relative (24 hours, 7 days, 2 weeks, 1 month). Uses the posted date, or the updated date when the ATS does not expose one."
          },
          "maxGhostScore": {
            "title": "Max ghost-job score",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Drop jobs whose ghost-job score is above this (e.g. 49 keeps low and medium risk). 0 = keep all.",
            "default": 0
          },
          "outputMode": {
            "title": "Output",
            "enum": [
              "all",
              "new",
              "changes"
            ],
            "type": "string",
            "description": "\"new\" and \"changes\" need tracking. On the first run for a company a baseline is saved and nothing is flagged new.",
            "default": "all"
          },
          "trackChanges": {
            "title": "Track new / closed jobs (hiring velocity)",
            "type": "boolean",
            "description": "Remember first-seen and last-seen per job in a named key-value store, so each run flags new and closed jobs and reports per-company opened/closed/net counts in OUTPUT.",
            "default": true
          },
          "includeClosedJobs": {
            "title": "Include closed jobs in \"All\" output",
            "type": "boolean",
            "description": "Add a status=closed item for each job that disappeared since the last run.",
            "default": true
          },
          "stateStoreName": {
            "title": "Tracking store name",
            "type": "string",
            "description": "Named key-value store that keeps tracking state. Use different names for independent watchlists.",
            "default": "ats-jobs-tracker"
          },
          "descriptionFormat": {
            "title": "Description",
            "enum": [
              "text",
              "html",
              "both",
              "none"
            ],
            "type": "string",
            "description": "SmartRecruiters needs one extra request per output job for descriptions; choose None to skip.",
            "default": "text"
          },
          "maxJobsPerCompany": {
            "title": "Max jobs per company",
            "minimum": 0,
            "type": "integer",
            "description": "Cap on output jobs per company (newest first). 0 = no cap. Tracking always uses the full board.",
            "default": 100
          },
          "maxJobs": {
            "title": "Max jobs total",
            "minimum": 0,
            "type": "integer",
            "description": "Cap on total output jobs. 0 = no cap.",
            "default": 0
          },
          "ghostScore": {
            "title": "Ghost-job score",
            "type": "boolean",
            "description": "Score every open job 0-100 for ghost/stale risk from transparent signals (age, posted-date refresh, repost of a closed role, evergreen/talent-pool wording, duplicate postings, no pay range in a pay-transparency state, thin description, stagnant board). Each job lists the signals and points. A heuristic, not proof.",
            "default": true
          },
          "parseSalaryFromText": {
            "title": "Parse salary from description text",
            "type": "boolean",
            "description": "When the ATS has no structured salary, extract a clear currency range from the description (e.g. \"$120,000 - $150,000\"). The matched text is kept in salary.text.",
            "default": true
          },
          "greenhouseSalaries": {
            "title": "Greenhouse: fetch pay ranges",
            "type": "boolean",
            "description": "One extra request per output Greenhouse job to read pay_input_ranges (structured pay transparency). Slower on big boards.",
            "default": false
          },
          "personioLanguage": {
            "title": "Personio feed language",
            "type": "string",
            "description": "Optional language code for Personio feeds, e.g. en or de."
          },
          "smartRecruitersMaxPages": {
            "title": "SmartRecruiters max pages (100 jobs each)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Large employers can have thousands of postings. If a board is not fully fetched, closed-job detection is skipped for it.",
            "default": 50
          },
          "probeBareTokens": {
            "title": "Probe bare tokens across ATS",
            "type": "boolean",
            "description": "For entries like \"stripe\", try each supported ATS until a board is found (up to 7 requests).",
            "default": true
          },
          "maxConcurrency": {
            "title": "Companies in parallel",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many company boards are processed at the same time.",
            "default": 5
          },
          "perHostConcurrency": {
            "title": "Parallel requests per ATS host",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keeps load on each ATS API low.",
            "default": 2
          },
          "minRequestGapMs": {
            "title": "Min gap between requests to one host (ms)",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "Polite pacing per ATS host.",
            "default": 250
          },
          "maxRetries": {
            "title": "Max retries",
            "minimum": 0,
            "maximum": 8,
            "type": "integer",
            "description": "Retries on 429, 5xx and network errors with exponential backoff (honors 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}