{
  "openapi": "3.0.1",
  "info": {
    "title": "Ashby Jobs API Scraper - Live Job Board Data",
    "description": "Live job postings from the Ashby public job-board API (api.ashbyhq.com posting-api). Job-board names or careers URLs in, one normalized schema out with structured compensation and a remote flag. No scraping, no proxies, no API keys.",
    "version": "0.1",
    "x-build-id": "sl3S2W0DjZT5rOcjx"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/acotr_moonie~ashby-jobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-acotr_moonie-ashby-jobs-scraper",
        "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/acotr_moonie~ashby-jobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-acotr_moonie-ashby-jobs-scraper",
        "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/acotr_moonie~ashby-jobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-acotr_moonie-ashby-jobs-scraper",
        "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": "Ashby job-board names or careers URLs",
            "minItems": 1,
            "maxItems": 2000,
            "uniqueItems": true,
            "type": "array",
            "description": "One per line. An Ashby job-board name (openai) or an Ashby careers URL (https://jobs.ashbyhq.com/openai). The board name is the slug in your jobs.ashbyhq.com URL. An entry for another ATS is refused with a free error row - use the multi-ATS Actor ats-jobs-scraper for those.",
            "items": {
              "type": "string"
            }
          },
          "maxJobs": {
            "title": "Max jobs (total)",
            "minimum": 0,
            "maximum": 200000,
            "type": "integer",
            "description": "Hard stop after this many charged job rows. Your main cost control. Companies not reached before the cap are never charged. Set 0 for no limit.",
            "default": 1000
          },
          "maxJobsPerCompany": {
            "title": "Max jobs per company",
            "minimum": 0,
            "maximum": 20000,
            "type": "integer",
            "description": "Stop after this many jobs from a single company. Useful when one enterprise board would eat the whole budget. Set 0 for no limit.",
            "default": 0
          },
          "titleKeywords": {
            "title": "Title must contain any of",
            "type": "array",
            "description": "Case-insensitive substring match on the job title. Empty = no title filter. Filtering happens before billing, so filtered-out jobs are free.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeTitleKeywords": {
            "title": "Title must NOT contain any of",
            "type": "array",
            "description": "Case-insensitive substring match. Applied after titleKeywords. Example: intern, contract, principal.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "locationKeywords": {
            "title": "Location must contain any of",
            "type": "array",
            "description": "Case-insensitive substring match on the raw location text and on the parsed city, region and country. A two-letter entry is matched exactly against the country code instead, so it cannot hit inside a word. Example: Berlin, Germany, EMEA.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "remoteOnly": {
            "title": "Remote jobs only",
            "type": "boolean",
            "description": "Keep only jobs where remote could be positively determined (remote = true). Jobs with unknown remote status are dropped.",
            "default": false
          },
          "departments": {
            "title": "Departments",
            "type": "array",
            "description": "Case-insensitive substring match on the department or team name as reported by the ATS. Empty = all departments.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "employmentTypes": {
            "title": "Employment types",
            "type": "array",
            "description": "Keep only these normalized employment types. Jobs whose type is unknown are kept unless you also enable strictEmploymentType.",
            "items": {
              "type": "string",
              "enum": [
                "full_time",
                "part_time",
                "contract",
                "temporary",
                "internship",
                "other"
              ],
              "enumTitles": [
                "Full-time",
                "Part-time",
                "Contract",
                "Temporary",
                "Internship",
                "Other"
              ]
            },
            "default": []
          },
          "strictEmploymentType": {
            "title": "Only ATS-confirmed employment types",
            "type": "boolean",
            "description": "Keep only jobs whose employment type came from the ATS itself, dropping both unknowns and types we guessed from the job title. Ashby reports an employment type on most postings, so this filter is usually safe here.",
            "default": false
          },
          "postedAfter": {
            "title": "Posted after",
            "type": "string",
            "description": "Keep only jobs posted at or after this date, e.g. 2026-08-01 or '7 days'. Jobs with no posting date from the ATS are kept and flagged postedAtSource=null."
          },
          "includeDescription": {
            "title": "Include job description",
            "type": "boolean",
            "description": "On by default, at no extra cost: Ashby returns the ad body in the same response we already make, and you are billed per row either way. Makes items about 10x larger - turn it off for a slimmer dataset. The body stays the employer's copyrighted text. Contact details are stripped unless you turn redactContacts off. Executable markup (`<script>`, `<iframe>`, `on*=`, `javascript:`) is removed; the remaining HTML is the employer's own, so render it sandboxed.",
            "default": true
          },
          "descriptionFormat": {
            "title": "Description format",
            "enum": [
              "html",
              "text",
              "both"
            ],
            "type": "string",
            "description": "Only used when includeDescription is on.",
            "default": "text"
          },
          "redactContacts": {
            "title": "Redact contact details from descriptions",
            "type": "boolean",
            "description": "Strip contact details from the ad body: email addresses, phone numbers, LinkedIn/Xing/WhatsApp/Calendly/Telegram links and handles, and a person's name where the ad labels it as a contact (`Ansprechpartner:`, `Kontakt:`, `Contactpersoon:`, `Contact:`, `Hiring manager:`, `Recruiter:`). On by default — EU ads routinely close with a named contact. It does not catch a name in running prose: no label, no pattern. `descriptionRedacted` on each row says whether anything was removed.",
            "default": true
          },
          "outputProfile": {
            "title": "Output profile",
            "enum": [
              "full",
              "compact",
              "minimal"
            ],
            "type": "string",
            "description": "minimal = title, company, location, url, postedAt. compact = minimal plus remote, department, employmentType, salary. full = every field. Use minimal for AI agents to cut token cost.",
            "default": "full"
          },
          "includeCompanySummary": {
            "title": "Add one summary row per company",
            "type": "boolean",
            "description": "Adds a free company_summary row with total jobs found, jobs kept after filters, new jobs, duplicates dropped and top departments. Summary rows are never charged.",
            "default": true
          },
          "includeRawJson": {
            "title": "Include raw ATS payload",
            "type": "boolean",
            "description": "Attach the provider JSON for each job under raw, with contact-shaped fields and ad bodies removed. Large. Useful when you need a field we do not normalize.",
            "default": false
          },
          "dedupe": {
            "title": "Deduplication",
            "enum": [
              "id",
              "content"
            ],
            "type": "string",
            "description": "id = drop repeats of the same ATS job id (always on). content = also merge same title + company + location + requisition id. May merge genuinely separate openings for the same role; leave off unless you see duplicates.",
            "default": "id"
          },
          "onlyNewJobs": {
            "title": "Only jobs not seen in a previous run",
            "type": "boolean",
            "description": "Compares against the ids stored under stateKey in your own named key-value store and outputs only new ones. The first run stores the baseline and outputs everything.",
            "default": false
          },
          "stateKey": {
            "title": "State key",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9-]{2,62}$",
            "type": "string",
            "description": "Name of the key-value store that holds seen job ids for onlyNewJobs. Use a different key per monitoring task. Stored in your account, never sent anywhere.",
            "default": "ashby-jobs-state-default"
          },
          "stateRetentionDays": {
            "title": "Forget job ids after N days",
            "minimum": 0,
            "maximum": 730,
            "type": "integer",
            "description": "Ids not seen for this many days are dropped from the state so it cannot grow forever. 0 keeps everything.",
            "default": 90
          },
          "maxConcurrency": {
            "title": "Max concurrent companies",
            "minimum": 1,
            "maximum": 32,
            "type": "integer",
            "description": "Lower this if Ashby starts rate limiting. Per-host request rate is capped separately at 2 requests per second regardless of this value.",
            "default": 8
          },
          "requestTimeoutSecs": {
            "title": "Request timeout",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "Per HTTP request timeout in seconds.",
            "default": 30
          },
          "failOnAllErrors": {
            "title": "Fail the run if every company failed",
            "type": "boolean",
            "description": "When on, a run where no company returned any job exits with FAILED instead of SUCCEEDED. Useful in scheduled pipelines.",
            "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}