{
  "openapi": "3.0.1",
  "info": {
    "title": "Remote Jobs Scraper - Employer-Direct, No Job-Board Reposts",
    "description": "Remote postings read straight from employer boards on Greenhouse, Lever, Ashby, Recruitee and Workable, not job-board reposts. Remote is location-inferred on Greenhouse. New-since-last-run diff.",
    "version": "1.0",
    "x-build-id": "goZRSVkq2MgOqox5c"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/maydit~remote-jobs-employer-direct/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-maydit-remote-jobs-employer-direct",
        "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/maydit~remote-jobs-employer-direct/runs": {
      "post": {
        "operationId": "runs-sync-maydit-remote-jobs-employer-direct",
        "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/maydit~remote-jobs-employer-direct/run-sync": {
      "post": {
        "operationId": "run-sync-maydit-remote-jobs-employer-direct",
        "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": {
          "preset": {
            "title": "Company preset",
            "enum": [
              "remote-first",
              "none"
            ],
            "type": "string",
            "description": "'remote-first' scrapes a built-in list of 70 employer boards that were majority-remote when last verified (2026-09-25): every board had at least 5 remote postings and remote postings were at least half of its open roles. The list is in the README. The preset is used only when 'companies' and the per-platform lists are empty - listing companies replaces it. Choose 'none' when you pass your own companies and want an error rather than the preset if the list is empty.",
            "default": "remote-first"
          },
          "companies": {
            "title": "Companies (platform auto-detected)",
            "type": "array",
            "description": "Company slugs to scrape, one per line. The slug is the path segment of the employer's board URL: job-boards.greenhouse.io/<slug>, jobs.lever.co/<slug>, jobs.ashbyhq.com/<slug>, <slug>.recruitee.com or apply.workable.com/<slug>. Each slug is tried on Greenhouse, Lever, Ashby, Recruitee and Workable in that order and the first board found is used. Slugs are case-insensitive. A slug with no board on any platform is reported and skipped. When you fill this in, the preset is not added.",
            "items": {
              "type": "string"
            }
          },
          "greenhouse": {
            "title": "Greenhouse boards",
            "type": "array",
            "description": "Board tokens to read from Greenhouse only, skipping detection (e.g. 'gitlab'). Remote on Greenhouse is always inferred from the location text, because the platform publishes no workplace field.",
            "items": {
              "type": "string"
            }
          },
          "lever": {
            "title": "Lever boards",
            "type": "array",
            "description": "Company slugs to read from Lever only (e.g. 'toptal'). Lever publishes a workplaceType per posting (remote / hybrid / onsite / unspecified).",
            "items": {
              "type": "string"
            }
          },
          "ashby": {
            "title": "Ashby boards",
            "type": "array",
            "description": "Board names to read from Ashby only (e.g. 'zapier'). Ashby publishes a workplaceType per posting (Remote / Hybrid / OnSite) but many employers leave it blank, in which case the location text decides.",
            "items": {
              "type": "string"
            }
          },
          "recruitee": {
            "title": "Recruitee boards",
            "type": "array",
            "description": "Subdomains to read from Recruitee only (e.g. 'timedoctor' for timedoctor.recruitee.com). Recruitee publishes remote / hybrid / on-site flags per posting.",
            "items": {
              "type": "string"
            }
          },
          "workable": {
            "title": "Workable accounts",
            "type": "array",
            "description": "Account names to read from Workable only (e.g. 'zyte' for apply.workable.com/zyte). Workable publishes a 'telecommuting' yes/no per posting and nothing that separates hybrid from on-site; postings without the flag are checked against their location text. Workable enforces a per-IP daily quota (HTTP 429 with a Retry-After of about 24 hours), so a board here can fail in one run and work in the next; such a board is named in SUMMARY.failedSources and the rest of the run continues. That is why no Workable board is in the preset.",
            "items": {
              "type": "string"
            }
          },
          "titleContains": {
            "title": "Job title contains",
            "type": "string",
            "description": "Optional. Keep only postings whose title contains this text (case-insensitive, partial match), for example 'engineer' or 'account executive'. Applied after the remote rule."
          },
          "strictRemote": {
            "title": "Strict remote (drop hybrid/on-site even if the location text says remote)",
            "type": "boolean",
            "description": "On (default): when the platform publishes a workplace type and it is Hybrid or OnSite, the posting is dropped even if its location text says 'Remote'. Off: such a posting is kept and marked remoteBasis 'location-text'. Postings with no workplace type at all (every Greenhouse posting, and many Ashby ones) are decided by their location text either way.",
            "default": true
          },
          "onlyWithSalary": {
            "title": "Only postings with a published salary range",
            "type": "boolean",
            "description": "Keep only postings where the platform returned a structured salary (salaryMin or salaryMax). Lever, Ashby and Recruitee publish one when the employer fills it in; Greenhouse and Workable never do, so this drops every Greenhouse and Workable row. On the default preset run of 2026-09-25, 12% of the 800 rows carried a salary.",
            "default": false
          },
          "postedWithinDays": {
            "title": "Posted within the last N days",
            "minimum": 1,
            "type": "integer",
            "description": "Optional. Keep only postings whose postedAt is within the last N days. Rows are always sorted newest first, so this simply trims the tail. Leave empty for no date filter."
          },
          "includeDescription": {
            "title": "Include full job description",
            "type": "boolean",
            "description": "Add a 'description' column with the posting text as clean plain text (HTML unescaped and stripped, list items kept as '- ' bullets, capped at 20,000 characters). Off by default because it multiplies the dataset size.",
            "default": false
          },
          "maxResultsPerCompany": {
            "title": "Max postings per company",
            "minimum": 1,
            "type": "integer",
            "description": "Upper bound on remote postings kept from any one board, newest first. Every board is fetched in one request regardless, so this only shapes the output.",
            "default": 100
          },
          "maxResults": {
            "title": "Max postings in total",
            "minimum": 1,
            "type": "integer",
            "description": "Upper bound on rows in the dataset. Postings from every company are merged and sorted newest first before this cap applies, so a capped run is the freshest N remote postings across the whole list, not the first few companies. The default preset had 3,292 remote postings on 2026-09-25, so the default of 800 returns the newest 800 of them; raise it for the full list.",
            "default": 800
          },
          "onlyNewSinceLastRun": {
            "title": "Only postings new since the last run",
            "type": "boolean",
            "description": "Save only remote postings this Actor has not seen before. The job IDs of every remote posting on each board are recorded in a named key-value store ('remote-jobs-employer-direct-state') and compared on the next run with this option on. The FIRST run has no baseline, so it returns every posting and records the baseline (the log says so); from the second run on you get only new ones. A run with nothing new finishes successfully with an empty dataset. Do not enable this on a run you expect to return rows every time.",
            "default": false
          },
          "maxRunSeconds": {
            "title": "Max run seconds",
            "minimum": 30,
            "type": "integer",
            "description": "Wall-clock budget for fetching boards. When it is reached the Actor stops cleanly, keeps everything already collected, and names the companies it did not reach - instead of being killed with a failed run. The default preset finishes in well under a minute; raise this only for very long custom lists.",
            "default": 240
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}