{
  "openapi": "3.0.1",
  "info": {
    "title": "IrishJobs.ie [$1.45/1K💰] Ireland Jobs Scraper + Salary",
    "description": "Search IrishJobs.ie by keyword, county & salary — or any URL. Structured salary bands, skills, employer + geo. Only-new-jobs mode for scheduled runs, Telegram/Slack/Discord/WhatsApp alerts, AI-agent compact output, optional contact-email enrichment. JSON/CSV out.",
    "version": "0.1",
    "x-build-id": "YJzfEy9mitC1l3Y3K"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~irishjobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-irishjobs-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~irishjobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-irishjobs-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~irishjobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-irishjobs-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 keyword",
            "type": "string",
            "description": "Job title, skill, or keyword — e.g. `software engineer`, `accountant`, `nurse`. Leave empty to browse all jobs (optionally narrowed by location/county). Add more keywords in **Batch keywords** below to run several searches in one go."
          },
          "queries": {
            "title": "Batch keywords (optional)",
            "type": "array",
            "description": "Extra keyword searches, one per line — each runs as its own search sharing the same location and filters, into one dataset. `maxItems` applies per search.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "📍 Location",
            "type": "string",
            "description": "City, town, or region in Ireland — e.g. `Dublin`, `Cork`, `Portlaoise`. Leave empty to search nationwide. Ignored when a County is selected below."
          },
          "county": {
            "title": "🗺️ County",
            "enum": [
              "dublin",
              "cork",
              "galway",
              "limerick",
              "waterford",
              "kilkenny",
              "wexford",
              "wicklow",
              "kildare",
              "meath",
              "louth",
              "kerry",
              "clare",
              "tipperary",
              "mayo",
              "sligo",
              "donegal",
              "cavan",
              "monaghan",
              "roscommon",
              "leitrim",
              "longford",
              "westmeath",
              "offaly",
              "laois",
              "carlow"
            ],
            "type": "string",
            "description": "Filter by Irish county — matches the site's own county pages. Overrides Location when set."
          },
          "radius": {
            "title": "🧭 Radius (km)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Search radius in km around the Location (requires a location). The site honours values like 5, 10, 20, 30, 40, 50, 75, 100."
          },
          "sort": {
            "title": "↕️ Sort by",
            "enum": [
              "relevance",
              "date",
              "salary_high",
              "salary_low",
              "distance"
            ],
            "type": "string",
            "description": "Result order. `date` = newest first — the right choice for monitoring feeds.",
            "default": "relevance"
          },
          "postedWithin": {
            "title": "🕐 Posted within (days)",
            "minimum": 0,
            "type": "integer",
            "description": "Only jobs posted in the last N days. The site supports windows of 1, 3, 7, or 14 — other values snap UP to the next window (5 → 7). Values above 14 disable the filter. For sharper recency (hours/minutes) use `maxAgeMinutes` in Filters."
          },
          "minSalary": {
            "title": "💶 Minimum salary (EUR/year)",
            "minimum": 0,
            "type": "integer",
            "description": "Only jobs with an annual salary of at least this (the site's own \"at least\" facet — e.g. 40000). Jobs without a disclosed salary are excluded by the site when this is set."
          },
          "companyType": {
            "title": "🏢 Company type",
            "enum": [
              "employer",
              "agency"
            ],
            "type": "string",
            "description": "Only agency postings, or only direct employers. Leave empty for both."
          },
          "startUrls": {
            "title": "📌 IrishJobs.ie URLs",
            "type": "array",
            "description": "Direct listing URLs (e.g. `https://www.irishjobs.ie/jobs/dublin`, `/jobs/software-engineer/in-cork`, `/jobs-at/{company}`) and/or job-detail URLs (`/job/{slug}/{company}-job{id}`). Every filter the IrishJobs web search supports works via the query string too. Scraped IN ADDITION to any keyword search above. Sister sites: for totaljobs.com use [TotalJobs Scraper](https://apify.com/memo23/totaljobs-scraper), for stepstone.de/at/fr use [StepStone Scraper](https://apify.com/memo23/stepstone-search-cheerio-ppr).",
            "items": {
              "type": "string"
            }
          },
          "remoteOnly": {
            "title": "🏠 Remote only",
            "type": "boolean",
            "description": "Only fully remote positions (listing tagged \"Remote\" or TELECOMMUTE). Hybrid roles do NOT pass. Applied after fetch — IrishJobs has no server-side remote facet — so runs scan up to `maxItems` jobs and emit the remote subset.",
            "default": false
          },
          "includeKeywords": {
            "title": "✅ Include keywords",
            "type": "object",
            "description": "Require at least one of these keywords in title/description/skills. Example: `{\"keywords\":[\"React\",\"Node.js\"],\"matchTitle\":true,\"matchDescription\":true,\"matchSkills\":true}` (the three match flags default to true)."
          },
          "excludeKeywords": {
            "title": "🚫 Exclude keywords",
            "type": "object",
            "description": "Drop jobs containing any of these keywords. Same shape as Include keywords: `{\"keywords\":[\"PHP\",\"WordPress\"]}`."
          },
          "fromDate": {
            "title": "📅 From date",
            "type": "string",
            "description": "Only jobs posted on or after this date — `YYYY-MM-DD` or full ISO-8601."
          },
          "toDate": {
            "title": "📅 To date",
            "type": "string",
            "description": "Only jobs posted on or before this date — `YYYY-MM-DD` (inclusive through end of day) or ISO-8601."
          },
          "maxAgeMinutes": {
            "title": "⏰ Max age (minutes)",
            "minimum": 0,
            "type": "integer",
            "description": "Only jobs posted within the last N minutes. 0 = off. Pair with an hourly schedule (e.g. 60) + `sort: date` for a real-time feed.",
            "default": 0
          },
          "customFilters": {
            "title": "🔧 Custom filters (advanced)",
            "type": "array",
            "description": "Rules on any output field, dot-notation supported. Each rule: `{\"field\":\"salary.min\",\"op\":\"gte\",\"value\":50000}`. Ops: includes, notIncludes, equals, notEquals, gt, gte, lt, lte. Example: `[{\"field\":\"location.locality\",\"op\":\"includes\",\"value\":\"Dublin\"},{\"field\":\"description\",\"op\":\"notIncludes\",\"value\":\"php\"}]`."
          },
          "skipReposts": {
            "title": "♻️ Only new jobs (skip reposts)",
            "type": "boolean",
            "description": "Remember every job emitted and skip it on future runs (90-day window). Skipped jobs are dropped BEFORE the page fetch — never charged, and they don't consume `maxItems`, so scheduled runs keep digging until they find genuinely new postings. Perfect with a daily/hourly schedule + notifications.",
            "default": false
          },
          "dedupStoreName": {
            "title": "Dedup store name",
            "type": "string",
            "description": "Named storage for the seen-jobs memory (default `irishjobs-seen-jobs`). Use different names to keep separate searches' memories apart, or the same name to share one memory across tasks."
          },
          "telegramToken": {
            "title": "🤖 Telegram bot token",
            "type": "string",
            "description": "Bot token from @BotFather, e.g. `110201543:AAHdqTc…`. Requires Telegram chat ID below."
          },
          "telegramChatId": {
            "title": "💬 Telegram chat ID",
            "type": "string",
            "description": "Chat or channel the bot posts to, e.g. `-1001234567890` (get yours from @userinfobot)."
          },
          "discordWebhookUrl": {
            "title": "🎮 Discord webhook URL",
            "type": "string",
            "description": "Channel webhook from Server Settings → Integrations → Webhooks."
          },
          "slackWebhookUrl": {
            "title": "💼 Slack webhook URL",
            "type": "string",
            "description": "Incoming webhook from api.slack.com/messaging/webhooks."
          },
          "whatsappPhoneNumberId": {
            "title": "📱 WhatsApp phone number ID",
            "type": "string",
            "description": "Meta Cloud API phone number ID (the numeric ID next to your business number — NOT the phone number). Requires the access token and recipient below."
          },
          "whatsappAccessToken": {
            "title": "🔐 WhatsApp access token",
            "type": "string",
            "description": "Meta Cloud API token with `whatsapp_business_messaging` scope."
          },
          "whatsappTo": {
            "title": "📨 WhatsApp recipient",
            "type": "string",
            "description": "Recipient phone in international format, e.g. `+353861234567`. Meta only delivers free-form text within 24h of the recipient's last message to your business number."
          },
          "webhookUrl": {
            "title": "🪝 Generic webhook URL",
            "type": "string",
            "description": "Any HTTPS endpoint — receives a JSON POST with counts, dataset link, and the newest items. The universal escape hatch for n8n / Make / Zapier / your own backend."
          },
          "webhookHeaders": {
            "title": "Webhook headers",
            "type": "object",
            "description": "Optional extra HTTP headers for the generic webhook, e.g. `{\"Authorization\": \"Bearer abc123\"}`."
          },
          "notificationLimit": {
            "title": "Items per notification",
            "minimum": 1,
            "maximum": 25,
            "type": "integer",
            "description": "Max jobs listed inside a notification message. Default 10, cap 25.",
            "default": 10
          },
          "notifyOnlyChanges": {
            "title": "Notify only on new results",
            "type": "boolean",
            "description": "Stay silent when a run found nothing (new). Disable to get a ping after every run.",
            "default": true
          },
          "descriptionFormat": {
            "title": "📝 Description formats",
            "enum": [
              "all",
              "text",
              "html",
              "markdown"
            ],
            "type": "string",
            "description": "Which derived description fields to add to each row: plain text, clean HTML, Markdown, or all three. The original `description` field is always kept.",
            "default": "all"
          },
          "descriptionMaxLength": {
            "title": "✂️ Description max length",
            "minimum": 0,
            "type": "integer",
            "description": "Truncate every description field to this many characters ('...' appended). 0 = no truncation. Pairs well with compact mode for token budgets.",
            "default": 0
          },
          "compact": {
            "title": "📦 Compact output",
            "type": "boolean",
            "description": "Flat 15-field core rows — jobId, title, company, location, salary band, skills, dates, URLs, plain-text description. Built for AI-agent and MCP workflows where token budgets matter. Email-enrichment columns are kept when enabled.",
            "default": false
          },
          "outputFields": {
            "title": "🎛️ Output fields",
            "type": "array",
            "description": "Keep only these fields, dot-notation supported — e.g. `title`, `salary.min`, `employer.name`, `location.locality`. Empty = all fields.",
            "items": {
              "type": "string"
            }
          },
          "excludeEmptyFields": {
            "title": "Exclude empty fields",
            "type": "boolean",
            "description": "Drop null / empty-string / empty-array fields from each row — smaller payloads for agents and dashboards.",
            "default": false
          },
          "enrichEmails": {
            "title": "📧 Enrich with contact emails (billed per email)",
            "type": "boolean",
            "description": "Finds a contact email for each hiring employer (discovered from the company name, then its website is scanned). Adds contactEmail + contactWebsite columns plus a detailed emailEnrichment object. Billed per contact email found; only charged when an email is returned, never for misses.",
            "default": false
          },
          "qualifyByPayment": {
            "title": "💳 Qualify by payment (flag businesses that take money online)",
            "type": "boolean",
            "description": "Requires \"Enrich with contact emails\". Scans each business's website — reusing the pages already fetched for email discovery, so no extra cost or time — for payment processors and e-commerce platforms (Stripe, Shopify, PayPal, Paddle, Lemon Squeezy, WooCommerce, Square, Chargebee and more). Adds takesPayments, paymentProcessors, stripeLiveKey and paymentConfidence. No extra charge.",
            "default": false
          },
          "maxItems": {
            "title": "Max jobs per search / listing URL",
            "minimum": 1,
            "type": "integer",
            "description": "Maximum job rows emitted **per search or listing URL**. 2 keywords with `maxItems: 100` → up to 200 total rows. Direct detail URLs always emit 1 row each. Each row is one paid dataset item. With `skipReposts` on, skipped known jobs do NOT count — the crawl digs until it finds this many NEW jobs (or the site runs out). Default 1000. Free-tier users are additionally capped at 100 total rows.",
            "default": 1000
          },
          "maxConcurrency": {
            "title": "Max parallel requests",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Parallel HTTP requests for detail-page fetches. Concurrency 3-6 is the sweet spot through the built-in residential proxy.",
            "default": 4
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 0,
            "type": "integer",
            "description": "Per-URL retry budget on network errors, proxy CONNECT failures, HTTP/2 stream resets, and transient 4xx responses. Each retry rotates the proxy session. Default 6.",
            "default": 6
          },
          "proxy": {
            "title": "Proxy configuration (optional override)",
            "type": "object",
            "description": "Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}