Maskinelt utlese med KI frå kommunane sine offentlege møteprotokollar. Dette er eit uttrekk under utprøving, ikkje ein protokoll: det inneheld feil, og tal må kontrollerast mot kjelda før dei blir brukte. Kor sikre tala er

API

Alle røystingane i maskinlesbar form, for deg som vil rekne på dei sjølv. Ingen nøkkel, inga registrering. JSON over HTTP.

Les dette først

Sjekk dekninga før du reknar. Eit tal rekna over eit utval som ikkje er lese heilt, seier lite om utvalet — det seier noko om den delen vi har lese. Tabellen under gjeld akkurat no; ho er henta frå den same basen som svara. Difor ligg dekninga i kvart einaste svar, ikkje berre her.

UtvalLesneAvDel
formannskapet 34 34 100 %
kommunestyret 77 77 100 %
utval-for-areal-plan-og-miljo 241 250 96 %
utval-for-levekar 137 137 100 %
utval-for-naering-kultur-og-idrett 108 108 100 %

Tala over er henta live frå same base som API-et. Sjå /api/v1/alver/dekning for maskinlesbar utgåve.

Endepunkt

Alt ligg under /api/v1. Versjonen aukar berre om eit svar endrar form på ein måte som kan brekke ein konsument; nye felt er ikkje ei formendring.

GET /api/v1/kommunar
Kva kommunar som finst, med tal og datospenn for kvar.
GET /api/v1/{kommune}/dekning
Kor mykje av kvart utval som faktisk er lese. Start her.
GET /api/v1/{kommune}/saker
Saker med framlegg og røystingar.
  • utvalg — slug for eitt utval. Ukjend slug gjev 404 med dei gyldige.
  • frå, til — møtedato, YYYY-MM-DD. Anna form gjev 422.
  • grense — 1–500, standard 100.
  • forskyving — hopp over dei fyrste N.
GET /api/v1/{kommune}/saksgang/{arkivnr}
Éi arkivsak gjennom alle utvala som handsama henne, kronologisk. Arkivnummeret med skråstrek bytt i bindestrek: 25/278625-2786.
GET /api/v1/{kommune}/{utval}/{dato}/{saksnr}
Éi handsaming. Same adresse som nettsida, berre med /api/v1 framfor — siterer du ei lenkje i ein artikkel, byter du prefiks og får same sak maskinlesbart.

Drift

GET /status
Trafikktal for sida sjølv, til overvaking. Monotone teljarar sidan tenesta starta — pollar du med jamne mellomrom, er det differansen mellom to hentingar som er raten.
  • Tala bur i minnet og nullstillast ved omstart. Overvakingsverktøy handsamar dette som ein counter reset; oppetid_sekund seier når det sist skjedde.
  • Ingenting om den einskilde lesaren blir talt — ingen IP-adresse, ingen user-agent, ingen informasjonskapsel, verken i svaret eller i minnet. Sida fører ingen logg over kven som har vore her.

Kva eit svar inneheld

Kvart svar har same tre delar: sjølve dataen, dekning, og atterhald. Kvar røysting kan dokumentere seg sjølv:

FeltKva det er
raatekstSetninga protokollen sjølv brukte. Ordrett, aldri omskriven.
protokoll_urlPDF-en setninga står i.
presisjonKor detaljert protokollen var: samroystes, parti_fordeling, namneliste, berre_total, blanda, ukjend.
partistemmer[].kjeldeeksplisitt = protokollen oppgav partitalet. utleidd_fra_namn = vi har talt namngjevne representantar og slege dei opp i medlemslista. utleidd_fra_total = protokollen nemnde partiet i ei oppteljing utan å skrive talet, so det følgjer av totalen (1 per parti utan tal). parti_utan_tal = protokollen namngav partiet, men talet kan ikkje utleiast — då er antal null, og det tyder «ukjent», ikkje null røyster.
moteleiar_dobbeltroystSant når møteleiaren si røyst avgjorde ved stemmelikskap.
merknadSett når vår eigen aritmetikkontroll fann at tala ikkje går opp. Vi rettar ikkje på protokollen; vi seier frå. Feltet er reservert for avvik som kan tilskrivast kjelda — eit avvik uttrekket sjølv hadde laga gjev presisjon = ukjend og status uklar, men ingen merknad. Sida merkjer alt som ligg her med «Uavklart i protokollen».

Døme

Eg las om ei sak. Korleis røysta partia?

Har du lenkja til saka på nettsida, set du /api/v1 framfor.

curl -s https://hvemstemte.no/api/v1/alver/kommunestyret/2025-04-10/ps-30-25 \
  | jq '.sak.framlegg[].votering
        | {utfall, for_total, mot_total, avstaar_total, moteleiar_dobbeltroyst,
           parti: [.partistemmer[] | "\(.kode) \(.side) \(.antal)"],
           kjelde: .raatekst}'

Følg éi sak gjennom alle utvala

Dette er det innsynsportalen ikkje gjev deg: der må du kjenne arkivnummeret på førehand for å sjå at fire handsamingar i fire utval er same sak.

curl -s https://hvemstemte.no/api/v1/alver/saksgang/25-2786 \
  | jq -r '.saksgang.behandlingar[]
           | "\(.mote_dato)  \(.utvalg_namn)  \(.behandlings_nr)"'

Gjev fire handsamingar av Kløvheim skule, frå formannskapet i mars til kommunestyret i juni.

Alt eitt utval gjorde i ein periode

curl -s "https://hvemstemte.no/api/v1/alver/saker\
?utvalg=kommunestyret&frå=2025-01-01&til=2025-12-31&grense=500" \
  | jq '{treff: .tal_treff,
         saker: [.saker[] | {dato: .mote_dato, nr: .behandlings_nr, tittel}]}'

tal_treff er talet før utsnittet, so du ser om du har henta alt utan å hente alt for å finne det ut.

Kor ofte røysta eit parti mot?

Det finst ikkje eit endepunkt som svarar på dette, og det er med vilje. Eit tal som «H røysta mot i 15 % av sakene» gøymer nemnaren, og nemnaren er heile poenget. Rekn det sjølv — då er han din:

curl -s "https://hvemstemte.no/api/v1/alver/saker?utvalg=kommunestyret&grense=500" \
  | jq '[.saker[] | (.framlegg[].votering // empty), (.lause_voteringar[] // empty)] as $v
        | [$v[] | select(.partistemmer | length > 0)] as $delte
        | {voteringar_totalt: ($v | length),
           med_partifordeling: ($delte | length),
           H_mot: ([$delte[] | select(.partistemmer[] | .kode=="H" and .side=="mot")] | length)}'

Køyrt mot dagens base gjev det 108 røystingar totalt, men berre 47 med partifordeling — resten er samrøystes utan at protokollen sundelte dei. H står som mot i 7. Nemnaren er altså 47, ikkje 108, og skilnaden mellom dei to er skilnaden mellom 15 % og 6 %.

Kva API-et nektar å gjere

Tomme svar på feilskrivne spørjingar
Ukjend utvalsslug gjev 404 med dei gyldige listа. Ugyldig datoform gjev 422. Eit tomt, vellukka svar ville lese som eit faktum om dataen i staden for ein feil i spørjinga.
Ukjende spørjeparametrar
Dei blir avviste, ikkje oversette. Skriv du ?utval= i staden for ?utvalg=, får du 422 med forslag — ikkje alle sakene medan du trur du filtrerte.
Aggregat
Sjå dømet over. Hent radene og rekn sjølv; då står dekninga i same svar som tala.
Database-id-ar
Dei interne heiltala vert sletta og sette inn på nytt ved kvar uttrekkskøyring. Ein fotnote som peikte på «votering 47» ville peike på ei anna røysting etter neste køyring. Adressene er bygde av protokollfakta og overlever både ei ny køyring og eit portalbytte.