{
  "openapi": "3.0.1",
  "info": {
    "title": "UK Public Sector Jobs Scraper: NHS Jobs & Teaching Vacancies",
    "description": "Scrape UK public-sector vacancies from NHS Jobs and Teaching Vacancies (official OGL APIs), plus optional DWP Find a Job. One schema with annual GBP salary, NHS Agenda for Change bands, teacher pay scales, region, closing-soon filter, new-job monitoring and employer hiring summaries.",
    "version": "0.1",
    "x-build-id": "xFhYcJp1NcdvU0t1G"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/signalscouter~uk-public-sector-jobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-signalscouter-uk-public-sector-jobs-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/signalscouter~uk-public-sector-jobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-signalscouter-uk-public-sector-jobs-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/signalscouter~uk-public-sector-jobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-signalscouter-uk-public-sector-jobs-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": {
          "sources": {
            "title": "Sources",
            "type": "array",
            "description": "Which official job sources to search. Both use free, official, openly licensed (OGL v3.0) APIs: no proxies, no browser.",
            "items": {
              "type": "string",
              "enum": [
                "nhs",
                "teaching"
              ],
              "enumTitles": [
                "NHS Jobs (England & Wales)",
                "Teaching Vacancies (DfE, schools in England)"
              ]
            },
            "default": [
              "nhs",
              "teaching"
            ]
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Keep jobs matching any keyword (case-insensitive). See 'Keyword match' for where keywords are looked for. Leave empty for all jobs.",
            "items": {
              "type": "string"
            }
          },
          "keywordScope": {
            "title": "Keyword match",
            "enum": [
              "title",
              "anywhere"
            ],
            "type": "string",
            "description": "Title: the keyword must appear in the job title (or Teaching Vacancies job role). Anywhere: NHS Jobs' own full-text search plus title/employer/description matching for Teaching Vacancies; much broader (e.g. 'nurse' matches ~40% of NHS adverts).",
            "default": "title"
          },
          "excludeKeywords": {
            "title": "Exclude keywords (title)",
            "type": "array",
            "description": "Drop jobs whose title contains any of these, e.g. bank, locum, apprentice.",
            "items": {
              "type": "string"
            }
          },
          "locations": {
            "title": "Locations (town, city or postcode)",
            "type": "array",
            "description": "For NHS Jobs this is NHS Jobs' own location search with the radius below. For Teaching Vacancies it keeps jobs whose address, postcode, local authority, region or school name contains the text.",
            "items": {
              "type": "string"
            }
          },
          "distanceMiles": {
            "title": "Distance from location (miles)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Search radius used with Locations for NHS Jobs.",
            "default": 10
          },
          "regions": {
            "title": "Regions",
            "type": "array",
            "description": "Keep jobs in these UK regions. Region comes from the job's postcode (postcodes.io, ONS data) or the source's own region field.",
            "items": {
              "type": "string",
              "enum": [
                "North East",
                "North West",
                "Yorkshire and The Humber",
                "East Midlands",
                "West Midlands",
                "East of England",
                "London",
                "South East",
                "South West",
                "Wales",
                "Scotland",
                "Northern Ireland"
              ]
            }
          },
          "salaryMin": {
            "title": "Minimum annual salary (GBP)",
            "minimum": 0,
            "type": "integer",
            "description": "Keep jobs whose normalised annual salary (top of the range) is at least this. Hourly/daily pay is annualised (37.5 h × 52 weeks; 260 days). Jobs with no salary information are dropped when this is set."
          },
          "nhsBands": {
            "title": "NHS Agenda for Change bands",
            "type": "array",
            "description": "Applies to NHS Jobs only (other sources are not affected). Uses NHS Jobs' own pay-band filter, so it is exact.",
            "items": {
              "type": "string",
              "enum": [
                "2",
                "3",
                "4",
                "5",
                "6",
                "7",
                "8a",
                "8b",
                "8c",
                "8d",
                "9"
              ],
              "enumTitles": [
                "Band 2",
                "Band 3",
                "Band 4",
                "Band 5",
                "Band 6",
                "Band 7",
                "Band 8a",
                "Band 8b",
                "Band 8c",
                "Band 8d",
                "Band 9"
              ]
            }
          },
          "teacherPayScales": {
            "title": "Teacher pay scales",
            "type": "array",
            "description": "Applies to Teaching Vacancies only (other sources are not affected). Keeps jobs that mention these pay ranges (MPS/M1-M6, UPS/U1-U3, Leadership/L-points, unqualified, lead practitioner) or whose salary matches a national range.",
            "items": {
              "type": "string",
              "enum": [
                "MPS",
                "UPS",
                "Leadership",
                "Unqualified",
                "LeadPractitioner"
              ],
              "enumTitles": [
                "Main pay scale (MPS)",
                "Upper pay scale (UPS)",
                "Leadership",
                "Unqualified teacher",
                "Lead practitioner"
              ]
            }
          },
          "teachingJobRoles": {
            "title": "Teaching Vacancies job roles",
            "type": "array",
            "description": "Teaching Vacancies only: keep these job roles.",
            "items": {
              "type": "string",
              "enum": [
                "teacher",
                "headteacher",
                "deputy_headteacher",
                "assistant_headteacher",
                "head_of_year_or_phase",
                "head_of_department_or_curriculum",
                "sendco",
                "other_leadership",
                "teaching_assistant",
                "higher_level_teaching_assistant",
                "education_support",
                "pastoral_health_and_welfare",
                "administration_hr_data_and_finance",
                "catering_cleaning_and_site_management",
                "it_support",
                "other_support"
              ],
              "enumTitles": [
                "Teacher",
                "Headteacher",
                "Deputy headteacher",
                "Assistant headteacher",
                "Head of year or phase",
                "Head of department or curriculum",
                "SENDCo",
                "Other leadership",
                "Teaching assistant",
                "Higher level teaching assistant (HLTA)",
                "Education support",
                "Pastoral, health and welfare",
                "Administration, HR, data and finance",
                "Catering, cleaning and site management",
                "IT support",
                "Other support"
              ]
            }
          },
          "contractTypes": {
            "title": "Contract types",
            "type": "array",
            "description": "Keep jobs with these normalised contract types.",
            "items": {
              "type": "string",
              "enum": [
                "permanent",
                "fixed_term",
                "temporary",
                "contract",
                "bank",
                "locum",
                "apprenticeship",
                "training",
                "voluntary"
              ]
            }
          },
          "workingPatterns": {
            "title": "Working pattern",
            "type": "array",
            "description": "Keep full-time and/or part-time jobs. Jobs offered as either count for both.",
            "items": {
              "type": "string",
              "enum": [
                "full_time",
                "part_time"
              ],
              "enumTitles": [
                "Full-time",
                "Part-time"
              ]
            }
          },
          "postedWithinDays": {
            "title": "Posted within last N days",
            "minimum": 0,
            "type": "integer",
            "description": "0 = no filter. Speeds up runs a lot (sources are read newest-first and paging stops early).",
            "default": 0
          },
          "closingWithinDays": {
            "title": "Closing soon: closes within N days",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only jobs whose closing date is today or within the next N days (e.g. 3). Empty or 0 = no filter. Jobs without a closing date are dropped when set."
          },
          "onlyNewJobs": {
            "title": "Only new jobs since last run (monitoring mode)",
            "type": "boolean",
            "description": "Remembers job IDs in a named key-value store and outputs only jobs not seen in previous runs with the same filters. Ideal for scheduled daily runs and alerts.",
            "default": false
          },
          "monitoringStateKey": {
            "title": "Monitoring state key (optional)",
            "type": "string",
            "description": "By default the 'seen jobs' memory is keyed on your filters, so different saved tasks don't interfere. Set a name to share or reset the memory explicitly."
          },
          "includeEmployerSummary": {
            "title": "Add a hiring summary per employer",
            "type": "boolean",
            "description": "One extra record per trust, school or employer among the matched jobs: open roles, posted in last 7/30 days, closing within 7 days, NHS band mix, teacher pay scale mix, median salary, regions and new since last run. In monitoring mode only employers with new jobs get a summary. Charged per summary.",
            "default": false
          },
          "summaryMinJobs": {
            "title": "Only summarise employers with at least N matched jobs",
            "minimum": 1,
            "type": "integer",
            "description": "Skip small employers to keep summary count (and cost) down.",
            "default": 1
          },
          "includeDescription": {
            "title": "Include job description",
            "type": "boolean",
            "description": "Teaching Vacancies gives full descriptions. NHS Jobs' feed gives a short summary; turn on 'NHS: fetch full advert' for the full text.",
            "default": true
          },
          "includeHtml": {
            "title": "Also include description HTML",
            "type": "boolean",
            "description": "Adds descriptionHtml where the source provides it.",
            "default": false
          },
          "maxJobsPerSource": {
            "title": "Max jobs per source",
            "minimum": 0,
            "type": "integer",
            "description": "0 = unlimited. Newest jobs are kept first.",
            "default": 0
          },
          "maxTotalJobs": {
            "title": "Max total jobs (cost cap)",
            "minimum": 0,
            "type": "integer",
            "description": "Stop pushing job results after this many. 0 = unlimited.",
            "default": 0
          },
          "nhsFetchDetails": {
            "title": "NHS: fetch full advert for each job",
            "type": "boolean",
            "description": "One extra request per output NHS job: full description, pay scheme, exact band from the advert, working pattern and reference. Slower; use with filters or caps.",
            "default": false
          },
          "nhsExactBands": {
            "title": "NHS: exact band tagging",
            "type": "boolean",
            "description": "Runs NHS Jobs' own pay-band filter for each band so every Agenda for Change job gets its exact band (about twice the API requests). Off = band detected from the title or salary.",
            "default": true
          },
          "lookupPostcodes": {
            "title": "Look up region and local authority from postcode",
            "type": "boolean",
            "description": "Uses the free postcodes.io API (ONS open data) in batches of 100. Off = approximate region from the postcode area.",
            "default": true
          },
          "requestDelaySecs": {
            "title": "Delay between requests to the same host (seconds)",
            "minimum": 0.2,
            "type": "number",
            "description": "Politeness delay per host.",
            "default": 0.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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}