{
  "openapi": "3.0.1",
  "info": {
    "title": "Eluta.ca Jobs Scraper",
    "description": "Scrape eluta.ca — Canada's national job search engine — by keyword and city. Full descriptions, CAD salary min/max, employer website, NAICS code, HQ geo, Top-100 employer rating, and the real ATS apply link (not an eluta redirect). Incremental monitoring built in. JSON or CSV out.",
    "version": "0.0",
    "x-build-id": "Hqc3bi915evOAbPNk"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~eluta-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-eluta-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/memo23~eluta-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-eluta-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/memo23~eluta-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-eluta-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": "Job keywords",
            "type": "array",
            "description": "One search per line, e.g. software engineer or registered nurse. Eluta's own search operators, such as sort:post, can be added to a line.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Cities or regions",
            "type": "array",
            "description": "Optional, e.g. Toronto or Vancouver, BC. Every keyword is searched in every place listed. Empty: all of Canada.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "eluta.ca links",
            "type": "array",
            "description": "Optional. Search result pages, pages such as /Nurse-jobs-in-Toronto-ON, employer pages such as /jobs-at-sunnybrook, or single job links (/spl/...). They run alongside the keywords above.",
            "items": {
              "type": "string"
            }
          },
          "sortBy": {
            "title": "Result order",
            "enum": [
              "relevance",
              "date",
              "popularity"
            ],
            "type": "string",
            "description": "Relevance (default) is eluta's own ranking. Newest first suits scheduled runs, since fresh postings come up first.",
            "default": "relevance"
          },
          "fromDate": {
            "title": "Posted on or after",
            "type": "string",
            "description": "Optional date, e.g. 2026-08-01. Older postings are skipped."
          },
          "toDate": {
            "title": "Posted on or before",
            "type": "string",
            "description": "Optional date. A plain date such as 2026-08-31 includes that whole day."
          },
          "maxAgeMinutes": {
            "title": "Posted within the last (minutes)",
            "minimum": 0,
            "type": "integer",
            "description": "Optional. Keep only jobs posted this many minutes ago or less, e.g. 1440 for the last day. Empty or 0: any age."
          },
          "includeKeywords": {
            "title": "Must mention one of",
            "type": "array",
            "description": "Optional words. A job is kept when its title, employer or description contains any of them, in any letter case.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Skip if it mentions",
            "type": "array",
            "description": "Optional words. A job whose title, employer or description contains any of them is skipped.",
            "items": {
              "type": "string"
            }
          },
          "includeDetails": {
            "title": "Open each job page",
            "type": "boolean",
            "description": "On (default): each row gets the full description as text and HTML, posting and closing dates, job type, industry and NAICS code, employer website, logo, head office with coordinates, and the Canada's Top 100 Employers rating. Off: quicker rows with only what the result list shows.",
            "default": true
          },
          "resolveApplyUrls": {
            "title": "Employer's own apply link",
            "type": "boolean",
            "description": "On (default): each row also gets the link to the employer's own application page, for example on its hiring system, next to the eluta.ca link. One extra small request per job.",
            "default": true
          },
          "enrichEmails": {
            "title": "Find employer contact emails (beta)",
            "type": "boolean",
            "description": "Off (default). On: the employer's website, usually taken from the job page, is searched on its contact and about pages for an email. Adds contactEmail, contactWebsite and an emailEnrichment object. Charged per email found, never for misses.",
            "default": false
          },
          "qualifyByPayment": {
            "title": "Flag employers that take payments online",
            "type": "boolean",
            "description": "Needs the email option above. The employer pages already read for emails are checked for payment and shop platforms (Stripe, Shopify, PayPal, Square, WooCommerce and others). Adds takesPayments, paymentProcessors, stripeLiveKey and paymentConfidence at no extra charge or time.",
            "default": false
          },
          "excludeEmptyFields": {
            "title": "Leave out empty fields",
            "type": "boolean",
            "description": "On: fields with no value (null, empty text or an empty list) are removed from each row.",
            "default": false
          },
          "compact": {
            "title": "Short rows",
            "type": "boolean",
            "description": "On: rows keep only job ID, title, employer, location, salary, job type, posting date and the two links. Handy when the rows go to an AI tool.",
            "default": false
          },
          "descriptionMaxLength": {
            "title": "Cut descriptions at",
            "minimum": 0,
            "type": "integer",
            "description": "Longest description kept, in characters. Empty or 0: the whole text."
          },
          "incrementalMode": {
            "title": "Only what changed since the last run",
            "type": "boolean",
            "description": "Off (default). On: each job is compared with earlier runs and saved only when it is NEW, UPDATED or REAPPEARED, with changeType and firstSeenAt on the row. The first run saves everything and becomes the baseline. Jobs that are not saved are not charged.",
            "default": false
          },
          "skipReposts": {
            "title": "Ignore re-posted ads",
            "type": "boolean",
            "description": "With change tracking on: skip a job whose content matches an ad that expired earlier, which is how employers re-list the same opening under a new ID.",
            "default": false
          },
          "emitExpired": {
            "title": "Also save jobs that disappeared",
            "type": "boolean",
            "description": "With change tracking on: save a small row with changeType EXPIRED for each tracked job that is no longer on eluta.ca.",
            "default": false
          },
          "emitUnchanged": {
            "title": "Also save unchanged jobs",
            "type": "boolean",
            "description": "With change tracking on: jobs with no change are saved too, and charged like any row.",
            "default": false
          },
          "stateKey": {
            "title": "Change-tracking name",
            "type": "string",
            "description": "Optional, e.g. nurse-toronto. Empty: the name is built from your keywords, places, links and result order, so the same search always finds the same memory."
          },
          "resetIncrementalState": {
            "title": "Start the memory over",
            "type": "boolean",
            "description": "One-off: forget what this memory holds at the start of the run, so every job counts as NEW again.",
            "default": false
          },
          "monitoringMode": {
            "title": "Old seen-jobs memory (legacy)",
            "type": "boolean",
            "description": "Kept for older scheduled tasks. Jobs whose ID you already received are skipped before their page is opened, with no charge. For new setups use change tracking above, which also catches updates, re-posts and removals.",
            "default": false
          },
          "resetMonitoringState": {
            "title": "Clear the old seen-jobs memory",
            "type": "boolean",
            "description": "One-off: empty the legacy memory at the start of the run.",
            "default": false
          },
          "notifyOnlyChanges": {
            "title": "Alert on changes only",
            "type": "boolean",
            "description": "Off (default). On, with change tracking: alerts list only NEW, UPDATED and REAPPEARED jobs.",
            "default": false
          },
          "notificationLimit": {
            "title": "Jobs listed per alert",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many jobs each chat message lists, default 5, at most 20. The rest are given as a count.",
            "default": 5
          },
          "webhookUrl": {
            "title": "Webhook address",
            "type": "string",
            "description": "Optional. Gets one JSON POST after the run with metadata and items, for n8n, Make, Zapier or your own backend."
          },
          "webhookHeaders": {
            "title": "Headers for that webhook",
            "type": "object",
            "description": "Optional headers sent with the webhook POST, as a JSON object, for example an Authorization header with your token."
          },
          "slackWebhookUrl": {
            "title": "Slack incoming webhook",
            "type": "string",
            "description": "Optional. The alert is posted to the Slack channel behind this link."
          },
          "discordWebhookUrl": {
            "title": "Discord channel webhook",
            "type": "string",
            "description": "Optional. Create one in the channel's integration settings; the alert is posted there."
          },
          "telegramChatId": {
            "title": "Telegram chat",
            "type": "string",
            "description": "Optional. ID of the chat or channel your bot posts to, e.g. -1001234567890. Needs the bot token below."
          },
          "telegramBotToken": {
            "title": "Token of your Telegram bot",
            "type": "string",
            "description": "Optional. From @BotFather. With the chat above set, the run's jobs are posted there."
          },
          "whatsappTo": {
            "title": "WhatsApp number to message",
            "type": "string",
            "description": "Optional. Number with country code and no +, e.g. 14165551234. Needs the two fields below, and that person must have written to your business number in the last 24 hours."
          },
          "whatsappPhoneNumberId": {
            "title": "WhatsApp sender number ID",
            "type": "string",
            "description": "Numeric ID of your WhatsApp Business number, from Meta's developer dashboard."
          },
          "whatsappAccessToken": {
            "title": "WhatsApp Cloud API token",
            "type": "string",
            "description": "A system-user token from Meta Business for your WhatsApp app."
          },
          "maxItems": {
            "title": "Jobs in the whole run",
            "minimum": 1,
            "type": "integer",
            "description": "The run stops after this many jobs across all searches and links, default 1000. On the free Apify plan a run reads at most 100 searches and links and stops at 100 jobs.",
            "default": 1000
          },
          "maxPagesPerSearch": {
            "title": "Result pages per search",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Each search stops after this many result pages of about 10 jobs, default 20. It also stops when a page brings no new jobs.",
            "default": 20
          },
          "maxConcurrency": {
            "title": "Job pages read at once",
            "minimum": 1,
            "type": "integer",
            "description": "How many job pages are read in parallel, default 10.",
            "default": 10
          },
          "minConcurrency": {
            "title": "Lowest parallel reads (not used)",
            "minimum": 1,
            "type": "integer",
            "description": "Not used by the current version. The field stays so saved inputs keep working.",
            "default": 1
          },
          "maxRequestRetries": {
            "title": "Retries per request (not used)",
            "minimum": 0,
            "type": "integer",
            "description": "Not used by the current version, which retries on its own. The field stays so saved inputs keep working.",
            "default": 5
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}