{
  "openapi": "3.0.1",
  "info": {
    "title": "SEEK, JobStreet & JobsDB Job Scraper — 8 Markets",
    "description": "Scrape public job listings from SEEK, JobStreet and JobsDB across 8 APAC markets, one market per run. Export titles, companies, locations and salary fields to JSON, CSV or Excel. Add optional company data and inspect search coverage in RUN_SUMMARY.",
    "version": "0.1",
    "x-build-id": "xHYAelUUVKWNBb7O3"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/bluedata~seek-jobstreet-jobsdb-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-bluedata-seek-jobstreet-jobsdb-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/bluedata~seek-jobstreet-jobsdb-scraper/runs": {
      "post": {
        "operationId": "runs-sync-bluedata-seek-jobstreet-jobsdb-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/bluedata~seek-jobstreet-jobsdb-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-bluedata-seek-jobstreet-jobsdb-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": {
          "query": {
            "title": "🔍 Search keywords",
            "description": "Optional keyword, comma-separated keywords, JSON string array, native string array, or {terms:[...]} for API callers. Each term becomes one search in the selected market, merged and deduplicated by job ID. Leave it empty when using startUrls alone; no hidden default keyword is added to URL-only input. If both query and startUrls are empty, the runtime uses the legacy default query \"AI Engineer\".",
            "default": ""
          },
          "queryMatchMode": {
            "title": "Query validation",
            "enum": [
              "source",
              "all_terms",
              "phrase"
            ],
            "type": "string",
            "description": "source uses source ranking to choose candidates but emits only records with complete target-specific literal evidence. All parsed query terms are forwarded without translation or synonym substitution in every market. Thai queries in TH and Chinese queries in HK with complete coverage and no literal match return no_results. SG Arabic/Korean queries with no literal match on the first result page terminate as unsupported_language; first-page literal matches remain eligible. Other non-Latin queries with complete evidence-free coverage may be unsupported_language. Configured page/candidate caps return coverage_limited; request/time/challenge failures report their own incomplete status. all_terms requires every query token in selected fields; phrase requires one contiguous phrase. Default fields are title/teaser/description. keywordMatch flags select fields. No semantic guarantee.",
            "default": "source"
          },
          "market": {
            "title": "Market",
            "enum": [
              "TH",
              "SG",
              "AU",
              "NZ",
              "MY",
              "HK",
              "ID",
              "PH"
            ],
            "type": "string",
            "description": "Which supported public job market to search.",
            "default": "TH"
          },
          "location": {
            "title": "📍 Location filter",
            "description": "Location text, JSON-string array, or native string array (up to 10). Known aliases are market-specific; unknown locations remain unchanged. Bangkok/Bangkok Metropolitan Area resolve to กรุงเทพมหานคร for TH compatibility; this is label matching, not a guarantee of metropolitan geographic coverage. RUN_SUMMARY.searchPlan/searches report originalLocation (the value you sent) and effectiveLocation (the source label actually used)."
          },
          "startUrls": {
            "title": "🔗 Start URLs",
            "maxItems": 20,
            "type": "array",
            "description": "Optional array of HTTPS search/category URL strings or {url} objects on supported hosts (maximum 20). Both item forms are accepted by the API. A URL without its own query text falls back to its search-slug path; its host selects that target's market. When query is empty, URL targets run without an implicit default keyword. Exact duplicate URLs and URL/query collisions are merged and reported in RUN_SUMMARY.searchPlan.inputSource. Detail pages and homepages are rejected.",
            "default": []
          },
          "maxResults": {
            "title": "💯 Max results",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "Run-wide output cap across all queries, not a per-query output quota and not a source coverage guarantee. In best_effort multi-target runs, the source candidate budget is shared fairly so each planned target gets an execution opportunity; fill_target may intentionally skip later targets once the run-wide target is met. Final emitted records never exceed this cap. Hard ceiling: 10,000. The Actor scans more candidates than this when location/relevance filters reject listings; resultLimitReached reports the output cap, coverageLimitReached reports a source fetch-window cap; use coverageMode=fill_target with maxResults greater than 0 to keep scanning until this target is met or a run limit is hit. This is not a request or spending cap; enrichment and filtering may process more candidates. 0 removes the requested output cap; exportExcel rejects 0, and a large scan may be required subject to the Actor's safety and time limits. Check run status and usage.",
            "default": 20
          },
          "coverageMode": {
            "title": "🎯 Search coverage mode",
            "enum": [
              "best_effort",
              "fill_target"
            ],
            "type": "string",
            "description": "best_effort (default): bounded scan that stops at the standard safety limits and reports coverage facts in RUN_SUMMARY. fill_target: keeps scanning and enriching candidates until maxResults matched jobs are emitted, the source is exhausted, or a hard run limit is reached. In fill_target runs, RUN_SUMMARY reports targetReached, shortfall, candidatesScanned, candidatesRejected and stopReason, and adds the TARGET_NOT_REACHED warning when the requested target could not be met. fill_target requires maxResults > 0; with maxResults 0 the value is echoed but the run stays bounded like best_effort. Billing is unchanged: emitted dataset items plus the run-start event are charged; rejected candidates are not charged.",
            "default": "best_effort"
          },
          "exportExcel": {
            "title": "Download custom lossless XLSX",
            "type": "boolean",
            "description": "Opt in to an Actor-owned JOBS.xlsx download after collection. Requires stateless mode (incremental=false) and maxResults from 1 through 1000; native Dataset exports remain unchanged.",
            "default": false
          },
          "preset": {
            "title": "Preset",
            "enum": [
              "basic",
              "company",
              "full"
            ],
            "type": "string",
            "description": "Choose the enrichment depth. Basic is fastest; Company context enforces workContext, companyProfile, and applicationInfo; Full enforces all supported public groups except contacts and login-only data. Preset groups cannot be disabled with additionalData=false; choose Basic for no enrichment. Detail concurrency is managed automatically.",
            "default": "basic"
          },
          "maxRetries": {
            "title": "Maximum source retries",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Retries after a failed source request (default 2, range 0-10). Retries consume the configured source request budget.",
            "default": 2
          },
          "maxSourceRequests": {
            "title": "Maximum source requests",
            "minimum": 0,
            "maximum": 20000,
            "type": "integer",
            "description": "Optional process-run request budget across search and detail requests (range 0-20,000), including failed requests and retries. Omit to preserve legacy behavior; this is not a money cap."
          },
          "maxDetailRequests": {
            "title": "Maximum detail requests",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Optional process-run detail-request budget (range 0-1,000). Explicit zero disables detail requests; omit to preserve legacy behavior. This is separate from maxResults and automatic detail concurrency."
          },
          "sortMode": {
            "title": "Sort mode",
            "enum": [
              "relevance",
              "date"
            ],
            "type": "string",
            "description": "Result ordering: relevance or newest first.",
            "default": "relevance"
          },
          "salaryMin": {
            "title": "Minimum salary",
            "type": "number",
            "description": "Keep jobs whose pay band reaches at least this amount (market home currency)."
          },
          "salaryMax": {
            "title": "Maximum salary",
            "type": "number",
            "description": "Keep jobs whose pay band starts at or below this amount (market home currency)."
          },
          "classification": {
            "title": "Classification text",
            "type": "string",
            "description": "Keep jobs whose category labels contain this text. Labels are in the market's local language, so copy an exact value from the 'categories' field of a sample run. For exact category IDs use categoryIds below."
          },
          "categoryIds": {
            "title": "Category IDs",
            "type": "string",
            "description": "Optional comma-separated classification IDs (for example, a software category). IDs can be read from an enriched record's classification fields."
          },
          "includeKeywords": {
            "title": "✅ Include keywords",
            "type": "string",
            "description": "Comma-separated or JSON-list terms. Every term must appear in the searched fields."
          },
          "excludeKeywords": {
            "title": "🚫 Exclude keywords",
            "type": "string",
            "description": "Comma-separated or JSON-list terms. A job is excluded if any term appears in the searched fields."
          },
          "keywordMatchTitle": {
            "title": "Match title only",
            "type": "boolean",
            "description": "Match job titles (combine with other toggles). With no include/exclude keywords, requires all main-query tokens in selected fields. With explicit include/exclude terms, preserves legacy keyword scope; set queryMatchMode=all_terms to validate the main query too.",
            "default": false
          },
          "keywordMatchCompany": {
            "title": "Match company only",
            "type": "boolean",
            "description": "Restrict keyword matching to company names.",
            "default": false
          },
          "keywordMatchLocation": {
            "title": "Match location only",
            "type": "boolean",
            "description": "Restrict keyword matching to locations.",
            "default": false
          },
          "keywordMatchCategory": {
            "title": "Match category only",
            "type": "boolean",
            "description": "Restrict keyword matching to category labels.",
            "default": false
          },
          "keywordMatchDescription": {
            "title": "Match description only",
            "type": "boolean",
            "description": "Scope include/exclude keywords to teaser/description text. Main-query strict matching checks actual description only, not teaser presented as a description; enable enrichDetails to fetch it.",
            "default": false
          },
          "fromDate": {
            "title": "Posted from (date)",
            "type": "string",
            "description": "Keep jobs posted on or after this date (YYYY-MM-DD or ISO). Records without a date are kept."
          },
          "toDate": {
            "title": "Posted to (date)",
            "type": "string",
            "description": "Keep jobs posted on or before this date (YYYY-MM-DD or ISO). Records without a date are kept."
          },
          "maxAgeMinutes": {
            "title": "Max age (minutes)",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only jobs posted within this many minutes. Records without a timestamp are kept."
          },
          "customFilters": {
            "title": "Custom field filters",
            "type": "array",
            "description": "Advanced record-field filters, e.g. [{\"field\":\"salaryMin\",\"op\":\"gte\",\"value\":\"50000\"}]. Operators: includes, notIncludes, equals, notEquals, gt, gte, lt, lte.",
            "default": []
          },
          "additionalData": {
            "title": "Optional data groups",
            "type": "object",
            "description": "Select extra public listing and company information. Every group is off by default; availability varies by listing and market.",
            "properties": {
              "listingMetadata": {
                "title": "Listing status and expiry",
                "type": "boolean",
                "description": "Include source listing status, expiry date, link-out, and verification fields.",
                "default": false
              },
              "workContext": {
                "title": "Work context",
                "type": "boolean",
                "description": "Include all available work types and arrangements.",
                "default": false
              },
              "locationDetails": {
                "title": "Location details",
                "type": "boolean",
                "description": "Include additional public location labels when available.",
                "default": false
              },
              "classifications": {
                "title": "Classification details",
                "type": "boolean",
                "description": "Include category labels and classification identifiers.",
                "default": false
              },
              "companyProfile": {
                "title": "Company profile",
                "type": "boolean",
                "description": "Include the available company profile, website, industry, size, and description.",
                "default": false
              },
              "companyReviews": {
                "title": "Company review summary",
                "type": "boolean",
                "description": "Include aggregate rating, review count, and listed benefits when available.",
                "default": false
              },
              "jobMedia": {
                "title": "Job media and highlights",
                "type": "boolean",
                "description": "Include public logo, cover, video links, and job highlights when available.",
                "default": false
              },
              "applicationInfo": {
                "title": "Application information",
                "type": "boolean",
                "description": "Include the listing share link, application restriction label, and listed questions.",
                "default": false
              },
              "publicContacts": {
                "title": "Public listing contacts",
                "type": "boolean",
                "description": "Include contact fields returned publicly for this listing. Contact data is sensitive; enable only when needed.",
                "default": false
              },
              "sourceActivity": {
                "title": "Listing activity",
                "type": "boolean",
                "description": "Include available listing activity counts and timestamps. These are not unique applicant counts.",
                "default": false
              },
              "applicantInsights": {
                "title": "Applicant insights",
                "type": "boolean",
                "description": "Currently unavailable for public searches. Enabling this option is rejected before a search starts.",
                "default": false
              },
              "searchInsights": {
                "title": "Search suggestions",
                "type": "boolean",
                "description": "Include available related searches, category and title facets, and spelling suggestions in the run summary.",
                "default": false
              },
              "sourceReferences": {
                "title": "Public source references",
                "type": "boolean",
                "description": "Include public employer and listing reference identifiers.",
                "default": false
              }
            },
            "default": {},
            "additionalProperties": false
          },
          "notificationDataGroups": {
            "title": "Optional data in notifications",
            "type": "array",
            "description": "Allowlist optional data groups that may be included in webhook notifications. Defaults to none; public contacts require explicit selection here as well.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "enrichDetails": {
            "title": "Enrich with job details",
            "type": "boolean",
            "description": "Detail enrichment: fetches each accepted listing's detail record for full descriptions, application links, company pages, and classification fields when available. More detail work takes longer; optional groups can trigger detail fetches independently.",
            "default": false
          },
          "descriptionMaxLength": {
            "title": "Description max length",
            "minimum": 0,
            "type": "integer",
            "description": "Truncate teaser/description text to this many characters (0 = no truncation)."
          },
          "compact": {
            "title": "Compact output",
            "type": "boolean",
            "description": "Omit teaser text and matched query terms from each record.",
            "default": false
          },
          "excludeEmptyFields": {
            "title": "Exclude empty fields",
            "type": "boolean",
            "description": "Remove null and empty optional values from each record.",
            "default": false
          },
          "contractCheck": {
            "title": "Output validation",
            "type": "boolean",
            "description": "Validate that returned records carry the expected fields; fail the run when the returned shape is incompatible. Useful for scheduled monitoring.",
            "default": false
          },
          "incremental": {
            "title": "Incremental mode",
            "type": "boolean",
            "description": "Track seen jobs across runs and flag isNew/isUpdated per record. For monitoring, reuse the same persistent stateStoreName and stateKey on every run; without them, a new run cannot load the previous baseline.",
            "default": false
          },
          "stateKey": {
            "title": "State key (monitor identity)",
            "type": "string",
            "description": "Stable key that isolates one monitor's baseline (for example sg-senior-backend-daily). Reuse the same key for that monitor; use a new key when the query or market scope changes."
          },
          "stateStoreName": {
            "title": "Persistent state store (monitoring)",
            "type": "string",
            "description": "Required for cross-run monitoring: a named cloud key-value store that persists between runs and is created on first use. Reuse the same store and stateKey for the monitor; the default run store does not preserve a baseline. Check RUN_SUMMARY.incrementalStateStatus if storage is unavailable."
          },
          "emitUnchanged": {
            "title": "Emit unchanged",
            "type": "boolean",
            "description": "In incremental mode, also emit records that have not changed.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired",
            "type": "boolean",
            "description": "In incremental mode, also emit markers for previously seen jobs that no longer appear. Markers are emitted only when this run achieved complete source coverage; a coverage-limited baseline sets baselineComplete=false and expiredRecordsReliable=false and suppresses all expiration markers.",
            "default": false
          },
          "skipReposts": {
            "title": "Skip reposts",
            "type": "boolean",
            "description": "In incremental mode, drop new listings whose content matches a previously expired one (flagged isRepost/repostOfId either way).",
            "default": false
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "Generic webhook receiving a JSON POST with run metadata and records."
          },
          "webhookHeaders": {
            "title": "Webhook headers",
            "type": "object",
            "description": "Optional headers for the webhook POST, e.g. {\"Authorization\": \"Bearer xyz\"}."
          },
          "discordWebhookUrl": {
            "title": "Discord webhook URL",
            "type": "string",
            "description": "Discord channel webhook for run alerts (messages chunked to the 2,000-character limit)."
          },
          "notifyOnlyChanges": {
            "title": "Notify only on changes",
            "type": "boolean",
            "description": "With incremental mode, send notifications only when new/updated jobs exist.",
            "default": false
          },
          "notificationLimit": {
            "title": "Notification record limit",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum records included per notification (1–20).",
            "default": 5
          },
          "includeRunSummary": {
            "title": "Include run summary",
            "type": "boolean",
            "description": "Include run metadata in notification payloads.",
            "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
                  },
                  "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}