API
Public read-only API for roles and tracked companies. Berlin is the default market for existing clients. Hamburg and Munich become available when each city is public. The API uses the website's filter vocabulary and returns the original ATS URL in a stable JSON shape.
Source license: the jobs feed and company list are released under CC0; see Terms for the full text.
Machine-readable contract: OpenAPI 3.1.
Paginated list of currently-active roles. Same filter vocabulary as the /jobs page.
| Param | Type | Description |
|---|---|---|
market | string | berlin, hamburg, munich, or paris. Defaults to berlin. Cities return 404 until public. |
page | integer | Page number (1-based). Default 1. |
pageSize | integer | Rows per page. Default 25, max 100. |
sector | string | Comma-separated sector keys. Same set as the /jobs filter. |
stage | string | Comma-separated company-stage keys. |
role | string | Comma-separated role-family ids, such as `finance,legal`. Matches either family using stored classification. Unclassified jobs are excluded. See OpenAPI for all accepted ids. |
german | string | German cities only. Comma of `needed`, `not_needed`, `unknown`. Paris rejects this filter. |
seniority | string | Comma-separated seniority strings. |
contract | string | Comma-separated contract-type strings. |
location | string | Comma-separated location strings. |
visa | boolean | Pass `1` to limit to roles whose hybrid visa filter returns sponsors. |
postedWithin | string | One of `7d`, `30d`, `90d`, `all`. |
q | string | Free-text query against title. |
Single role by full UUID or the 8-character suffix used in /jobs/<slug>-<suffix> URLs.
| Param | Type | Description |
|---|---|---|
market | string | berlin, hamburg, munich, or paris. Defaults to berlin. Cities return 404 until public. |
All active companies plus a live open-role count. Not paginated because the allowlist is operator-curated.
| Param | Type | Description |
|---|---|---|
market | string | berlin, hamburg, munich, or paris. Defaults to berlin. Cities return 404 until public. |
sort | string | One of `alpha`, `hiring`, `recent`. Default alpha. |
Single company with all currently-active open roles inlined.
| Param | Type | Description |
|---|---|---|
market | string | berlin, hamburg, munich, or paris. Defaults to berlin. Cities return 404 until public. |
List endpoints return { data: T[], pagination }. Single-resource endpoints return { data: T }. Errors are { error: { status, message } } with the matching HTTP status. Every response sends Cache-Control: public, max-age=300, s-maxage=300, stale-while-revalidate=3600.
Every job and company has a markets array with public memberships only. An unknown or repeated market value returns 400. A known city that is not public returns 404. Job detail URLs stay shared across markets.
A job carries salaryMin, salaryMax, salaryCurrency and salaryPeriod only when the employer disclosed them. Pegel never estimates pay, so null means "not disclosed", never "we guessed". Treat it that way downstream. techTags is the classifier's stack read, and an empty array means no stack signal was found.
60 requests per minute per IP, fixed-window. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix seconds). When you hit the limit you get a 429 with Retry-After in seconds. Identifier is the first hop of x-forwarded-for — if you're behind a corporate egress NAT, your whole office shares one bucket.