Öppna data

Kommunernas livsmedelskontroller som JSON

13 kommuner publicerar sina hygienkontroller, var och en i sitt eget format. Vi läser alla 13 och ger fälten samma namn. Nuläget hämtar du som JSON, nya kontroller som Atom.

Kom igång Skapa konto

17 130 verksamheter i 13 kommuner, bedömda ur 73 840 kontroller. Senast hämtat 22 september 2026.

Svar /api/v1/kommun/hoganas.json
{
  "version": "v1",
  "municipality": { "name": "Höganäs kommun", "slug": "hoganas" },
  "count": 316,
  "assessed": 314,
  "establishments": [
    {
      "name": "Arilds Vingård",
      "address": "Arild",
      "verdict": "clean",
      "reason": "assessed",
      "inspections": 1,
      "latest": { "date": "2025-07-01", "assessment": 0, "type": 0 },
      … 8 fält till …
    },
    … 315 till …
  ]
}
  • 13kommunala system

    Ett format, inte ett per kommun

    Samma fältnamn, samma kodlista och samma identitet oavsett vilket system kommunen råkar köra. Du skriver en läsare, inte en per kommun.

  • 24timmars hämtningstakt

    Varje svar säger hur gammalt det är

    Beståndet hämtas i dygnstakt, och varje svar bär källans fetchedAt. Du ser alltså åldern på uppgiften utan att fråga oss.

  • 0kronor, med konto eller utan

    Prova direkt, bygg med konto

    Rutterna nedan svarar på ett curl-anrop direkt, så att du ser vad du får innan du bestämmer dig. Ska svaren bära något du bygger skapar du ett konto.

Kom igång

En rad i en terminal ger dig täckningen, adressmallarna och kodlistan. Ingenting behöver godkännas först.

Anrop bash
curl -s https://prikko.se/api/v1/index.json
Svar /api/v1/index.json
{
  "api": "prikko-livsmedelskontroller",
  "version": "v1",
  "generated": "2026-09-22",
  "coverage": {
    "municipalities": 13,
    "establishments": 17130,
    "assessed": 15441,
    "inspections": 73840,
    "swedishMunicipalities": 290
  },
  "endpoints": {
    "municipality": "https://prikko.se/api/v1/kommun/{kommun}.json",
    "feed": "https://prikko.se/flode/{kommun}.xml",
    "nationalFeed": "https://prikko.se/flode/riket.xml"
  },
  "licence": { … },
  "codes": { … },
  "municipalities": [ … 13 kommuner … ]
}

Klippt. Hela dokumentet är 13 kommuner plus licens och kodlista.

endpoints bär mallarna till allt annat, och municipalities bär varje kommuns färdiga adress. Du behöver alltså aldrig gissa en URL: börja i indexet och följ fälten.

Och sedan ett konto

Det räcker så länge du provar. Ska svaren bära något du bygger vidare på skapar du ett konto, och det kostar en e-postadress och en kod i mejlen.

Vi stänger inte rutterna för den som låter bli. Samma uppgifter står öppet på kommunernas och verksamheternas egna sidor hos oss, och en inloggning framför dem hindrar mest den som vill citera oss. Kontot är hur vi vet vem som bygger på datan, inte en spärr. Det som faktiskt kräver ett samtal står längre ned.

Slutpunkter

Versionen står i adressen. /api/v1/ svarar med den form som beskrivs här, och den formen ändras inte. Tillkommer ett fält går det att lägga till utan att något går sönder. Ska ett fält försvinna eller byta betydelse hamnar det i /api/v2/ vid sidan av, och v1 står kvar.

Index, täckning och kodlista

Autentisering
Ingen.
Parametrar
Inga.

Startpunkten. Bär täckningen, hela kodlistan i klartext, och per kommun dess adress, källa och hämtdatum.

Exempel bash
curl -s https://prikko.se/api/v1/index.json

Svaret står under Kom igång.

Nuläget i en kommun

Adress
GET /api/v1/kommun/{kommun}.json
Autentisering
Ingen.
Parametrar
{kommun} är kommunens slug, alltså fältet slug i indexets municipalities.

Varje verksamhet i kommunen med sin senaste kontroll. Filen bär NULÄGET, alltså exakt vad kommunens egen listsida visar, och inte kontrollhistoriken.

Exempel bash
curl -s https://prikko.se/api/v1/kommun/hoganas.json
Svar, alla fält /api/v1/kommun/hoganas.json
{
  "version": "v1",
  "municipality": {
    "code": "1284",
    "slug": "hoganas",
    "name": "Höganäs kommun",
    "city": "Höganäs"
  },
  "source": {
    "type": "reverse_engineered",
    "url": "https://www.hoganas.se/boende-trafik--miljo/boendemiljo/livsmedel/livsmedelskontroller.html",
    "fetchedAt": "2026-09-22T08:31:06+00:00",
    "licence": "unstated"
  },
  "count": 316,
  "assessed": 314,
  "establishments": [
    {
      "id": "F-1284-7e2313c4667d",
      "slug": "arilds-vingard",
      "name": "Arilds Vingård",
      "address": "Arild",
      "types": [
        "Butik, restaurang och servering"
      ],
      "lat": 56.266635,
      "lng": 12.574686,
      "verdict": "clean",
      "reason": "assessed",
      "uncertain": false,
      "distinction": false,
      "inspections": 1,
      "latest": {
        "date": "2025-07-01",
        "assessment": 0,
        "type": 0
      },
      "url": "https://prikko.se/hoganas/arilds-vingard/"
    },
    … 315 till …
  ]
}

Klippt efter den första verksamheten av 316 i Höganäs.

Nya kontroller som flöde

Adress
GET /flode/{kommun}.xml
GET /flode/riket.xml
Autentisering
Ingen.
Format
Atom 1.0. Läses av allt som läser RSS.

De senaste kontrollerna, nyast först. Varje post bär en beständig identitet som följer KONTROLLEN och inte adressen, alltså dyker en post inte upp som ny igen om en verksamhet byter sida. Datumet är kontrollens, inte den dag vi hämtade den.

Fälten

En post under establishments ser likadan ut i varje kommunfil.

FältTypBetyder
id string Beständig identitet. Följer verksamheten även om namnet eller adressen ändras.
slug string Verksamhetens led i adressen. Tillsammans med kommunens slug bildar den sidans URL.
name string Namnet som kommunen registrerat det.
address string | null Gatuadress där kommunen lämnar en. Null är vanligt.
types string[] Verksamhetstyp i klartext, en eller flera.
lat number | null Latitud, WGS 84. Null där verksamheten inte gått att geokoda.
lng number | null Longitud, WGS 84. Null på samma grund som lat.
verdict string | null Prikkos bedömning av nuläget. Se kodlistan. Null betyder otillräckligt underlag.
reason string Varför verdict ser ut som det gör. Läs alltid det här fältet innan du tolkar ett null.
uncertain boolean Sant när underlaget är tunt nog att bedömningen bör visas med förbehåll.
distinction boolean Sant för verksamheter med utmärkelse i årets utgåva.
inspections number Antal kontroller vi har registrerade. Noll är ett giltigt värde.
latest object | null Senaste kontrollen: date, assessment och type. Null när inspections är noll.
url string Verksamhetens sida hos oss. Den ska länkas när uppgiften återges.
latest.date string Kontrollens datum, ISO 8601. Kontrollens datum, aldrig vårt hämtdatum.
latest.assessment number Utfallet vid den kontrollen. 0, 1 eller 2. Se kodlistan.
latest.type number Kontrollens art. 0, 1 eller 2. Se kodlistan.

Fältnamnen är hämtade ur den svenska nationella specifikationen Livsmedelskontroller som öppna data v2.0, framtagen av NSÖD och ÖDIS. Varför vi lånar dess ordförråd men inte dess dokumentform står längre ned.

Kodlistan

Listan står i klartext i indexet under codes, så en klient slipper skriva av den härifrån.

FältVärdeBetyder
verdict "clean" Inga anmärkningar vid den senaste kontrollen.
"minor" Anmärkningar vid den senaste kontrollen.
"major" Brister som stod kvar. Antingen fann kommunen dem vid ett återbesök, eller gav sitt allvarligaste omdöme, eller så fanns avvikelser redan vid kontrollen före. Vilket av de tre går att läsa ur inspections.
null Otillräckligt underlag. Se `reason`. Aldrig detsamma som en dålig bedömning.
reason "assessed" Bedömd ur kontrolldatan.
"no_inspections" Ingen registrerad kontroll hos kommunen.
"stale_inspections" Ingen kontroll de senaste fem åren.
assessment 0 Inga anmärkningar
1 Avvikelse
2 Kvarstående avvikelse
type 0 Planerad kontroll
1 Återbesök
2 Händelsestyrd kontroll
source.type "open_data" Kommunen publicerar en öppen datamängd.
"reverse_engineered" Vi anropar samma gränssnitt som kommunens egen tjänst.
"scrape" Läst ur kommunens publicerade sidor.
"foi_request" Utlämnad efter begäran om allmän handling.

Bedömningen är vår och inte kommunens. Sverige har inget nationellt hygienbetyg. verdict räknas fram ur kontrolldatan enligt en öppet publicerad metodik, och den får aldrig återges som kommunens betyg. assessment och type är däremot kommunens egna uppgifter, normaliserade till en gemensam skala.

verdict: null betyder att underlaget inte räcker och aldrig att bedömningen är dålig. reason säger vilket av de två fallen det är.

Gränser och drift

Kvot
Ingen räknare. Svaren är statiska filer, alltså ser vi inte hur ofta du hämtar dem. Hämta hellre en gång om dygnet än en gång i minuten: oftare än så ändras de inte.
Cache
Cache-Control säger en timme, och beståndet uppdateras i dygnstakt eller långsammare. Att hämta samma dokument oftare ger samma svar.
CORS
Access-Control-Allow-Origin: * på varje svar. Anrop från en webbsida fungerar.
Färskhet
Varje svar bär källans fetchedAt, och där källan själv säger när den ändrades även modifiedAt. De två är inte samma sak: en kommuns fil kan hämtas i dag och vara skriven för två år sedan.
Täckning
13 av Sveriges 290 kommuner. De flesta publicerar ingenting. Vad som saknas står på källsidan.

Hör av dig om det här

Allt ovanför är gratis och kommer att förbli det. Fyra saker ligger utanför, och de har alla samma skäl: de är för tunga för att lägga ut som statiska filer åt alla.

Hela kontrollhistoriken
Kommunfilerna bär nuläget. Tidsserien bakom 73 840 kontroller finns, men publiceras inte.
Uttag i bulk
Hela det normaliserade beståndet i en leverans i stället för 13 hämtningar.
Uppslagning per verksamhet
Ett dokument per verksamhet med historiken. Rutten är byggd och verifierad men inte publicerad: den kostar 17 066 filer och utgåvan ligger nära gratisplanens tak på 20 000.
Bevakning av ett bestånd
Besked när något ändras i en uppsättning verksamheter du följer, i stället för att du hämtar om allt och jämför själv.

Vi säljer ingenting av det i dag. Det finns inget pris, ingen prislista och ingen produkt att beställa. Det som finns är en adress, och den som hör av sig får ett ärligt besked om vad som går att få och när.

Skriv till oss mans@prikko.se. Skriv vad du vill bygga, så svarar vi på om datan räcker.

Vad vi aldrig säljer

Vi publicerar bedömningar av namngivna verksamheter och tar samtidigt emot förfrågningar om data. Det är en intressekonflikt, den går inte att designa bort, och därför står gränserna skrivna här i stället för i ett avtal ingen läser.

  • Ingen placering i sökresultatet. Sökordningen går inte att köpa, i någon form. Det är branschens vanligaste intäkt och den enda vi aldrig kan ta.
  • Inget bättre betyg för pengar. Inte heller en snabbare omprövning, en mildare formulering eller en tidigare borttagning av en rad.
  • Inget betalt märke och inget certifikat. Utmärkelsen och dekalen är gratis och kommer att förbli det. Att sälja beviset på en bra bedömning är att sälja bedömningen, med ett extra steg emellan.
  • Ingen jämförelse mot en namngiven konkurrent. Den som följer sina egna enheter ser dem mot varandra och mot riksmedianen. Aldrig mot en namngiven annan verksamhet, även om en kund ber om det.
  • Inga utgående säljbrev till den vi pekat ut. Vi kontaktar inte en verksamhet med anmärkning för att sälja något.

Varför formatet är vårt eget

Det närmast till hands liggande alternativet var LIVES, som Yelp tog fram tillsammans med San Francisco och New York och som Montreal publicerar i under CC BY 4.0. Ett etablerat format som andra redan kan läsa är normalt värt mer än ett eget som är en aning bättre, så frågan prövades på riktigt innan den avfärdades.

Tre saker i formatet fällde det. LIVES bygger på ett poängtal mellan noll och hundra, och svensk livsmedelskontroll har inget sådant tal. Fältet för icke-numeriska utfall rymmer fyra tecken, alltså varken ”Brister” eller ”Brister som kvarstår”. LIVES har vidare ingen identitet per kontroll: en avvikelse kopplas till en verksamhet och ett datum, inte till kontrollen den gäller, och två kontroller samma dag går då inte att hålla isär. Och formatet är till sin form fem CSV-filer i en zip, alltså precis den massnedladdning vi inte publicerar.

Och argumentet om att andra redan kan läsa formatet håller inte heller. Standarden uppdaterades senast 2015. Av de 247 jurisdiktioner Yelp listar levereras 237 numera av en kommersiell part, Ecolabs Health Department Intelligence, och båda de kommuner som en gång tog fram formatet finns i den gruppen. Att ansluta sig till LIVES i dag är alltså inte att gå med i ett levande ekosystem.

Fältnamnen är i stället hämtade ur den svenska nationella specifikationen Livsmedelskontroller som öppna data v2.0. Den har fält för precis det svensk kontroll faktiskt innehåller: bedömning per kontroll, kontrolltyp, om besöket var föranmält, kontrollpunkter med och utan avvikelse, och verksamhetens egen replik. Vi lånar dess ordförråd, inte dess dokumentform, och vi ansluter oss inte till något: ingen kommun publicerar i specifikationen i dag.

Licens och attribution

Två lager, och de ska hållas isär.

Kommunernas underlag är fritt, och inte tack vare oss. Ett kontrollresultat är ett yttrande av en svensk myndighet, och 9 § upphovsrättslagen (1960:729) undantar sådana från upphovsrätt. Katalogskyddet i 49 § räknar i sitt tredje stycke upp 9 § bland de bestämmelser som gäller även för en sammanställning, alltså skyddas inte heller tabellen som helhet. Ingen behöver vårt tillstånd för de uppgifterna, och vi kan inte licensiera dem.

Vårt eget arbete är normaliseringen, identifierarna och bedömningen. Det erbjuds under CC BY 4.0. Villkoret är attribution, och den här raden uppfyller det:

Attribution
Prikko, https://prikko.se

Länken ska vara klickbar där formatet tillåter en länk. Ta med kontrolldatumet tillsammans med uppgiften: kontrollresultat ändras, och en uppgift utan datum blir fel med tiden. Hittar du ett fel, rätta det här.

Kommunernas egna villkor

Ingen av de 13 kommunerna har skrivit ett enda villkor för vidareutnyttjande. Det gäller alla, inte några, och det står som "licence": "unstated" på varje källa i svaren.

Tystnad är varken ett förbud eller ett tillstånd, och slutsatsen ovan vilar därför inte på den utan på lagtexten. Att villkoret ändå redovisas per kommun är för att den som bygger vidare ska kunna göra sin egen bedömning i stället för att lita på ett medelvärde vi räknat åt hen.

KommunHur vi hämtarVillkorHämtat
Borgholm Kommunens eget gränssnitt Inga angivna 22 september 2026
Höganäs Kommunens eget gränssnitt Inga angivna 22 september 2026
Jönköping Kommunens eget gränssnitt Inga angivna 22 september 2026
Karlstad Kommunens eget gränssnitt Inga angivna 22 september 2026
Kristinehamn Kommunens eget gränssnitt Inga angivna 22 september 2026
Linköping Kommunens eget gränssnitt Inga angivna 22 september 2026
Lomma Kommunens eget gränssnitt Inga angivna 22 september 2026
Norrköping Öppen datamängd Inga angivna 22 september 2026
Oskarshamn Kommunens eget gränssnitt Inga angivna 22 september 2026
Stockholm Kommunens eget gränssnitt Inga angivna 22 september 2026
Svenljunga Kommunens eget gränssnitt Inga angivna 22 september 2026
Uppsala Kommunens eget gränssnitt Inga angivna 22 september 2026
Örebro Kommunens eget gränssnitt Inga angivna 22 september 2026

Vad som inte finns här

  • Inga bilder. Gatubilderna kommer från Mapillary, Panoramax och Wikimedia Commons, och deras villkor gäller per bild: en kräver logotyp och länk, en annan fotografens namn och en länk till filsidan. En URL i ett JSON-fält kan inte bära det kravet vidare, och en bild som visas utan sin attribution är ett brutet villkor hos oss.
  • Inga öppettider och inga kontaktuppgifter. De kommer ur OpenStreetMap och står under ODbL 1.0, som är en share-alike-licens. Att lägga dem i ett svar vi märker CC BY vore att sätta villkor vi inte har rätt att sätta.
  • Ingen massnedladdning som öppen fil. Underlaget är allmänna handlingar och du kan begära ut det av varje kommun själv. Vill du ha det normaliserade materialet på en gång är det en fråga att ställa, inte något vi hemlighåller.

Logga in eller bli medlem

Vi skickar en sexsiffrig kod till din e-post. Integritetspolicyn.