{
  "openapi": "3.0.1",
  "info": {
    "title": "Polish Jobs Aggregator - every portal in one feed",
    "description": "Searches Poland's biggest job boards at once - pracuj.pl, OLX, praca.gov.pl, RocketJobs and optionally justjoin.it — and returns one deduplicated feed with a single schema.",
    "version": "2.0",
    "x-build-id": "ebExqHhsoZlLZ8fZS"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/trev0n~pl-jobs-aggregator/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-trev0n-pl-jobs-aggregator",
        "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/trev0n~pl-jobs-aggregator/runs": {
      "post": {
        "operationId": "runs-sync-trev0n-pl-jobs-aggregator",
        "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/trev0n~pl-jobs-aggregator/run-sync": {
      "post": {
        "operationId": "run-sync-trev0n-pl-jobs-aggregator",
        "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": {
          "keyword": {
            "title": "Keyword",
            "type": "string",
            "description": "What to search for, e.g. \"laborant\", \"kierowca\", \"kontrola jakości\". Searched across every selected portal."
          },
          "keywords": {
            "title": "Keywords (one search each)",
            "type": "array",
            "description": "Several phrases, each run as its own search and merged into one deduplicated feed. Use this for a niche watch, where no single phrase covers the field: [\"technolog\", \"laborant\", \"chemik\", \"kontrola jakości\"]. Overrides \"Keyword\" when set.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "City",
            "type": "string",
            "description": "City name or slug, e.g. \"krakow\" or \"Gdańsk\". Leave empty to search the whole country."
          },
          "radiusKm": {
            "title": "Radius (km)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "How far around the city to look. Honoured by the portals that support a radius; the others match the city itself.",
            "default": 30
          },
          "category": {
            "title": "Category",
            "type": "string",
            "description": "Optional category for the portals that have one, e.g. \"produkcja\", \"logistyka\", \"gastronomia\"."
          },
          "portals": {
            "title": "Portals",
            "type": "array",
            "description": "Which portals to search. Leave empty for all the general boards.",
            "items": {
              "type": "string",
              "enum": [
                "pracuj.pl",
                "praca.gov.pl",
                "rocketjobs.pl",
                "olx.pl",
                "justjoin.it"
              ],
              "enumTitles": [
                "pracuj.pl (largest general board)",
                "praca.gov.pl (government database)",
                "RocketJobs.pl (non-IT)",
                "OLX (local and blue-collar)",
                "justjoin.it (IT only)"
              ]
            },
            "default": []
          },
          "includeItBoards": {
            "title": "Include IT-only boards",
            "type": "boolean",
            "description": "Off by default: for a general search the IT boards are mostly noise.",
            "default": false
          },
          "maxItemsPerPortal": {
            "title": "Max offers per portal",
            "minimum": 1,
            "type": "integer",
            "description": "Each portal is capped separately, so one huge board cannot crowd out the rest.",
            "default": 100
          },
          "extractFullDetails": {
            "title": "Extract full details",
            "type": "boolean",
            "description": "Fetch each offer's page for the full description and the employer's application link. Slower and pricier, but the application link is also the strongest signal for spotting the same offer on two portals.",
            "default": false
          },
          "strictLocation": {
            "title": "Only the requested city",
            "type": "boolean",
            "description": "Drop offers outside the city you asked for. Off by default because most of what a portal adds is the commuter belt (a Warsaw search returns Pruszków, Piaseczno, Grodzisk) and most people want those. Turn it on when you mean the city itself and nothing else.",
            "default": false
          },
          "includeTerms": {
            "title": "Must mention (any of)",
            "type": "array",
            "description": "Keep an offer only if its title, company or description mentions one of these. This is the relevance filter a portal's own search cannot do: it reads the whole text, not just the job title. Diacritics and letter case are ignored.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "includeTermsMode": {
            "title": "Match mode for \"Must mention\"",
            "enum": [
              "any",
              "all"
            ],
            "type": "string",
            "description": "\"any\" keeps an offer that mentions at least one term (right for a list of synonyms). \"all\" demands every term.",
            "default": "any"
          },
          "excludeTerms": {
            "title": "Must NOT mention",
            "type": "array",
            "description": "Drop an offer if its text mentions any of these — the fastest way to kill a recurring false positive (\"praktyki\", \"staż\", \"agencja pracy\", a company you do not want to hear from again).",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeShiftWork": {
            "title": "No shift work",
            "type": "boolean",
            "description": "Drop offers whose schedule the portal reports as shift or night work — including the spelled-out forms (\"dwie zmiany\"), while keeping \"jedna zmiana\". Reads the portals' own schedule fields, never the description, because the description never says. Turning this on also fetches offer details, since praca.gov.pl only ships its schedule field there.",
            "default": false
          },
          "unknownScheduleIsShift": {
            "title": "Also drop offers with no stated schedule",
            "type": "boolean",
            "description": "Strict companion to \"No shift work\": most listings say nothing about the schedule, so this empties the feed considerably. Off by default; survivors are tagged shiftSignal: null so you can see which were never confirmed.",
            "default": false
          },
          "maxAgeDays": {
            "title": "Only offers newer than (days)",
            "minimum": 0,
            "maximum": 365,
            "type": "integer",
            "description": "0 = no age limit. Offers with no publication date are kept, because plenty of portals omit it.",
            "default": 0
          },
          "incremental": {
            "title": "Watch mode — only what changed",
            "type": "boolean",
            "description": "Turns the run into a standing watch. The first run records a baseline; every later run on the same input returns only NEW, UPDATED and REAPPEARED offers. Put it on a schedule and read it like an inbox.",
            "default": false
          },
          "stateKey": {
            "title": "Watch name",
            "type": "string",
            "description": "Optional label for the watch's memory. Leave empty and it is derived from the query and filters, so changing the search starts a fresh baseline instead of silently inheriting the old one."
          },
          "emitUnchanged": {
            "title": "Also return unchanged offers",
            "type": "boolean",
            "description": "Watch mode only. Off by default — the point of a watch is what changed.",
            "default": false
          },
          "emitExpired": {
            "title": "Report offers that disappeared",
            "type": "boolean",
            "description": "Watch mode only. Emits a record with changeType EXPIRED for every offer that was there last run and is gone now.",
            "default": false
          },
          "skipReposts": {
            "title": "Hide reposts",
            "type": "boolean",
            "description": "Watch mode only. An employer re-listing word-for-word the same expired offer is matched by content and suppressed instead of reported as new.",
            "default": false
          },
          "resetState": {
            "title": "Forget the baseline",
            "type": "boolean",
            "description": "Watch mode only. Wipes this watch's memory for one run, so everything counts as new again.",
            "default": false
          },
          "dedupeThreshold": {
            "title": "Duplicate sensitivity",
            "minimum": 0.5,
            "maximum": 1,
            "type": "number",
            "description": "How similar two offers must be to count as one (0.7 merges aggressively, 0.95 barely merges). 0.85 is the tested default.",
            "default": 0.85
          },
          "keepDuplicatesSeparate": {
            "title": "Do not merge duplicates",
            "type": "boolean",
            "description": "Return every portal's copy as its own record. Useful when you want to compare how the same offer is worded across boards.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Used only by the portals that need a proxy — pracuj.pl requires Polish residential IPs (it returns nothing without them) and OLX gets a cheap datacenter IP. The other three boards answer a bare request, so they are never sent through a proxy and never spend your residential traffic. Per-portal control lives in \"portalProxies\"."
          },
          "portalProxies": {
            "title": "Proxy per portal (advanced)",
            "type": "object",
            "description": "Override the proxy for one portal, e.g. {\"pracuj.pl\": {\"useApifyProxy\": true, \"apifyProxyGroups\": [\"RESIDENTIAL\"], \"apifyProxyCountry\": \"PL\"}, \"olx.pl\": null}. `null` disables the proxy for that portal. Residential traffic is the single biggest cost in a run, so this is where to tune it."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}