{
  "openapi": "3.0.3",
  "info": {
    "title": "Job Spotter",
    "version": "1.1.0",
    "description": "Finds current job listings by keywords, place (a city, state, country or remote), level and how recently they were posted. Searches The Muse, Remotive, Himalayas, Jobicy, Remote OK and Arbeitnow together (plus Careerjet, USAJOBS and Adzuna when switched on), removes duplicates, understands that a developer job may be titled engineer, puts title matches first, then tag and description matches, newest first in each group, and turns each description into a short summary. Remote searches without a country put jobs open to the US first. When few jobs turn up, search_elsewhere gives ready search links for Indeed, LinkedIn, CareerOneStop and USAJOBS. Every result carries the original apply link and the name of the job board it came from; listings from Remotive, Himalayas, Jobicy and Remote OK must be credited to them, which `say` does. Some links may come from job search partners that pay per click, stated in `disclosure`; that never changes the results or their order. Every answer has a ready-to-read `say` line. Read only, no account, nothing stored. It never applies for jobs on the user's behalf.",
    "contact": { "email": "hello@askmizan.com" }
  },
  "servers": [{ "url": "https://jobspotter.pages.dev" }],
  "paths": {
    "/v1/jobs": {
      "get": {
        "operationId": "searchJobs",
        "summary": "Search current job listings",
        "description": "Use for \"find remote Python jobs\", \"marketing jobs in New York\", \"junior data analyst jobs posted this week\", \"senior software engineer jobs in London\". Put the job words in what and the place in where. Everyday phrasing in what also works: level words (junior, senior), \"remote\", \"in <city>\" and \"this week\" are picked out. Read out `say`. Listings from Remotive, Himalayas, Jobicy and Remote OK must be credited to them, which `say` already does. If there are no or few results, offer the search_elsewhere links.",
        "parameters": [
          { "name": "what", "in": "query", "required": false, "description": "Job title, skill or field, for example \"python developer\" or \"marketing\". Required unless where is given.", "schema": { "type": "string", "maxLength": 80 } },
          { "name": "where", "in": "query", "required": false, "description": "A city (New York, Austin, TX, London), a US state (Texas), a country (USA, UK, Germany), \"remote\", or remote in a country (\"remote US\").", "schema": { "type": "string", "maxLength": 60 } },
          { "name": "level", "in": "query", "required": false, "description": "entry (junior, graduate, intern), mid or senior.", "schema": { "type": "string", "enum": ["entry", "mid", "senior"] } },
          { "name": "posted_within_days", "in": "query", "required": false, "description": "Only jobs posted in the last N days, 1 to 90. Default 30. Use 7 for \"this week\".", "schema": { "type": "integer", "minimum": 1, "maximum": 90 } },
          { "name": "limit", "in": "query", "required": false, "description": "How many results, 1 to 10. Default 10.", "schema": { "type": "integer", "minimum": 1, "maximum": 10 } }
        ],
        "responses": { "200": { "description": "Jobs with title, company, location, posted date, summary, apply_url, source and say, plus search_elsewhere links and a disclosure when partner links are used" }, "400": { "description": "Missing or invalid input" }, "503": { "description": "All job boards unavailable" } }
      }
    },
    "/v1/job": {
      "get": {
        "operationId": "getJob",
        "summary": "Details for one job from a search result",
        "description": "Use when the user asks about one of the results, for example \"tell me more about the second one\" or \"what's the apply link for the Uber job?\". Pass the id from a /v1/jobs result.",
        "parameters": [ { "name": "id", "in": "query", "required": true, "description": "The id from a /v1/jobs result, for example muse-22049500, remotive-2091141 or jobicy-153808.", "schema": { "type": "string", "maxLength": 200 } } ],
        "responses": { "200": { "description": "Job details with a longer summary, apply_url, source and say" }, "400": { "description": "Missing or malformed id" }, "404": { "description": "Job no longer listed" }, "503": { "description": "Job board unavailable" } }
      }
    },
    "/v1/health": { "get": { "operationId": "health", "summary": "Service status", "description": "For monitoring only.", "responses": { "200": { "description": "OK" } } } }
  }
}
