Skip to content
Pegel Jobs

Methodology

This page exists for two reasons. Most people who land on Pegel want to know how the inventory gets here. The smaller second group, mostly other founders and the occasional journalist, want to know how the AI parts work and what kind of project they're looking at. Both groups get answered below.

How the inventory gets here

Pegel tracks companies with Berlin-relevant roles and a public hiring feed it can read reliably. Most use an applicant tracking system. Pegel has dedicated adapters for the common providers and a generic RSS fallback for compatible feeds.

Pegel polls those feeds three times a day. Six staggered batches run ten minutes apart in windows beginning at 04:05, 10:05 and 16:05 UTC, scheduled through Upstash QStash. The batching avoids sending the whole company list at once. If one batch fails, the others can still complete and QStash can retry the failed delivery.

When a role appears in a feed, it gets ingested. When a role stops appearing in a feed for three days in a row, it gets marked expired. The job description displayed on Pegel is verbatim from the source. Pegel does not edit it. It does not summarize it inline. It does not "improve" anything.

Sometimes the company feed keeps a role after its application URL is already gone. Pegel checks that link separately. One 404 or 410 only records evidence; the same conclusive result twice marks the role expired. Bot blocks and rate limits do not count as proof. Neither do network failures.

The company list is curated by hand. There's a YAML file in the repository with entries like:

- slug: n26
  name: N26
  sector: fintech
  stage: series_d
  ats_provider: greenhouse
  ats_handle: n26

If a Berlin startup is not on the list, suggest one via the submit form linked in the footer. Submissions are reviewed manually, and companies that fit the documented scope get added.

How the classifications work

Five structured classification fields run in production. The one most people notice is the language requirement. It assigns one of two supported answers: German required, or English (no German needed). A role either needs German to do the work or it does not. "German is a plus" counts as not needed. The other live fields cover visa evidence and disclosed salary. Tech-stack tags and remote mode are also classified. A one-line English summary path exists in the codebase but is not active on live role pages.

The language classifier has two stages. A heuristic pass first checks for explicit evidence that German is required or optional. When the heuristics are confident, that's the answer. When they aren't, the role is handed to a language model for a more nuanced read. That model runs on its own daily schedule, under a flat-rate subscription to a third-party AI provider rather than a pay-per-call API, and off the request path rather than inline during the crawl.

Each classification has a confidence level and a source ("heuristic" or "llm" or "company_default"). When the confidence falls below a threshold, the field is shown as null instead of getting a confident wrong answer. Filters respect this: if a role's language requirement is null, it doesn't appear when you filter for "no German required."

The language and visa classifiers have hand-labeled evaluation sets. A new version must reach 95% accuracy before production release. Per-tier accuracy is tracked separately, so a classifier that performs well on "German required" but poorly on "English" does not pass. The other live fields use deterministic fixtures and focused unit tests; Pegel does not claim an evaluation-set score for them.

Salary transparency

Most Berlin postings don't say what the job pays. When an employer does say, Pegel repeats the figure exactly as published. When an employer doesn't, Pegel shows nothing. It never estimates a band, and it never infers one from headcount or seniority. A salary you see here came out of the job description. A salary you don't see was never in it.

The "Salary disclosed only" filter on the jobs page exists so you can see how small that set still is.

Member states had until 7 June 2026 to write the EU Pay Transparency Directive (2023/970) into national law. Germany missed the deadline. As of July 2026 no draft bill has been published, and the responsible ministry has signalled the law will take effect in early 2027, with the pay-reporting duties biting later than that. Until then the 2017 Entgelttransparenzgesetz is what binds private employers here, and it says nothing about what a job posting has to disclose.

One part of the directive gets misreported often enough to be worth stating plainly: it does not require employers to print a salary in the job advertisement. Article 5 gives applicants the right to be told the starting pay or its range before pay gets negotiated, and it bars employers from asking what you currently earn. Publishing the range in the ad is one permitted way to satisfy that right, not an obligation. A Berlin posting with no salary on it breaks no rule today.

Where a posting does disclose a salary in euros per year, Pegel compares the bottom of the range against the two EU Blue Card salary thresholds that Germany resets every January. For 2026 they are €50,700 gross a year, and a reduced €45,934.20. Both are fixed percentages of the pension insurance contribution ceiling (50% and 45.3%) under § 18g of the Aufenthaltsgesetz, so both move each year.

The chip on a role says one thing: the salary this employer published reaches that bar. It does not say the role is Blue Card eligible, and Pegel has no way to know whether it is. A Blue Card also needs a recognized university degree, though ICT roles can substitute three years of comparable experience. It needs a concrete job offer matching that qualification, on a contract of at least six months. The reduced threshold is narrower than it sounds: it covers a fixed list of occupation groups, mostly engineering, ICT, medicine and teaching, plus anyone who finished a degree within the last three years, and those cases need the Bundesagentur für Arbeit to sign off. Applicants over 45 entering Germany for the first time face a higher bar again, 55% of the same ceiling, which is €55,770 in 2026. Whether any of this applies to you is a question for a lawyer or the Ausländerbehörde. It is not something a job board can answer.

Four rules govern the comparison, and each errs toward showing nothing:

  • Pegel reads the bottom of a range and never the top. A role advertised at €40,000 to €90,000 gets no chip, because €40,000 is the number the employer committed to.
  • A salary posted in a currency other than the euro gets no chip. Converting it at some exchange rate would invent a euro figure nobody published.
  • A monthly or hourly rate gets no chip. Annualizing it needs an assumed working year, and that is an estimate.
  • A salary of exactly €45,934 gets no chip. The reduced threshold is €45,934.20, and twenty cents short is short.

Generated prose

Pegel does not currently generate summaries or commentary on live role pages. Both paths stay dormant until their accuracy controls are verified and their disclosure treatment is settled. If that changes, this page and the changelog will be updated before generated prose appears publicly.

How Pegel uses AI

A summary, for the curious or the regulatory:

  • Deterministic first pass: the poll applies evidence rules without calling a language model.
  • Scheduled model task: a third-party language model reviews some German-requirement cases the deterministic pass cannot resolve. It runs off the request path under a flat-rate subscription.
  • What is sent: public job-description text only. Subscriber data is never included.
  • What remains dormant: one-line summaries and per-job commentary.
  • What AI is not used for: ranking roles or scoring candidates. It is not used for candidate matching or anything involving the subscriber list.

The European Commission's final Article 50 guidance distinguishes extracted structured labels from generated prose. Pegel's live labels fall on the structured side. The dormant summary and the planned commentary do not, so neither can be activated until the marking duties and visible disclosure are verified.

Pegel does not auto-publish articles. When AI helps with a draft about a matter of public interest, the founder checks the factual claims against their sources and edits the substance after the last AI change. The founder takes editorial responsibility before publication. Text that does not receive that review must carry a clear AI label or stay unpublished.

Classifier outputs are observations. They can be wrong. When a label looks wrong, send an email with the role link and the supporting text. The result gets reviewed and corrected when the evidence supports that. Cases that expose a reusable gap go into the evaluation set.

What data Pegel collects from you

If you subscribe to the daily digest:

  • Your email address
  • Your filter preferences (which kinds of roles you want)
  • Confirmation and last-sent timestamps
  • A confirmation token
  • Unsubscribe and manage tokens

Pegel does not add a name or profile to the subscription record. It does not store an IP address with that record. The full breakdown is in the Privacy Policy. There are no public user accounts and no tracking cookies.

If you browse the site without subscribing, Pegel knows nothing about you beyond what your browser sends to Cloudflare's logs (request URL, user agent, approximate region). Cloudflare Web Analytics is cookieless and collects aggregate counts only.

What Pegel doesn't do

  • It doesn't sell, share, or trade your data with anyone
  • It doesn't build a per-person history of the jobs you view. Email open and click tracking are disabled
  • It doesn't accept money from employers or recruiters
  • It doesn't rank jobs by any algorithm other than recency (first-seen-at)
  • It doesn't auto-translate German job descriptions (it labels them clearly and you decide)
  • It doesn't estimate salary ranges (only what the employer disclosed is shown)
  • It doesn't keep a missing role active indefinitely. The three-day confirmation window is described below

Ghost roles

A role that's been open past 90 days, or that's been seen as expired and reposted at least twice, gets called a ghost role. The signal isn't a judgment about the company. It can mean the role is hard to fill, or it can mean the team forgot to take down a posting that's already filled. Either way, the number is what it is, and you can decide whether it matters for your search.

On the listings Pegel shows the underlying number: "Open 142 days", "Reposted 4x". The word "ghost" only appears on the /jobs sidebar (a toggle to hide them) and on /companies/[slug] (a small line counting how many of the company's open roles meet the predicate). The badges themselves stay literal.

The 90-day and 2-repost thresholds are calibration points. They will be adjusted once Pegel has been running long enough to see what actually predicts a useless role.

How current the data is

The "Last updated" line on listings pages tells you exactly when the last poll completed. The three daily polling windows start at 04:05, 10:05 and 16:05 UTC. The roles shown after each window reflect what was in each company's ATS during that run.

A role posted at noon should appear after the late-afternoon UTC poll, provided the source feed responds. A role removed from the ATS today is still shown on the site for up to three days while the system confirms it's actually gone (an ATS provider can fail intermittently and Pegel does not want to falsely expire roles). An application URL that returns 404 or 410 twice is marked expired after the second conclusive check.

Open data

The curated company list and the open job feed are both available openly:

Everything above is licensed CC0 (Public Domain Dedication). Use it for whatever you want. Attribution appreciated, not required.

Source

The site is built with Next.js, Drizzle, Supabase, plus a handful of supporting libraries. The full stack is in the README. The repository is private as of v1.

If you spot a bug or want to suggest something, the best path is email: pegel@mail.pegel.berlin.