{
  "openapi": "3.0.1",
  "info": {
    "title": "JobStreet Scraper - Jobs, Salaries, Companies & Apply Details",
    "description": "From $1/1K. Scrape JobStreet listings across Malaysia, Singapore, Indonesia, and the Philippines. Extract titles, companies, salaries, locations, descriptions, company info, and apply details. Search with filters or paste JobStreet URLs directly. Fast and cost-efficient.",
    "version": "1.0",
    "x-build-id": "sdZwfHfHSnn92xksz"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~jobstreet-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-jobstreet-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/abotapi~jobstreet-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-jobstreet-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/abotapi~jobstreet-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-jobstreet-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": {
          "country": {
            "title": "Country",
            "enum": [
              "MY",
              "SG",
              "PH",
              "ID"
            ],
            "type": "string",
            "description": "Country market to search. MY = my.jobstreet.com, SG = sg.jobstreet.com, PH = ph.jobstreet.com, ID = id.jobstreet.com.",
            "default": "MY"
          },
          "keywords": {
            "title": "Keywords",
            "type": "string",
            "description": "Job title or keywords (e.g. 'software engineer'). Leave empty to match all jobs in the location."
          },
          "location": {
            "title": "Location",
            "type": "string",
            "description": "Where to search within the country. Examples: 'Kuala Lumpur', 'Selangor', 'Singapore', 'Metro Manila', 'Jakarta Raya'. Leave empty to search the whole country."
          },
          "classification": {
            "title": "Classification",
            "type": "array",
            "description": "Filter by one or more top-level job categories. Leave empty for all. Subclassifications can still be used via URL mode.",
            "items": {
              "type": "string",
              "enum": [
                "1200",
                "6251",
                "6304",
                "1203",
                "1204",
                "7019",
                "6163",
                "1206",
                "6076",
                "6263",
                "6123",
                "1209",
                "6205",
                "1210",
                "1211",
                "1212",
                "6317",
                "6281",
                "1214",
                "1216",
                "6092",
                "6008",
                "6058",
                "1220",
                "6043",
                "6362",
                "1223",
                "6261",
                "6246",
                "1225"
              ],
              "enumTitles": [
                "Accounting",
                "Administration & Office Support",
                "Advertising, Arts & Media",
                "Banking & Financial Services",
                "Call Centre & Customer Service",
                "CEO & General Management",
                "Community Services & Development",
                "Construction",
                "Consulting & Strategy",
                "Design & Architecture",
                "Education & Training",
                "Engineering",
                "Farming, Animals & Conservation",
                "Government & Defence",
                "Healthcare & Medical",
                "Hospitality & Tourism",
                "Human Resources & Recruitment",
                "Information & Communication Technology",
                "Insurance & Superannuation",
                "Legal",
                "Manufacturing, Transport & Logistics",
                "Marketing & Communications",
                "Mining, Resources & Energy",
                "Real Estate & Property",
                "Retail & Consumer Products",
                "Sales",
                "Science & Technology",
                "Self Employment",
                "Sport & Recreation",
                "Trades & Services"
              ]
            },
            "default": []
          },
          "workType": {
            "title": "Work type",
            "type": "array",
            "description": "Filter by one or more work types. Leave empty for all.",
            "items": {
              "type": "string",
              "enum": [
                "242",
                "243",
                "244",
                "245"
              ],
              "enumTitles": [
                "Full time",
                "Part time",
                "Contract / Temp",
                "Casual / Vacation"
              ]
            },
            "default": []
          },
          "workArrangement": {
            "title": "Work arrangement",
            "type": "array",
            "description": "Filter by on-site, hybrid or remote. Leave empty for all. Ignored in URL mode (put workarrangement in the URL instead).",
            "items": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3"
              ],
              "enumTitles": [
                "On-site",
                "Hybrid",
                "Remote"
              ]
            },
            "default": []
          },
          "subClassification": {
            "title": "Sub-category IDs",
            "type": "array",
            "description": "Narrow to sub-categories by numeric ID (e.g. 6028 = Electrical/Electronic Engineering, shown in the output as subCategoryId). Use together with a category. Ignored in URL mode.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "salaryMin": {
            "title": "Minimum salary",
            "type": "integer",
            "description": "Optional minimum salary, in the local currency (RM / SGD / PHP / IDR). By default treated as a monthly figure."
          },
          "salaryMax": {
            "title": "Maximum salary",
            "type": "integer",
            "description": "Optional maximum salary, in the local currency. By default treated as a monthly figure."
          },
          "salaryType": {
            "title": "Salary period",
            "enum": [
              "monthly",
              "annual"
            ],
            "type": "string",
            "description": "Whether the salary filter values are monthly or annual amounts. JobStreet markets quote monthly salaries by default.",
            "default": "monthly"
          },
          "daterange": {
            "title": "Listed within N days",
            "type": "integer",
            "description": "Only return jobs listed in the last N days. Accepted values: 1, 3, 7, 14, 31. Other values are dropped with a warning."
          },
          "includeKeywords": {
            "title": "Must mention any of",
            "type": "array",
            "description": "Post-filter: keep only jobs whose title, company, teaser, bullet points or description (when 'Include full description' is on) mention at least one of these words.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "excludeKeywords": {
            "title": "Must mention none of",
            "type": "array",
            "description": "Post-filter: drop jobs that mention any of these words (same fields as above).",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "fromDate": {
            "title": "Listed on or after",
            "type": "string",
            "description": "Post-filter, ISO date or datetime (e.g. 2026-10-01)."
          },
          "toDate": {
            "title": "Listed on or before",
            "type": "string",
            "description": "Post-filter, ISO date or datetime."
          },
          "maxAgeMinutes": {
            "title": "Max listing age (minutes)",
            "minimum": 0,
            "type": "integer",
            "description": "Post-filter: keep only jobs listed within the last N minutes. 0 = off.",
            "default": 0
          },
          "requireContact": {
            "title": "Require contact details",
            "enum": [
              "off",
              "email",
              "phone",
              "either",
              "both"
            ],
            "type": "string",
            "description": "Post-filter: keep only jobs where an email and/or phone was found. Needs 'Include full description' on.",
            "default": "off"
          },
          "sortmode": {
            "title": "Sort order",
            "enum": [
              "ListedDate",
              "KeywordRelevance"
            ],
            "type": "string",
            "description": "ListedDate = newest first. KeywordRelevance = best match.",
            "default": "ListedDate"
          },
          "urls": {
            "title": "JobStreet search URLs",
            "type": "array",
            "description": "Paste one or more JobStreet search URLs. Supported: keyword and location pages (/software-engineer-jobs/in-Kuala-Lumpur), keyword-only (/it-jobs), location-only (/jobs/in-Selangor), category and sub-category pages (/jobs-in-information-communication-technology, .../developers-programmers), a work type (full-time, part-time, contract-temp, casual-vacation) or work arrangement (on-site, hybrid, remote) after the keyword or category, the filtered query form (/jobs?classification=6281&worktype=242&daterange=7&page=2), a ?where= location, hosts my, sg, ph and id, or a v5 search API link. Job detail pages (/job/<id>), single-job share links (?jobId=) and company pages are not supported and are skipped with a warning.",
            "items": {
              "type": "string"
            },
            "default": [
              "https://my.jobstreet.com/software-engineer-jobs/in-Kuala-Lumpur",
              "https://my.jobstreet.com/it-jobs",
              "https://my.jobstreet.com/jobs/in-Selangor",
              "https://my.jobstreet.com/jobs-in-information-communication-technology",
              "https://my.jobstreet.com/jobs-in-information-communication-technology/in-Kuala-Lumpur",
              "https://my.jobstreet.com/jobs-in-information-communication-technology/developers-programmers",
              "https://my.jobstreet.com/software-engineer-jobs/remote",
              "https://my.jobstreet.com/software-engineer-jobs-in-information-communication-technology/in-Kuala-Lumpur/full-time",
              "https://my.jobstreet.com/jobs?classification=6281&worktype=242&daterange=7&sortmode=ListedDate&page=2",
              "https://sg.jobstreet.com/jobs-in-accounting/in-Singapore",
              "https://ph.jobstreet.com/jobs-in-accounting/in-Manila",
              "https://id.jobstreet.com/jobs-in-accounting/in-Jakarta",
              "https://my.jobstreet.com/api/jobsearch/v5/search?siteKey=MY-Main&sourcesystem=houston&where=Kuala+Lumpur&keywords=software+engineer&page=1&pageSize=5"
            ]
          },
          "includeFullDescription": {
            "title": "Fetch full job description",
            "type": "boolean",
            "description": "If true, fetches the full job HTML body, company overview, expiry date, and phone (when available) via the jobseeker graphql endpoint. Batched per page: one extra request covers up to 22 jobs.",
            "default": true
          },
          "maxItems": {
            "title": "Max items to return",
            "minimum": 0,
            "type": "integer",
            "description": "Total cap across ALL URLs and ALL pages (not per-URL). Example: maxItems=50 with 3 URLs paginates URL 1 until the budget is filled; URLs 2 and 3 run only if budget remains. Set to 0 for unlimited.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 0,
            "type": "integer",
            "description": "Stop each search after N result pages (22 jobs per page). 0 = no limit.",
            "default": 0
          },
          "descriptionFormat": {
            "title": "Description format",
            "enum": [
              "all",
              "text",
              "html",
              "markdown"
            ],
            "type": "string",
            "description": "Which description shapes to output: all (text, HTML, Markdown), or only one.",
            "default": "all"
          },
          "maxTimeSec": {
            "title": "Max run time (seconds)",
            "minimum": 0,
            "type": "integer",
            "description": "Wall-clock cap across ALL URLs and pages. When exceeded, the actor stops paginating, flushes whatever it already fetched to the dataset, and exits cleanly. Set to 0 for no time limit.",
            "default": 0
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Defaults to Apify datacenter proxy. If your account can't access it (free tier), the actor falls back to a backup connection automatically. For heavy/production workloads, set apifyProxyGroups to [\"RESIDENTIAL\"] on an Apify paid plan.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": []
            }
          },
          "resumeFromRunId": {
            "title": "Resume from run/dataset ID",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue an interrupted crawl: jobs already collected there are skipped so you get only what's still missing. One-off continuation of a SPECIFIC run - for ongoing scheduled monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "For a search you run on a schedule (e.g. daily/weekly): remembers what this exact search returned last time and classifies every job as NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED, so you can act on only what changed. Off by default so existing scheduled runs are unaffected. Separate from Resume above, which continues one specific interrupted run. Uses State key below to isolate different searches; see Emit unchanged rows / Emit expired rows to control which of those get pushed (both bill extra rows when on). A job is UPDATED when any returned field differs from last time except scrapedAt, listingDateDisplay (the site's relative 'N ago' text) and detailFetched, which are excluded because they change on every fetch; a genuine relist (a new listingDate) does count. Add more with Ignore fields when detecting changes.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Names the saved baseline Incremental mode compares against. Leave empty to auto-derive one from your country/keywords/location/classification/workType/salary/daterange/sortmode/urls/includeFullDescription - two differently-configured searches never share a baseline even with this left empty. Set your own text only if you want to explicitly reuse or separate baselines yourself. Ignored when Incremental mode is off."
          },
          "emitUnchanged": {
            "title": "Emit unchanged rows",
            "type": "boolean",
            "description": "When Incremental mode is on: also push rows classified UNCHANGED (identical to last run), not just NEW/UPDATED/REAPPEARED/EXPIRED. Off by default to save you from paying for rows that didn't change. Turning this on bills the per-result event (and the detail-enrichment surcharge, if Fetch full job description is on) for every unchanged row too.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired rows",
            "type": "boolean",
            "description": "When Incremental mode is on: push a synthetic EXPIRED row for jobs tracked in a previous run that no longer appear in this one. Only fires after a run that scanned every page of every search with no cap, time limit, or resume truncating it - a partial scan can't tell 'gone' apart from 'not reached yet', so it's skipped (with a log line) otherwise. Off by default; turning it on bills the per-result event for each EXPIRED row emitted.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Optional. Field names to exclude from UPDATED change detection when Incremental mode is on, e.g. salaryLabel or branding.logo (a dotted path reaches inside nested objects). The fields are still returned in every row; they just never turn a row into UPDATED or appear in changedFields. Changing this list never causes a one-time wave of UPDATED rows.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}