{
  "openapi": "3.0.1",
  "info": {
    "title": "Duunitori Jobs Scraper",
    "description": "[💰 $1.80 / 1K] Extract job listings from Duunitori, Finland's largest job board. Search by keyword, location, category, employment type, remote work, and ad language, or paste search and job-ad URLs. Returns title, company, location, salary, dates, description, and apply link — one row per job.",
    "version": "1.0",
    "x-build-id": "peVXMAXgckXrsCZ6a"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/solidcode~duunitori-fi-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-solidcode-duunitori-fi-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/solidcode~duunitori-fi-scraper/runs": {
      "post": {
        "operationId": "runs-sync-solidcode-duunitori-fi-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/solidcode~duunitori-fi-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-solidcode-duunitori-fi-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": {
          "searchQueries": {
            "title": "Search Keywords",
            "maxItems": 50,
            "type": "array",
            "description": "Job titles or keywords to search for, such as 'ohjelmistokehittäjä', 'myyjä', or 'sairaanhoitaja'. Each keyword runs its own search. Leave empty to collect the broadest result set for the chosen location and filters. Up to 50 keywords per run.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Location",
            "type": "string",
            "description": "City or region in Finland to search in, such as 'Helsinki', 'Tampere', 'Turku', or 'Oulu'. Matches what you would type into Duunitori's location box. Leave empty to search the whole country. Applies to every search keyword."
          },
          "startUrls": {
            "title": "Direct Duunitori URLs",
            "maxItems": 50,
            "type": "array",
            "description": "Paste full Duunitori URLs to scrape them directly. Two kinds work: a search-result page (e.g. https://duunitori.fi/tyopaikat?haku=ohjelmistokehittaja&alue=Helsinki), where any filters baked into the URL are respected as-is, and a single job ad (e.g. https://duunitori.fi/tyopaikat/tyo/myyja-helsinki-12345678), which returns just that one job. Location and employer pages work too. You can mix both kinds in one run. Job-ad rows carry every field a search result does except the ad's own Job Field tag, which Duunitori publishes only on search pages. Up to 50 URLs per run.",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "Job Category",
            "enum": [
              "",
              "asennus, huolto ja kunnossapito (ala)",
              "asiakaspalvelu (ala)",
              "asiantuntijatyöt ja konsultointi (ala)",
              "hallinto ja yleiset toimistotyöt (ala)",
              "henkilöstöala (ala)",
              "hyvinvointi- ja henkilöpalvelut (ala)",
              "johtotehtävät (ala)",
              "julkinen sektori ja järjestöt (ala)",
              "kiinteistöala (ala)",
              "kuljetus, logistiikka ja liikenne (ala)",
              "kulttuuri-, viihde- ja taidealat (ala)",
              "lakiala (ala)",
              "markkinointi (ala)",
              "markkinointi, mainonta, media ja viestintä (ala)",
              "myynti- ja kaupan ala (ala)",
              "opetusala (ala)",
              "opiskelijoiden työpaikat (ala)",
              "rakennusala (ala)",
              "ravintola- ja matkailuala (ala)",
              "siivous, puhtaanapito ja jätehuolto (ala)",
              "sosiaali- ja hoiva-ala (ala)",
              "taloushallinto ja pankkiala (ala)",
              "teollisuus ja teknologia (ala)",
              "terveydenhuoltoala (ala)"
            ],
            "type": "string",
            "description": "Limit results to one Duunitori job field. Leave on 'Any' to include all categories.",
            "default": ""
          },
          "employmentType": {
            "title": "Employment Type",
            "enum": [
              "",
              "full_time",
              "part_time"
            ],
            "type": "string",
            "description": "Full-time or part-time. Leave on 'Any' to include both.",
            "default": ""
          },
          "contractType": {
            "title": "Contract Type",
            "enum": [
              "",
              "permanent",
              "fixed_term",
              "summer_job"
            ],
            "type": "string",
            "description": "Permanent, fixed-term, or summer job. Leave on 'Any' to include all.",
            "default": ""
          },
          "remoteOnly": {
            "title": "Remote Only",
            "type": "boolean",
            "description": "Only return jobs that can be done remotely. Leave off to include on-site and hybrid roles too.",
            "default": false
          },
          "language": {
            "title": "Ad Language",
            "enum": [
              "",
              "fi_lang",
              "swe_lang",
              "eng_lang"
            ],
            "type": "string",
            "description": "Only return job ads written in this language. Leave on 'Any' to include all languages.",
            "default": ""
          },
          "searchDescriptions": {
            "title": "Also Search Ad Text",
            "type": "boolean",
            "description": "Also match your keywords inside the full job-ad text, not just the title. Broadens results — turn on when a keyword returns too few jobs.",
            "default": false
          },
          "sortBy": {
            "title": "Sort By",
            "enum": [
              "relevance",
              "date"
            ],
            "type": "string",
            "description": "Order results by best match or by newest first.",
            "default": "relevance"
          },
          "maxResults": {
            "title": "Maximum Results",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of job listings to collect across all keywords and URLs. Set to 0 to collect all available results (an internal upper bound still applies to prevent runaway pagination). Duunitori serves 20 listings per page. A cap below 20 is exact: ask for 5 and you get exactly 5. From 20 upwards the actor stops requesting pages once your cap is reached but keeps the whole final page, so a run can finish with up to 19 more results than you asked for (a cap of 100 can return up to 119). Jobs repeated across pages are deduplicated, so the final count can also run slightly below your cap.",
            "default": 100
          },
          "onlyUniqueJobs": {
            "title": "Only Unique Jobs",
            "type": "boolean",
            "description": "When on, each job is returned once even if Duunitori lists it across several pages or searches. Deduplicates by the listing's job ID. Turn off to keep every copy.",
            "default": true
          },
          "fetchDescription": {
            "title": "Fetch Full Job Descriptions",
            "type": "boolean",
            "description": "Fetch the full job description, salary, employment details, expiry date, and apply link from each job's detail page. Leave on for the most complete data. Turn off for lighter, faster records when you only need titles, companies, locations, and links from the results list.",
            "default": true
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}