{
  "openapi": "3.0.1",
  "info": {
    "title": "Intermediair Scraper: Every Vacancy Gets a Real Salary Estimate",
    "description": "Scrapes Intermediair.nl job vacancies (title, company, location, contract, description) and adds a real salary to every one: employer-disclosed, or a sourced market estimate when pay isn't listed. Standalone salary-intelligence dataset. 5-state monitor mode for tracking searches. No login needed.",
    "version": "0.1",
    "x-build-id": "6aM0MoXTZzhhBydvv"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/getascraper~intermediair-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-getascraper-intermediair-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/getascraper~intermediair-scraper/runs": {
      "post": {
        "operationId": "runs-sync-getascraper-intermediair-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/getascraper~intermediair-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-getascraper-intermediair-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",
        "properties": {
          "keywords": {
            "title": "Job Title Keywords",
            "type": "array",
            "description": "Job titles to search for, e.g. \"Data Engineer\" or \"Product Owner\". Each keyword is matched against Intermediair's own job-title browse pages, so a keyword close to a real Dutch job title works best.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "vacancyUrls": {
            "title": "Vacancy URLs",
            "type": "array",
            "description": "Direct links to specific Intermediair vacancy pages to scrape, bypassing search entirely. Useful for re-checking known listings or tracking a saved shortlist over time.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "city": {
            "title": "City",
            "type": "string",
            "description": "Only show vacancies in and around this Dutch city, e.g. \"Amsterdam\" or \"Rotterdam\". Leave blank to search all locations.",
            "default": ""
          },
          "radiusKm": {
            "title": "City Radius (km)",
            "minimum": 5,
            "maximum": 200,
            "type": "integer",
            "description": "How far from the chosen city to include vacancies. This mirrors Intermediair's own default catchment area for a city search (40 km) rather than a separately tunable site parameter, so changing it has no effect unless a city is also set.",
            "default": 40
          },
          "contractType": {
            "title": "Contract Type",
            "type": "string",
            "description": "Only keep vacancies with this contract type, e.g. \"Vast\" (permanent) or \"Tijdelijk\" (temporary). Matched against each vacancy's own listed contract type after it is scraped, so it can be combined freely with the other filters below.",
            "default": ""
          },
          "educationLevel": {
            "title": "Education Level",
            "type": "string",
            "description": "Only keep vacancies requiring this education level, e.g. \"WO\" (university), \"HBO\" (applied sciences), or \"MBO\". Matched against each vacancy's own listed education requirement.",
            "default": ""
          },
          "careerLevel": {
            "title": "Career Level",
            "type": "string",
            "description": "Only keep vacancies at this career level, e.g. \"Starter\" or \"Ervaren\" (experienced). Matched against each vacancy's own listed career level.",
            "default": ""
          },
          "industry": {
            "title": "Industry",
            "type": "string",
            "description": "Which Intermediair industry category to browse, e.g. \"ict\", \"finance\", or \"zorg\". This is the Actor's main discovery seed when no keywords are given, so it defaults to \"ict\" to keep a first run fast and populated with real vacancies.",
            "default": "ict"
          },
          "province": {
            "title": "Province",
            "type": "string",
            "description": "Only show vacancies in this Dutch province, e.g. \"Noord-Holland\" or \"Utrecht\". Leave blank to search all provinces.",
            "default": ""
          },
          "workingPlace": {
            "title": "Working Arrangement",
            "enum": [
              "",
              "remote",
              "hybrid",
              "on-site"
            ],
            "type": "string",
            "description": "Best-effort keyword match for \"remote\", \"hybrid\", or \"on-site\" against the vacancy's own description text. Intermediair does not expose working arrangement as a structured filter anywhere on the site, so this is a text heuristic, not a precise site-side filter, and some genuinely-matching vacancies may be missed if the posting does not spell it out.",
            "default": ""
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Residential proxy by default: browser-TLS impersonation alone clears the target's Akamai/DPG Media WAF over a direct connection, but a real Apify Cloud run confirmed Apify's own datacenter proxy IPs get silently timed out by the same WAF, while residential IPs work reliably.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "includeDetails": {
            "title": "Fetch Full Vacancy Detail Pages",
            "type": "boolean",
            "description": "Re-fetches each vacancy's own dedicated page for the most authoritative, cross-checked record. Off by default because the search results already carry the full job description server-rendered, so this mainly matters if you want an extra completeness guarantee at the cost of one additional request per vacancy.",
            "default": false
          },
          "includeSalaryIntelligence": {
            "title": "Add Market-Rate Salary Estimates",
            "type": "boolean",
            "description": "Fetches Intermediair's own salary-intelligence pages (national average, per-company pay, per-city pay, and year-over-year trend for each job title) and attaches a sourced market-rate salary estimate to every vacancy that did not disclose its own salary. This is the Actor's core value: on its own, Intermediair only shows a real salary figure on roughly half to two-thirds of postings. Kept on by default because it is cheap (a handful of role-level page fetches per run, not one per vacancy) and is what makes every row usable for pay comparison.",
            "default": true
          },
          "maxItems": {
            "title": "Max Vacancies",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "The maximum number of vacancies to return in this run. Kept modest by default so a first run finishes quickly; raise it once you know the search returns what you expect.",
            "default": 20
          },
          "onlyChangedListings": {
            "title": "Only Return Changed Listings",
            "type": "boolean",
            "description": "When enabled, vacancies that are identical to the last run (UNCHANGED) are left out of the output entirely, so you only see what actually moved: NEW, UPDATED, REAPPEARED, or EXPIRED listings. Intended for scheduled monitoring runs rather than one-off searches.",
            "default": false
          },
          "stateName": {
            "title": "Monitor State Name",
            "type": "string",
            "description": "Names the saved tracking state for this search, so you can run several independent monitors (e.g. one per keyword or city) without them overwriting each other's history. Reuse the same name across scheduled runs of the same search to keep its change history intact.",
            "default": "default"
          },
          "resetState": {
            "title": "Reset Monitor State",
            "type": "boolean",
            "description": "Clears the saved tracking history for this state name before this run, so every vacancy found is reported as NEW again. Use this once if a saved search's history needs a clean restart; leave off for normal scheduled runs.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}