Sök
Metodik · Senast uppdaterad 23 maj 2026

Vi visar siffrorna.
Och hur vi fick fram dem.

All data på yrkesatlas.se kommer från 5 officiella svenska källor – SCB, SKR, Skatteverket, Arbets­förmedlingen och Konsumentverket. Varje datapunkt har en spårbar rad till en specifik tabell, ett publicerings­datum och vår hämtnings­tidpunkt. Råfilerna är versionerade – vi skriver aldrig över.

Datapunkter
1,9M
Sedan 2014
Källtabeller
9
9 endpoints, 5 myndigheter
SCB-hämtningar
361
Versionerade i råfiler
Skrivs över
0
Append-only sedan dag ett
Vad vi lovar

Tre löften som styr allt annat

Det mesta på den här sidan är operationaliseringen av dessa tre. Om något i resten av metodiken känns som att den motsäger ett av löftena – säg till, det är då en bugg.

  1. 01

    Råfilen finns alltid kvar

    Varje hämtning sparas som en tidsstämplad JSON-fil i data/raw/. Vi skriver aldrig över. SCB:s API kan gå ner, deras format kan ändras – databasen kan alltid byggas om från råfilerna deterministiskt.

    Bevis data/raw/scb/AM0110_LonYrkeOSekN1_2026-05-20T08-14-22Z.json
  2. 02

    Varje datapunkt har en källa

    Bottom-up: tabellen ingest_log loggar varje körning med endpoint, rad-antal och råfil-path. Top-down: varje siffra på sajten visas under en <SourceNote> med SCB-tabellkod, publicerings­datum och vår hämtnings­tidpunkt. Klicka på källan – du landar i tabellpaketet hos SCB.

    Bevis Källa: SCB Lönestrukturstatistik · AM0110 · Publicerad 2025-06-15 · Hämtad 2026-05-20
  3. 03

    Modellerade tal är märkta

    När vi måste estimera – typiskt för kommunlöner, eftersom SCB inte publicerar lönedata på kommunnivå – säger vi det rakt ut, visar metoden, och redovisar osäkerheten. Aldrig en uppskattning utan etikett.

    Bevis Kommunsidor: obligatorisk Callout om NUTS 2-modelleringen i hero
Vad vi hämtar

Datakällor

Nio källtabeller från fem myndigheter. Inga proprietära källor, inga betalmurar, ingen ompaketerad data från tredjepartsleverantörer – alla siffror kan verifieras direkt hos källan.

När en sida visar data från flera källor (nettolön = SCB OE0101 + Skatteverket-formeln) är båda namngivna i <SourceNote> under blocket. Aldrig en sammanblandning utan ursprung.

Datakällor som hela sajten bygger på
Tabell Källa · vad vi hämtar
AM0110
SCB Lönestrukturstatistik
Median, medellön, p10, p90 per yrke × sektor × kön
Årligen, juni · Yrkessidor, lönefördelning, lönejämförare
AM0110 (regional)
SCB Lön per region
Medellön per NUTS 2-storregion × sektor × kön
Årligen, juni · Region- och kommunsidor
YREG58
SCB Yrkesregistret
Antal anställda per yrke (SSYK-3) × region × kön
Årligen, mars · Kommun­sidor, Location Quotient
BE0101
SCB Befolknings­statistik
Folkmängd per kommun, kön och ålder
Kvartalsvis · Kommun­sidor
OE0101
SCB / SKR Kommunalskatt
Skatt till kommun, region och total per region × år
Årligen, december (förskott) · Nettolön, kommun­sidor, köpkraft
PR0101
SCB Konsument­prisindex
KPI fastställda årsmedeltal (1980 = 100)
Månadsvis · Inflation vs lön, reallöne­diagram
–
Skatteverket
Grundavdrag, jobbskatte­avdrag, statlig brytpunkt
Årligen, december · Nettolön, brytpunkt, konsult vs anställd
–
Konsumentverket
Standard­budget för 12 hushållstyper
Årligen · Köpkrafts­kalkylator
–
Arbets­förmedlingen
Yrkesprognoser, bristyrken på 1- och 5-års sikt
Halvårsvis · Yrkessidor (framtids­utsikter)
Från SCB till sajt

Datapipelinen i sex steg

Sex steg, varav två är "minne" (råfiler och git) och fyra är "transform" som alltid kan köras om från scratch. Om något går fel i steg 2–6 påverkar det inte stegen före – råfilen ligger kvar.

Designval:

Den viktigaste designprincipen är separationen mellan minne och derivat. Råfilen är minne – den får aldrig röras. Databasen är derivat – den kan kastas och byggas om. Det gör att ett buggfix i normaliserings­logiken inte är farligt; vi kör bara om pipelinen mot samma råfiler och får en konsistent ny databas.

  1. Steg 1

    Hämta

    SCB API · POST + json-stat2

    scb.ts-klienten hämtar tabellpaket och sparar svaret som råfil med ISO-tidsstämpel i namnet. Idempotent: samma anrop, samma fil­struktur.

    Output data/raw/<källa>/<tabell>_<typ>_<timestamp>.json
  2. Steg 2

    Normalisera

    TypeScript · jsonstat.ts

    Pivotera celler ur json-stat-strukturen till tabell­rader. Strippa SCB:s prefix från valueTexts. Filtrera bort aggregat­värden som '0000 Samtliga yrken' när de inte ska in i fakta­tabellen.

    Output Iterable av platta rader (yrke, år, sektor, kön, värde)
  3. Steg 3

    Skriva

    SQLite · WAL · foreign_keys=ON

    En transaktion per körning. Alla fakta-tabeller är append-only – ny rad, inte UPDATE. revision-kolumnen är del av PK så SCB-revideringar av äldre år kan saminlagras utan att skriva över historiken.

    Output site.db (~1,9M rader över fakta-tabellerna)
  4. Steg 4

    Metrics

    SQL · DROP+CREATE TABLE AS

    Förberäknade vyer (metric_*) byggs om från rådata. Ingen state – kan alltid återskapas. Här ligger reallöner (KPI-deflaterade), CAGR, Location Quotient och regionala viktade SSYK-3-medellöner.

    Output metric_* (kan repliceras från rådata)
  5. Steg 5

    Validera

    TypeScript · exit 1 vid fel

    Sanity-checks: täckning per dimension (alla 290 kommuner? alla 589 yrken?), FK-konsistens, KPI-värden inom rimligt intervall. Build går inte vidare vid fel – siffrorna ska aldrig komma upp på sajten korrupta.

    Output Pass / fail · loggad i ingest_log
  6. Steg 6

    Astro build

    Astro · getStaticPaths · query mot SQLite

    Statisk HTML genereras vid build-tid. Inga tunga beräkningar i runtime – sajten levereras från CDN. Vid SCB-release: ny ingest → ny build → ny deploy.

    Output ~2 700 statiska sidor till CDN
Den ringer ingen tredjepartsleverantör. Den skickar ingen data utåt. Den skriver inget annat än till lokala filer och databasen. Hela kedjan kan köras offline om råfilerna redan finns på disk.
Tid är en dimension

Vi UPDATE:ar aldrig – vi append:ar

SCB reviderar äldre års siffror regelbundet. Vår databas är därför temporal, inte mutation-baserad. Ny data blir en ny rad – aldrig en UPDATE.

Alla fakta-tabeller har år som dimension och en revision-kolumn som del av primary key. Det betyder att en revidering av t.ex. 2023 års siffror som publiceras senare än det ursprungliga tabellpaketet kan tas in utan att förstöra den version vi hade vid första hämtningen.

UI visar alltid senaste publicerade revision, men historiken finns kvar – både i råfilerna och i databasen. Det gör två saker möjliga: vi kan svara på "vilken siffra publicerades när?", och vi kan rendera löne­utveckling över tid som riktig serie­data, inte som en aktuell ögonblicks­bild på flera år.

Att kunna visa löneutveckling över tid är en explicit produkt­princip – inte teknisk hygien. Historik är innehåll, inte arkiv.

Varje uppdatering loggas i ändringsloggen med datum, källa och en kort beskrivning av vad som ändrades. Råfilerna i data/raw/ behåller alltid originalvärdet så att en specifik revision kan jämföras mot den ursprungliga publiceringen.
Datajournalistiken i praktiken

Hur datan blir sidor

Fyra sidtyper, samma underliggande datalager. Varje sida börjar med svaret i första meningen – sedan kommer vinklarna.

Yrkessida /yrke/[yrke] 9 sektioner

Svaret i hero: median, medel, p10, p90, sparkline. Sedan löne­fördelning (DistributionBar), löneutveckling vs riket, per sektor, per kön, per region (NUTS 2), närliggande yrken, FAQ. Lutar på SCB AM0110 och YREG58.

Kommunsida /kommun/[kommun] 11 sektioner

Obligatorisk NUTS 2-callout i hero – kommun­lön är region­lön. Snabb­tolkning (regelbaserad, inte AI). Topp-yrken med trend. Specialisering (LQ). Vad blir kvar efter skatt. Befolkning och skattutveckling över tid.

Regionsida /region/[region] 5 sektioner

En per NUTS 2-storregion. Äger lönedatan som vi tidigare doublade på alla 290 kommun­sidor. Löneutveckling vs riket. Kommuner per län, länkat – inte duplicerat. Korta, tunga sidor.

Verktyg /verktyg/* 5 sektioner

Räknesnurror som körs lokalt i webbläsaren. Inga inmatade belopp lämnar din enhet, vi loggar inte din lön. Samma SCB- och Skatteverket-formler som datasidorna – öppen källkod på GitHub.

När data saknas

Estimering och osäkerhet

Tre typer av luckor i offentlig statistik. Vår regel: visa metoden, visa felmarginalen, märk datapunkten visuellt – eller säg att vi inte vet.

1. Kommunlöner finns inte

SCB publicerar inte lönedata på kommunnivå – AM0110 LonYrkeRegion* går bara ner till NUTS 2 (åtta storregioner + Riket). Vi visar därför regionens lön på kommunsidor med en obligatorisk Callout högst upp som flaggar det. Stockholms stad får Stockholms läns lön; Mölndal får Västsveriges lön. Aldrig en låtsas-kommunmedian.

2. SCB-sekretess för små samples

För kombinationer med få observationer (t.ex. ett specifikt yrke × kön × sektor) döljer SCB antalet helt – för att skydda individers integritet. När vi räknar andelar i query-lagret sätter vi då andel = null istället för att räkna 100 % på den ena synliga raden. Site-koden respekterar null och renderar inte falska procenttal.

3. Modellerade serier

Reallöner kräver KPI-deflatering. Regionala SSYK-3-medellöner i kommunens topp-yrken-tabell härleds genom att vikta SSYK-4-lönerna inom respektive grupp. Varje modellering har en metodik-rad i den specifika data­visualiseringen – du ska aldrig behöva läsa den här sidan för att förstå hur en siffra räknats fram.

Visar metoden. Visar felmarginalen. Märker datapunkten visuellt med en liten markering. Vi tar aldrig en uppåt­rundad uppskattning utan att säga att den är just en uppskattning.
Språkmodell som verktyg, inte författare

Hur AI används – och inte används

Allt AI-genererat innehåll går genom en tre-stegs-pipeline: generera → validera → kritisera. Språkmodellen (LLM) får aldrig en öppen fråga, bara strukturerad data att rephrase:a.

  1. Steg 1

    Generera

    Strict Zod-schema + OpenAI structured output. Språkmodellen får aldrig en öppen fråga, bara strukturerad input att rephrase:a. Prompten förbjuder företagsnamn, "drivs av"-fraser, superlativ och spekulation.

  2. Steg 2

    Validera

    Syntaktisk kontroll. Alla siffror i texten måste finnas i input­datan. Alla kapitaliserade ord måste finnas i en allowlist. En blacklist fångar spekulativa fraser ("tech-hub", "Sveriges bästa"). Failure → regenerera med feedback.

  3. Steg 3

    Kritisera

    En andra AI-runda som faktagranskar texten mot input­datan. Listar konkreta saklighets­fel: sektor som motsäger data, namngivna institutioner, numeriska påståenden utanför datan. Failure → manuell review eller regenerering.

Drafts committas i git som canonical output – texter vi har granskat och accepterat. Vid varje AI-anrop sparas hela request + response som råfil i data/raw/llm/, samma audit-princip som SCB-rådata. Du kan se exakt vilken modell + vilket prompt som producerade en given text.

Var språkmodellen används: intro­meningar på yrkessidor som rephrase:ar strukturerad data till naturlig text. Var den inte används: sifferpåståenden, kausala slutsatser, jämförelser mellan källor, beslut om vad som är publicerings­värt. Den biten gör vi själva.

Negativ lista

Vad vi medvetet inte gör

Det vi låter bli är lika viktigt som det vi gör. Hela vitsen med en datadriven sajt är att den ska kunna citeras – och det går bara om vi undviker mönstren nedan.

  • AI-genererad fluff

    "Det är en spännande utveckling att se hur löner förändras över tid." Ingen siffra, ingen insikt, ingen anledning att finnas på sajten.

  • "Det beror på"

    Säg vad det beror på, inte att det beror på. Om vi inte vet – säg att vi inte vet, och varför datan inte räcker.

  • Estimat utan etikett

    En modellerad siffra som ser ut som en mätning är värre än ingen siffra alls. Vi visar metoden, inte bara talet.

  • Identiska FAQ-block

    En FAQ ska besvara en fråga som faktiskt ställs om just det här yrket eller den här kommunen – inte fyllnadstext som återanvänds över hundra sidor. Hellre ingen FAQ alls än samma fyra frågor överallt.

  • Dolda loggar

    Verktygen körs lokalt. Vi loggar inte lön, inte kommun, inte personnummer. Det går inte att läcka data vi aldrig samlat in.

  • Citerade studier vi inte kan länka till

    "Forskning visar att…" är en röd flagga. Om en studie är värd att citera är den värd en URL och ett publicerings­datum.

Audit-stacken

Fyra lager spårbarhet

Frågar någon "var kom den här siffran ifrån?" ska svaret finnas på minst ett av lagren nedan. Tillsammans täcker de allt från råsvaret från SCB:s API till mänskligt skrivna noter när vi ändrat metodik.

De fyra spårbarhetslagren
Lager Vad det fångar
Råfil
data/raw/<källa>/
Exakt API-svar från källan, ord för ord
Alltid · aldrig överskrivet
ingest_log
site.db · ingest_log-tabell
En rad per körning: källa, endpoint, råfil-path, rad-antal, status
Alltid
Git
Versionskontroll
Kod, schema-migrations, AI-drafts, SQL-recept för metrics
Alltid · varje ändring är ett separat commit
Ändringslogg
/andringslogg
Mänskligt skrivna noter när data eller metodik ändras
Alltid · synlig för läsare
Hittat något fel?

Säg till. Vi rättar och loggar.

Hela poängen med spårbar metodik är att fel kan hittas – av oss eller av dig. Om en siffra ser konstig ut, om en källa har uppdaterats utan att vi fångat det, eller om något i metodiken inte håller – hör av dig. Varje rättning syns i ändringsloggen med datum, källa och motivering.

Kort sagt
  • · Allt kommer från fem officiella myndigheter
  • · Råfilerna skrivs aldrig över – de är audit trail
  • · Databasen är temporal – UPDATE existerar inte
  • · Estimerade tal är alltid märkta och förklarade
  • · AI-text går genom generera → validera → kritisera
  • · Verktygen körs lokalt – vi loggar ingen lön

Välj per kategori. Du kan ändra dig när som helst via länken i sidfoten.