# Get a job

`GET https://trawle.com/v1/jobs/{id}`

One job, open or closed, with the company's hiring activity. Closed jobs have `closedAt` set.

## Path parameters

- `id` (string, required): 1 to 20 characters. Example: `1234567`.

## Responses

### 200: The job.

Schema: JobDetail

- `id` (string, required): Stable public id; never changes across scans. Example: `1234567`.
- `title` (string, required)
- `company` (object, required)
  - `slug` (string, required): Example: `stripe`.
  - `name` (string, required): Example: `Stripe`.
  - `domain` (string | null, required): Example: `stripe.com`.
  - `openJobs` (integer, required)
  - `newLast30` (integer, required)
  - `trend` (array<integer>, required): Open jobs per day, oldest first, the last 90 days.
- `role` (object | null, required, Ref)
  - `slug` (string, required)
  - `name` (string, required)
- `family` (object | null, required, Ref)
  - `slug` (string, required)
  - `name` (string, required)
- `locations` (array<object>, required, PlaceRef): Where the job is located (or, for remote jobs, who may apply), most specific first.
  - `id` (integer, required): GeoNames id (regions are negative).
  - `name` (string, required): Example: `Copenhagen`.
  - `country` (string | null, required): ISO 3166-1 alpha-2 country code; null for multi-country regions. Example: `DK`.
- `workplace` (string | null, required): One of: `remote`, `hybrid`, `onsite`.
- `remoteScope` (string | null, required): For remote jobs: who may apply, in words ("Anywhere", "United States only").
- `seniority` (string | null, required): One of: `intern`, `entry`, `mid`, `senior`, `lead`, `principal`, `director`, `vp`, `executive`.
- `employmentType` (string | null, required): One of: `full_time`, `part_time`, `contract`, `temporary`, `internship`, `apprenticeship`, `seasonal`, `volunteer`.
- `salary` (object | null, required, Salary): Pay as the employer listed it (not converted).
  - `min` (integer | null, required)
  - `max` (integer | null, required)
  - `currency` (string | null, required): ISO 4217 code. Example: `EUR`.
  - `period` (string, required): One of: `year`, `month`, `week`, `day`, `hour`.
- `firstSeenAt` (string<date-time>, required): First seen by Trawle under this id. Example: `2026-10-31T06:12:00.000Z`.
- `lastSeenAt` (string<date-time>, required): Last time a daily scan saw it open on the employer's site. Example: `2026-10-31T06:12:00.000Z`.
- `postedAt` (string<date-time> | null, required): "Date posted" from the employer's ATS, when it has one. Often unreliable. Example: `2026-10-31T06:12:00.000Z`.
- `openSince` (string<date-time>, required): First time any posting of this job (reposts included) was seen; days open count from here. Example: `2026-10-31T06:12:00.000Z`.
- `repostCount` (integer, required): Earlier postings of this job under other ids, plus reopenings. 0 = original.
- `closedAt` (string<date-time> | null, required): When it disappeared; null while open. Example: `2026-10-31T06:12:00.000Z`.
- `applyUrl` (string, required): The employer's own posting (their ATS).
- `url` (string, required): This job on Trawle.
- `department` (string | null, required)
- `summary` (string | null, required): One-paragraph summary (generated).
- `skills` (array<string>, required)
- `experienceYears` (object | null, required)
  - `min` (integer | null, required)
  - `max` (integer | null, required)
- `visaSponsorship` (string | null, required): One of: `yes`, `no`.
- `education` (string | null, required): Minimum required degree, if stated. One of: `none`, `high_school`, `vocational`, `associate`, `bachelor`, `master`, `doctorate`.
- `managesPeople` (boolean | null, required): Has direct reports (true), individual contributor (false), or not stated.
- `relocation` (boolean | null, required): Relocation support offered (true), explicitly not (false), or not stated.
- `clearanceRequired` (boolean | null, required): A government security clearance is required (true), explicitly not (false), or not stated.
- `equityOffered` (boolean | null, required): Equity (stock options, RSUs) offered (true), explicitly not (false), or not stated.
- `languages` (array<string>, required): Required languages, ISO 639-1.
- `postingLanguage` (string | null, required): Language the posting is written in, ISO 639-1 (detected). Example: `en`.
- `source` (string, required): The ATS the job was read from ("greenhouse"). Example: `greenhouse`.

### 404: Not found.

Schema: Error

- `error` (object, required)
  - `code` (string, required): Machine-readable: `invalid_request`, `not_found`, `forbidden`, `rate_limited`, `internal`. Example: `invalid_request`.
  - `message` (string, required): Example: `places: expected an array of GeoNames ids`.
  - `hint` (string, optional): What to do next, e.g. which lookup to call first. Example: `Resolve place names to ids with GET /v1/places?q=`.
  - `issues` (array<object>, optional): Validation problems, one per invalid field.
    - `path` (string, required)
    - `message` (string, required)

## Examples

### cURL

```bash
curl "https://trawle.com/v1/jobs/1234567"
```

### TypeScript

```ts
import createClient from "openapi-fetch";

// npx openapi-typescript https://developers.trawle.com/openapi.json -o trawle.d.ts
import type { paths } from "./trawle";

const trawle = createClient<paths>({ baseUrl: "https://trawle.com" });

const { data, error } = await trawle.GET("/v1/jobs/{id}", {
  params: {
    path: {
      id: "1234567",
    },
  },
});
```

### Python

```python
import requests

response = requests.get(
    "https://trawle.com/v1/jobs/1234567",
)
response.raise_for_status()
data = response.json()
```

### Response 200

```json
{
  "id": "1234567",
  "title": "string",
  "company": {
    "slug": "stripe",
    "name": "Stripe",
    "domain": "stripe.com",
    "openJobs": 0,
    "newLast30": 0,
    "trend": [0]
  },
  "role": {
    "slug": "string",
    "name": "string"
  },
  "family": {
    "slug": "string",
    "name": "string"
  },
  "locations": [
    {
      "id": 0,
      "name": "Copenhagen",
      "country": "DK"
    }
  ],
  "workplace": "remote",
  "remoteScope": "string",
  "seniority": "intern",
  "employmentType": "full_time",
  "salary": {
    "min": 0,
    "max": 0,
    "currency": "EUR",
    "period": "year"
  },
  "firstSeenAt": "2026-10-31T06:12:00.000Z",
  "lastSeenAt": "2026-10-31T06:12:00.000Z",
  "postedAt": "2026-10-31T06:12:00.000Z",
  "openSince": "2026-10-31T06:12:00.000Z",
  "repostCount": 0,
  "closedAt": "2026-10-31T06:12:00.000Z",
  "applyUrl": "string",
  "url": "string",
  "department": "string",
  "summary": "string",
  "skills": ["string"],
  "experienceYears": {
    "min": 0,
    "max": 0
  },
  "visaSponsorship": "yes",
  "education": "none",
  "managesPeople": true,
  "relocation": true,
  "clearanceRequired": true,
  "equityOffered": true,
  "languages": ["string"],
  "postingLanguage": "en",
  "source": "greenhouse"
}
```

### Response 404

```json
{
  "error": {
    "code": "not_found",
    "message": "Job not found",
    "hint": "Job ids come from search results (`jobs[].id`)."
  }
}
```
