{
  "openapi": "3.1.0",
  "info": {
    "title": "Trawle API",
    "version": "1.0.0",
    "description": "Open jobs straight from employers' own applicant tracking systems, verified daily, with closure and repost history.\n\n- Data refreshes once a day; polling more often returns the same results.\n- Build a `JobQuery` from ids: resolve place names with `GET /v1/places`, roles with `GET /v1/roles`, companies with `GET /v1/companies`.\n- For a daily \"new jobs\" check, pass the previous response's `nextSince` as `postedSince`.\n- Results link to the employer's posting (`applyUrl`) and to Trawle (`url`). Show \"Data by Trawle\" with a link when you display them.\n- Full job descriptions are not served; link to `applyUrl`."
  },
  "servers": [
    {
      "url": "https://trawle.com"
    }
  ],
  "components": {
    "securitySchemes": {},
    "schemas": {
      "SearchJobsResult": {
        "type": "object",
        "properties": {
          "jobs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobSummary"
            }
          },
          "total": {
            "type": "integer",
            "description": "Matches, capped at 10,000 (`totalCapped`)."
          },
          "totalCapped": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": ["string", "null"],
            "description": "Next page; null on the last."
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Names for the ids and slugs in the query, keyed `filter:value` (`places:2618425` → `Copenhagen`). Unknown values are absent and matched nothing."
          },
          "dataDate": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "When the data was last refreshed (daily)."
          },
          "nextSince": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "Pass as `postedSince` on the next scheduled run to get only jobs that are new since this one."
          }
        },
        "required": [
          "jobs",
          "total",
          "totalCapped",
          "nextCursor",
          "labels",
          "dataDate",
          "nextSince"
        ]
      },
      "JobSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable public id; never changes across scans.",
            "example": "1234567"
          },
          "title": {
            "type": "string"
          },
          "company": {
            "$ref": "#/components/schemas/CompanyRef"
          },
          "role": {
            "$ref": "#/components/schemas/Ref"
          },
          "family": {
            "$ref": "#/components/schemas/Ref"
          },
          "locations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlaceRef"
            },
            "description": "Where the job is located (or, for remote jobs, who may apply), most specific first."
          },
          "workplace": {
            "type": ["string", "null"],
            "enum": ["remote", "hybrid", "onsite", null]
          },
          "remoteScope": {
            "type": ["string", "null"],
            "description": "For remote jobs: who may apply, in words (\"Anywhere\", \"United States only\")."
          },
          "seniority": {
            "type": ["string", "null"],
            "enum": [
              "intern",
              "entry",
              "mid",
              "senior",
              "lead",
              "principal",
              "director",
              "vp",
              "executive",
              null
            ]
          },
          "employmentType": {
            "type": ["string", "null"],
            "enum": [
              "full_time",
              "part_time",
              "contract",
              "temporary",
              "internship",
              "apprenticeship",
              "seasonal",
              "volunteer",
              null
            ]
          },
          "salary": {
            "$ref": "#/components/schemas/Salary"
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "First seen by Trawle under this id."
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "Last time a daily scan saw it open on the employer's site."
          },
          "postedAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "\"Date posted\" from the employer's ATS, when it has one. Often unreliable."
          },
          "openSince": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "First time any posting of this job (reposts included) was seen; days open count from here."
          },
          "repostCount": {
            "type": "integer",
            "description": "Earlier postings of this job under other ids, plus reopenings. 0 = original."
          },
          "closedAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "When it disappeared; null while open."
          },
          "applyUrl": {
            "type": "string",
            "description": "The employer's own posting (their ATS)."
          },
          "url": {
            "type": "string",
            "description": "This job on Trawle."
          }
        },
        "required": [
          "id",
          "title",
          "company",
          "role",
          "family",
          "locations",
          "workplace",
          "remoteScope",
          "seniority",
          "employmentType",
          "salary",
          "firstSeenAt",
          "lastSeenAt",
          "postedAt",
          "openSince",
          "repostCount",
          "closedAt",
          "applyUrl",
          "url"
        ]
      },
      "CompanyRef": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "stripe"
          },
          "name": {
            "type": "string",
            "example": "Stripe"
          },
          "domain": {
            "type": ["string", "null"],
            "example": "stripe.com"
          }
        },
        "required": ["slug", "name", "domain"]
      },
      "Ref": {
        "type": ["object", "null"],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": ["slug", "name"]
      },
      "PlaceRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "GeoNames id (regions are negative)."
          },
          "name": {
            "type": "string",
            "example": "Copenhagen"
          },
          "country": {
            "type": ["string", "null"],
            "description": "ISO 3166-1 alpha-2 country code; null for multi-country regions.",
            "example": "DK"
          }
        },
        "required": ["id", "name", "country"]
      },
      "Salary": {
        "type": ["object", "null"],
        "properties": {
          "min": {
            "type": ["integer", "null"]
          },
          "max": {
            "type": ["integer", "null"]
          },
          "currency": {
            "type": ["string", "null"],
            "description": "ISO 4217 code.",
            "example": "EUR"
          },
          "period": {
            "type": "string",
            "enum": ["year", "month", "week", "day", "hour"]
          }
        },
        "required": ["min", "max", "currency", "period"],
        "description": "Pay as the employer listed it (not converted)."
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable: `invalid_request`, `not_found`, `forbidden`, `rate_limited`, `internal`.",
                "example": "invalid_request"
              },
              "message": {
                "type": "string",
                "example": "places: expected an array of GeoNames ids"
              },
              "hint": {
                "type": "string",
                "description": "What to do next, e.g. which lookup to call first.",
                "example": "Resolve place names to ids with GET /v1/places?q="
              },
              "issues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": ["path", "message"]
                },
                "description": "Validation problems, one per invalid field."
              }
            },
            "required": ["code", "message"]
          }
        },
        "required": ["error"]
      },
      "SearchJobsRequest": {
        "type": "object",
        "properties": {
          "query": {
            "$ref": "#/components/schemas/JobQuery"
          },
          "cursor": {
            "type": ["string", "null"],
            "description": "`nextCursor` from the previous page."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Default 25."
          },
          "postedSince": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "Only jobs first seen at or after this instant. Scheduled agents pass the `nextSince` of their previous run to get only new jobs."
          }
        },
        "required": ["query"]
      },
      "JobQuery": {
        "type": "object",
        "properties": {
          "q": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100,
            "description": "Free text. Every word must start a word of the job title or department (any order, `react` matches \"React/TypeScript\"), or every word must start a word of the company name.",
            "example": "react"
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]{0,79}$"
            },
            "minItems": 1,
            "maxItems": 20,
            "description": "Role slugs, any of them. Look slugs up with `GET /v1/roles?q=` (MCP `find_occupation`).",
            "example": ["frontend-engineer"]
          },
          "families": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]{0,79}$"
            },
            "minItems": 1,
            "maxItems": 10,
            "description": "Job family slugs (any role in the field). List them with `GET /v1/families`.",
            "example": ["software-engineering"]
          },
          "places": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 1,
            "maxItems": 20,
            "description": "Where the person wants to work from, as GeoNames ids (multi-country regions are negative, `-1` is worldwide). Matches onsite/hybrid jobs located in the place plus remote jobs open to people living there. Look ids up with `GET /v1/places?q=` (MCP `resolve_location`).",
            "example": [2618425]
          },
          "companies": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]{0,79}$"
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Company slugs. Look them up with `GET /v1/companies?q=`.",
            "example": ["stripe"]
          },
          "workplace": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["remote", "hybrid", "onsite"]
            },
            "minItems": 1,
            "example": ["remote", "hybrid"]
          },
          "seniority": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "intern",
                "entry",
                "mid",
                "senior",
                "lead",
                "principal",
                "director",
                "vp",
                "executive"
              ]
            },
            "minItems": 1,
            "example": ["senior"]
          },
          "employment": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "full_time",
                "part_time",
                "contract",
                "temporary",
                "internship",
                "apprenticeship",
                "seasonal",
                "volunteer"
              ]
            },
            "minItems": 1,
            "example": ["full_time"]
          },
          "postingLanguages": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[a-z]{2}$"
            },
            "minItems": 1,
            "maxItems": 10,
            "description": "Languages the posting is written in, ISO 639-1, any of them. Detected from the description; jobs without one never match. Not the languages a job requires (`JobDetail.languages`).",
            "example": ["en"]
          },
          "salary": {
            "$ref": "#/components/schemas/SalaryRange"
          },
          "pay": {
            "type": "string",
            "enum": ["listed"],
            "description": "`listed`: only jobs that show pay."
          },
          "posted": {
            "type": "string",
            "enum": ["1d", "3d", "7d", "30d"],
            "description": "First seen by Trawle within this window. For scheduled agents, prefer `postedSince` with the `nextSince` of the previous run."
          },
          "reposts": {
            "type": "string",
            "enum": ["hide", "only"],
            "description": "Reposts are jobs seen before under another id, or closed and reopened. `hide` keeps only originals."
          },
          "sort": {
            "type": "string",
            "enum": ["newest", "pay"],
            "description": "`newest` (default) or `pay` (highest annual pay first; only jobs that show pay)."
          }
        },
        "description": "A job search. Values inside one filter are OR, filters are AND. The same object is used by the website's links and saved views."
      },
      "SalaryRange": {
        "type": "object",
        "properties": {
          "min": {
            "type": ["integer", "null"],
            "minimum": 0,
            "example": 60000
          },
          "max": {
            "type": ["integer", "null"],
            "minimum": 0,
            "example": null
          },
          "currency": {
            "type": "string",
            "enum": ["USD", "EUR", "GBP", "DKK", "SEK", "NOK", "CHF", "CAD", "AUD"]
          }
        },
        "required": ["min", "max", "currency"],
        "description": "Annual pay range, both ends inclusive, either end open (null). Jobs match when their own range overlaps it after converting currencies; jobs without pay never match."
      },
      "CheckJobStatusResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobStatus"
            },
            "description": "One item per distinct id asked for, in the order given."
          }
        },
        "required": ["items"]
      },
      "JobStatus": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "1234567"
          },
          "status": {
            "type": "string",
            "enum": ["open", "closed", "not_found"],
            "description": "`open`: still on the employer's site at the last daily scan. `closed`: gone from it. `not_found`: not a Trawle job id (or archived long ago); treat it as closed."
          },
          "closedAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "When it disappeared; null unless closed."
          },
          "lastSeenAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "Last daily scan that saw it open; null when not found."
          }
        },
        "required": ["id", "status", "closedAt", "lastSeenAt"]
      },
      "CheckJobStatusRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 20
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Job ids from earlier search results (`jobs[].id`), up to 100.",
            "example": ["1234567", "1234568"]
          }
        },
        "required": ["ids"]
      },
      "JobDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/JobSummary"
          },
          {
            "type": "object",
            "properties": {
              "company": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/CompanyRef"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "openJobs": {
                        "type": "integer"
                      },
                      "newLast30": {
                        "type": "integer"
                      },
                      "trend": {
                        "type": "array",
                        "items": {
                          "type": "integer"
                        },
                        "description": "Open jobs per day, oldest first, the last 90 days."
                      }
                    },
                    "required": ["openJobs", "newLast30", "trend"]
                  }
                ]
              },
              "department": {
                "type": ["string", "null"]
              },
              "summary": {
                "type": ["string", "null"],
                "description": "One-paragraph summary (generated)."
              },
              "skills": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "experienceYears": {
                "type": ["object", "null"],
                "properties": {
                  "min": {
                    "type": ["integer", "null"]
                  },
                  "max": {
                    "type": ["integer", "null"]
                  }
                },
                "required": ["min", "max"]
              },
              "visaSponsorship": {
                "type": ["string", "null"],
                "enum": ["yes", "no", null]
              },
              "education": {
                "type": ["string", "null"],
                "enum": [
                  "none",
                  "high_school",
                  "vocational",
                  "associate",
                  "bachelor",
                  "master",
                  "doctorate",
                  null
                ],
                "description": "Minimum required degree, if stated."
              },
              "managesPeople": {
                "type": ["boolean", "null"],
                "description": "Has direct reports (true), individual contributor (false), or not stated."
              },
              "relocation": {
                "type": ["boolean", "null"],
                "description": "Relocation support offered (true), explicitly not (false), or not stated."
              },
              "clearanceRequired": {
                "type": ["boolean", "null"],
                "description": "A government security clearance is required (true), explicitly not (false), or not stated."
              },
              "equityOffered": {
                "type": ["boolean", "null"],
                "description": "Equity (stock options, RSUs) offered (true), explicitly not (false), or not stated."
              },
              "languages": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Required languages, ISO 639-1."
              },
              "postingLanguage": {
                "type": ["string", "null"],
                "description": "Language the posting is written in, ISO 639-1 (detected).",
                "example": "en"
              },
              "source": {
                "type": "string",
                "description": "The ATS the job was read from (\"greenhouse\").",
                "example": "greenhouse"
              }
            },
            "required": [
              "department",
              "summary",
              "skills",
              "experienceYears",
              "visaSponsorship",
              "education",
              "managesPeople",
              "relocation",
              "clearanceRequired",
              "equityOffered",
              "languages",
              "postingLanguage",
              "source"
            ]
          }
        ]
      },
      "JobDescription": {
        "type": "object",
        "properties": {
          "markdown": {
            "type": ["string", "null"],
            "description": "The employer's description as stored at the last scan; null when none."
          }
        },
        "required": ["markdown"]
      },
      "SignInProviders": {
        "type": "object",
        "properties": {
          "email": {
            "type": "boolean",
            "description": "Magic-link sign-in by email."
          },
          "google": {
            "type": "boolean",
            "description": "\"Continue with Google\"."
          }
        },
        "required": ["email", "google"]
      },
      "SiteStats": {
        "type": "object",
        "properties": {
          "openJobs": {
            "type": "integer"
          },
          "companies": {
            "type": "integer",
            "description": "Companies with at least one open job."
          },
          "newToday": {
            "type": "integer",
            "description": "Open jobs first seen in the last 24 hours."
          },
          "dataDate": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z"
          },
          "historyStart": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z",
            "description": "First day of Trawle's own history; earlier dates come from employers."
          }
        },
        "required": ["openJobs", "companies", "newToday", "dataDate", "historyStart"]
      },
      "Company": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CompanyRef"
          },
          {
            "type": "object",
            "properties": {
              "description": {
                "type": ["string", "null"]
              },
              "industry": {
                "type": ["string", "null"]
              },
              "hq": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PlaceRef"
                  },
                  {
                    "type": ["object", "null"]
                  }
                ]
              },
              "careersUrl": {
                "type": ["string", "null"]
              },
              "url": {
                "type": "string",
                "description": "This company on Trawle."
              },
              "stats": {
                "type": "object",
                "properties": {
                  "openJobs": {
                    "type": "integer"
                  },
                  "newLast7": {
                    "type": "integer"
                  },
                  "closedLast30": {
                    "type": "integer"
                  },
                  "medianDaysOpen": {
                    "type": ["integer", "null"]
                  },
                  "repostShare": {
                    "type": "number",
                    "description": "Share of open jobs that are reposts (0–1)."
                  },
                  "trend": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Open jobs per day, oldest first, the last 90 days."
                  }
                },
                "required": [
                  "openJobs",
                  "newLast7",
                  "closedLast30",
                  "medianDaysOpen",
                  "repostShare",
                  "trend"
                ]
              },
              "families": {
                "type": "array",
                "items": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Ref"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        }
                      },
                      "required": ["count"]
                    }
                  ]
                }
              },
              "places": {
                "type": "array",
                "items": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PlaceRef"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        }
                      },
                      "required": ["count"]
                    }
                  ]
                }
              }
            },
            "required": [
              "description",
              "industry",
              "hq",
              "careersUrl",
              "url",
              "stats",
              "families",
              "places"
            ]
          }
        ]
      },
      "CompanyMatch": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CompanyRef"
          },
          {
            "type": "object",
            "properties": {
              "industry": {
                "type": ["string", "null"]
              },
              "openJobs": {
                "type": "integer"
              }
            },
            "required": ["industry", "openJobs"]
          }
        ]
      },
      "PlaceMatch": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PlaceRef"
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["city", "metro", "admin1", "country", "region"]
              },
              "context": {
                "type": ["string", "null"],
                "description": "Where it is, for telling homonyms apart (\"Washington, United States\")."
              }
            },
            "required": ["kind", "context"]
          }
        ]
      },
      "RoleMatch": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Ref"
          },
          {
            "type": "object",
            "properties": {
              "family": {
                "$ref": "#/components/schemas/Ref"
              },
              "openJobs": {
                "type": "integer"
              }
            },
            "required": ["family", "openJobs"]
          }
        ]
      },
      "FamilyItem": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Ref"
          },
          {
            "type": "object",
            "properties": {
              "openJobs": {
                "type": "integer"
              }
            },
            "required": ["openJobs"]
          }
        ]
      },
      "Me": {
        "type": "object",
        "properties": {
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": ["id", "email", "name"]
          }
        },
        "required": ["user"]
      },
      "Agent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "query": {
            "$ref": "#/components/schemas/JobQuery"
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Names for the ids and slugs in `query`, keyed `filter:value` (`places:2618425` → `Copenhagen`)."
          },
          "prompt": {
            "type": ["string", "null"],
            "description": "The description it was made from."
          },
          "emailEnabled": {
            "type": "boolean",
            "description": "Email new matches after the daily scan."
          },
          "status": {
            "type": "string",
            "enum": ["active", "paused"]
          },
          "lastSentAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z"
          }
        },
        "required": [
          "id",
          "name",
          "query",
          "labels",
          "prompt",
          "emailEnabled",
          "status",
          "lastSentAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateAgent": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "query": {
            "$ref": "#/components/schemas/JobQuery"
          },
          "prompt": {
            "type": ["string", "null"],
            "maxLength": 300
          },
          "emailEnabled": {
            "type": "boolean",
            "description": "Default true."
          }
        },
        "required": ["name", "query"]
      },
      "DescribedAgent": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "A suggested name."
          },
          "query": {
            "$ref": "#/components/schemas/JobQuery"
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Names for the ids and slugs in `query`, keyed `filter:value` (`places:2618425` → `Copenhagen`)."
          },
          "unmatched": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Parts of the description that did not become a filter (shown to the person)."
          }
        },
        "required": ["name", "query", "labels", "unmatched"]
      },
      "DescribeAgentRequest": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "minLength": 3,
            "maxLength": 300,
            "example": "Senior React jobs in Copenhagen or remote in Europe, no reposts"
          }
        },
        "required": ["prompt"]
      },
      "AgentPreview": {
        "type": "object",
        "properties": {
          "matches": {
            "type": "integer",
            "description": "Open jobs matching now (capped at 10,000)."
          },
          "newLastWeek": {
            "type": "integer",
            "description": "Of those, first seen in the last 7 days: roughly what the agent will send."
          },
          "jobs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobSummary"
            },
            "description": "The newest few matches."
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Names for the ids and slugs in `query`, keyed `filter:value` (`places:2618425` → `Copenhagen`)."
          },
          "dataDate": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-31T06:12:00.000Z"
          }
        },
        "required": ["matches", "newLastWeek", "jobs", "labels", "dataDate"]
      },
      "PreviewAgentRequest": {
        "type": "object",
        "properties": {
          "query": {
            "$ref": "#/components/schemas/JobQuery"
          }
        },
        "required": ["query"]
      },
      "UpdateAgent": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "query": {
            "$ref": "#/components/schemas/JobQuery"
          },
          "emailEnabled": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": ["active", "paused"]
          }
        }
      }
    },
    "parameters": {}
  },
  "paths": {
    "/v1/jobs/search": {
      "post": {
        "operationId": "searchJobs",
        "tags": ["Jobs"],
        "summary": "Search open jobs",
        "description": "Open jobs matching a `JobQuery`, newest first (or by pay). Paginate with `cursor`. For a daily \"what's new\" run, store `nextSince` and pass it back as `postedSince` next time. Data refreshes once a day.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchJobsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A page of jobs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchJobsResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: see `error.issues` and `error.hint`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/status": {
      "post": {
        "operationId": "checkJobStatus",
        "tags": ["Jobs"],
        "summary": "Check whether jobs are still open",
        "description": "Bulk status for up to 100 job ids from earlier results: `open`, `closed` (with `closedAt`) or `not_found`. Use it to drop closed jobs from a list you are tracking, instead of fetching each job. Data refreshes once a day.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckJobStatusRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One status per id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckJobStatusResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: see `error.issues` and `error.hint`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": ["Jobs"],
        "summary": "Get a job",
        "description": "One job, open or closed, with the company's hiring activity. Closed jobs have `closedAt` set.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 20,
              "example": "1234567"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stats": {
      "get": {
        "operationId": "getStats",
        "tags": ["Meta"],
        "summary": "Index size and freshness",
        "responses": {
          "200": {
            "description": "Totals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteStats"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{slug}": {
      "get": {
        "operationId": "getCompany",
        "tags": ["Companies"],
        "summary": "Get a company and its hiring activity",
        "description": "Open jobs, new and closed jobs, median days open, repost share and a 90-day trend.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 80,
              "example": "stripe"
            },
            "required": true,
            "name": "slug",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies": {
      "get": {
        "operationId": "searchCompanies",
        "tags": ["Companies", "Lookups"],
        "summary": "Find companies by name or domain",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "Company name or domain.",
              "example": "stripe"
            },
            "required": true,
            "description": "Company name or domain.",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 8,
              "example": 8
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Best matches first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CompanyMatch"
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: see `error.issues` and `error.hint`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/places": {
      "get": {
        "operationId": "resolveLocation",
        "tags": ["Lookups"],
        "summary": "Find places (GeoNames) for the `places` filter",
        "description": "Cities, metro areas, states, countries and multi-country regions (\"EMEA\", \"Europe\", \"Anywhere\") whose name starts with `q`. Use `items[].id` in `JobQuery.places`; `context` tells homonyms apart.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "Place name.",
              "example": "copenhagen"
            },
            "required": true,
            "description": "Place name.",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 8,
              "example": 8
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Best matches first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PlaceMatch"
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: see `error.issues` and `error.hint`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/roles": {
      "get": {
        "operationId": "findRoles",
        "tags": ["Lookups"],
        "summary": "Find roles for the `roles` filter",
        "description": "Roles whose name or common job titles match `q` (\"react\" finds Frontend Engineer). Use `items[].slug` in `JobQuery.roles`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "Role or job title.",
              "example": "frontend"
            },
            "required": true,
            "description": "Role or job title.",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 8,
              "example": 8
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Best matches first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RoleMatch"
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: see `error.issues` and `error.hint`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/families": {
      "get": {
        "operationId": "listFamilies",
        "tags": ["Lookups"],
        "summary": "List job families for the `families` filter",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "Optional name filter.",
              "example": "engineering"
            },
            "required": false,
            "description": "Optional name filter.",
            "name": "q",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "All families, in browsing order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FamilyItem"
                      }
                    }
                  },
                  "required": ["items"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: see `error.issues` and `error.hint`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
