# Mikroregnskap — API-dokumentasjon for KI-agenter > Sist oppdatert: 2026-03-22 > GraphQL-skjema: /api/graphql/schema > GraphQL-endepunkt: POST /api/graphql ## Systemoversikt Mikroregnskap er et personlig regnskaps- og budsjetteringssystem bygget for privatpersoner, småorganisasjoner, klubber og lag med enkle regnskapsbehov. Systemet kombinerer: - Nullbasert budsjettering (inspirert av Every Dollar / Dave Ramsey og YNAB) - Dobbelt bokholderi med norsk kontoplan - Automatisk bankintegrasjon via Open Banking (Nordigen/GoCardless) - Enkel oversikt over budsjett vs faktisk forbruk Systemet er designet for brukere som ønsker full kontroll over økonomien uten kompleksiteten til tradisjonelle regnskapssystemer. ## Budsjettfilosofi ### Nullbasert budsjettering Hver krone som kommer inn skal ha en jobb. Inntekt minus planlagte utgifter skal gi null: Inntekter - Utgifter - Sparing = 0 ### Prinsipper - **Hver krone tildeles en kategori** — All inntekt fordeles på konti (faste utgifter, variable utgifter, sparing, etc.) - **Månedlig oppfølging** — Dashboard viser budsjett vs faktisk per kategori med visuell indikator (grønn = under budsjett, rød = over) - **Budsjett per måned** — Hvert kontos budsjett kan variere fra måned til måned (f.eks. høyere strømkostnad om vinteren) - **Balansekonti med mål** — Eiendeler og gjeld har åpningssaldo og målsaldo (31.12), systemet beregner månedlig budsjett automatisk ### Fremtidig fokus Systemet utvides for organisasjoner, klubber, lag og foreninger med enkle regnskapsbehov — f.eks. idrettslag, borettslag, småbedrifter. ## Kontoplan Norsk kontoplan med 8 hovedgrupper. Hver gruppe har en `factor` (for normalisering i visning) og `type` (balance/result): ### Balansekonti (type: balance) - **1xxx Eiendeler** (factor: 1) — Eiendom, kjøretøy, aksjer, fond, fordringer, bankkonti - 11xx Eiendom - 12xx Kjøretøy - 13xx Aksjer - 14xx Fond - 15xx Fordringer - 19xx Bankkonti ← Disse kobles typisk til bankintegrasjonen - **2xxx Gjeld** (factor: -1) — Forpliktelser, langsiktig gjeld, kredittkort - 21xx Forpliktelser - 22xx Langsiktig gjeld - 25xx Kredittkort - 29xx Annen gjeld ### Resultatkonti (type: result) - **3xxx Inntekter** (factor: -1) — Lønn, offentlig støtte, utleie - 31xx Lønn - 32xx Offentlig støtte - 36xx Utleie - 39xx Andre inntekter - **4xxx Faste regninger** (factor: 1) — Forsikring, abonnement, mobil, pensjonssparing - **5xxx Variable regninger** (factor: 1) — Parkering, strøm, internett, kommunale avgifter - **6xxx Månedlig forbruk** (factor: 1) — Dagligvarer, annet månedlig forbruk - **7xxx Årlig forbruk** (factor: 1) — Ferie, vedlikehold bolig/bil, annet årlig - **8xxx Andre kostnader** (factor: 1) — Renter, diverse ### Factor-systemet Factor brukes til å normalisere visningen: - Inntekter (factor: -1): Bokføres som negative beløp (kredit), men vises som positive tall i dashboard - Utgifter (factor: 1): Bokføres og vises som positive tall - Eiendeler (factor: 1): Økning er positivt - Gjeld (factor: -1): Bokføres som negative beløp, men gjeldssaldo vises som positivt tall ## Dobbelt bokholderi Hver transaksjon har to eller flere poster (entries) som alltid summerer til 0: Eksempel: Lønn 30 000 kr inn på bankkonto Entry 1: Konto 1920 (Bankkonto) +30 000 (debet) Entry 2: Konto 3100 (Lønn) -30 000 (kredit) Sum: 0 Eksempel: Dagligvarer 500 kr betalt fra bank Entry 1: Konto 6100 (Dagligvarer) +500 (debet) Entry 2: Konto 1920 (Bankkonto) -500 (kredit) Sum: 0 Ved banktransaksjoner bestemmes retning av beløpets fortegn: - **Negativt beløp** (penger ut fra bank): counterAccount er debet (fra), bankAccount er kredit (til) - **Positivt beløp** (penger inn til bank): bankAccount er debet (fra), counterAccount er kredit (til) ## API-tilgang ### Autentisering Alle API-kall krever Bearer token i Authorization-headeren: Authorization: Bearer Token utstedes via /api/graphql/token. ### Endepunkt POST /api/graphql Content-Type: application/json { "query": "...", "variables": { ... } } ### GraphQL-skjema Det fulle skjemaet med alle typer og beskrivelser er tilgjengelig på: GET /api/graphql/schema ## API-referanse ### Queries #### organizations Hent alle organisasjoner for innlogget bruker. query { organizations { id name years } } Bruk organizationId og year fra responsen i alle andre queries. #### dashboard Månedssammendrag — budsjett vs faktisk for en gitt måned. Tilsvarer dashbordet i appen. query { dashboard(organizationId: "...", year: 2026, month: 3) { month year incomeAndExpenses { name accountGroup factor totalBudget totalActual accounts { id name sequence budget actual budgetUsedPercent } } assetsAndLiabilities { name accountGroup factor totalBudget totalActual accounts { id name sequence budget actual budgetUsedPercent openingBalance } } } } Felter: - budget: Planlagt beløp for måneden - actual: Faktisk beløp (normalisert med factor) - budgetUsedPercent: Prosent av budsjett brukt (0-100), kun for utgifter - openingBalance: Startsaldo ved månedsskiftet (kun balansekonti) #### accounts Kontoplan med saldo og budsjett for et gitt år. query { accounts(organizationId: "...", year: 2026) { id name sequence category type openingBalance closingBalance budget change } } #### profitAndLoss Resultatregnskap — inntekter og utgifter gruppert per kategori med månedlig nedbrytning. query { profitAndLoss(organizationId: "...", year: 2026) { name accountGroup factor total accounts { id name sequence openingBalance closingBalance change monthlyChanges } } } monthlyChanges er en liste med 12 verdier (januar-desember), normalisert med factor. #### balance Balanse — eiendeler og gjeld med månedlig nedbrytning. query { balance(organizationId: "...", year: 2026) { name accountGroup factor total accounts { id name sequence openingBalance closingBalance change monthlyChanges } } } #### transactions Transaksjoner for en spesifikk konto, med løpende saldo. query { transactions(organizationId: "...", year: 2026, accountId: "...") { accountName openingBalance transactions { id date description amount otherAccountName balance } } } #### allTransactions Alle transaksjoner for et år (alle konti). query { allTransactions(organizationId: "...", year: 2026) { id date description entries { accountId accountName accountSequence amount } } } #### bankTransactions Banktransaksjoner for en konto og måned, med match-status og forslag til motkonto. Krever at kontoen er koblet til en bankkonto via Nordigen. query { bankTransactions(organizationId: "...", year: 2026, accountId: "...", month: 3) { openingBalance closingBalance fetchedAt unmatchedCount matchedCount transactions { externalId date amount description creditorName debtorName matched matchedTransactionId suggestions { accountId accountName accountSequence } } } } Felter: - matched: true hvis transaksjonen allerede er bokført i regnskapet - matchedTransactionId: ID til den bokførte transaksjonen (hvis matched) - suggestions: Forslag til motkonto basert på historiske transaksjoner med samme beskrivelse, sortert etter hyppighet (mest brukte først) - unmatchedCount: Antall transaksjoner som ikke er bokført ennå #### syncStatus Status for siste bank-synkronisering (cron-jobb). query { syncStatus(organizationId: "...") { timestamp totalAccounts successCount errorCount allSuccessful summary accounts { accountId accountName success error } } } #### feedbackItems Hent alle tilbakemeldinger/issues. query { feedbackItems(status: "open") { id createdAt source type title description status } } ### Mutations #### createTransaction Opprett en transaksjon med poster. Dobbelt bokholderi: entries må summere til 0. mutation { createTransaction(input: { organizationId: "..." year: 2026 date: "2026-03-15" description: "Dagligvarer Rema 1000" entries: [ { accountId: "konto-6100-id", amount: 500 } { accountId: "konto-1920-id", amount: -500 } ] }) { id date description entries { accountId accountName amount } } } Viktig: entries må summere til nøyaktig 0. API-et returnerer feil hvis summen avviker med mer enn 0.01. #### fetchBankTransactions Hent banktransaksjoner fra Nordigen (via S3-cache). Filtrerer for angitt måned, lagrer til S3, og auto-bokfører transaksjoner med nøyaktig 1 forslag. mutation { fetchBankTransactions( organizationId: "..." year: 2026 accountId: "..." month: 3 ) { success error autoPostedCount autoPostedErrors } } Denne mutasjonen: 1. Leser banktransaksjoner fra S3-cache (fylt av automatisk cron-jobb) 2. Filtrerer for angitt måned 3. Auto-bokfører transaksjoner som har nøyaktig 1 historisk forslag til motkonto 4. Returnerer antall auto-bokførte transaksjoner og eventuelle feil Etter fetchBankTransactions, bruk bankTransactions-queryen for å se oppdatert status. #### createTransactionFromBank Opprett en bokført transaksjon fra en banktransaksjon. Bestemmer debet/kredit basert på beløpets fortegn. mutation { createTransactionFromBank(input: { organizationId: "..." year: 2026 bankAccountId: "konto-1920-id" counterAccountId: "konto-6100-id" date: "2026-03-15" description: "Dagligvarer Rema 1000" amount: -500 }) { id date description entries { accountId amount } } } Beløpet er fra bankens perspektiv: - Negativt (-500): Penger ut fra bankkonto → utgift/overføring - Positivt (+500): Penger inn til bankkonto → inntekt/overføring Bruk accountId fra suggestions i bankTransactions-responsen som counterAccountId. #### deleteTransaction Slett en transaksjon og alle tilhørende poster. mutation { deleteTransaction(id: "transaksjon-id") { deletedTransactionId } } Sletter først alle poster (entries), deretter selve transaksjonen. Returnerer ID-en til den slettede transaksjonen. #### createFeedback Send tilbakemelding eller rapporter en feil. mutation { createFeedback(input: { source: "agent" type: "bug" title: "Feil ved matching" description: "Transaksjoner med desimalbeløp matches ikke korrekt" }) { id status } } source: "agent" eller "user" type: "bug", "feature", "improvement", eller "other" #### closeFeedback Lukk en tilbakemelding. mutation { closeFeedback(id: "...") { id status } } #### createAccount Opprett en ny konto i kontoplanen med budsjett. Beregner årlig budsjett som (target - openingBalance) og fordeler det jevnt over gjenværende måneder fra firstMonth. mutation { createAccount(input: { organizationId: "..." year: 2026 sequence: "6200" description: "Klær" openingBalance: 0 target: 12000 firstMonth: 1 }) { accountId sequence description yearlyBudget } } Felter: - sequence: Kontokode, f.eks. "6200". Første siffer (1-8) bestemmer kategori (se kontoplan) - description: Kontonavn - openingBalance: Åpningssaldo per 01.01 (default: 0) - target: Målsaldo per 31.12 for balansekonti, eller total årsbudsjett + openingBalance for resultatkonti (default: 0) - notes: Valgfrie notater - firstMonth: Første måned med budsjett, 1-12 (default: gjeldende måned). Måneder før denne får budsjett 0. Årlig budsjett = target - openingBalance. Fordeles jevnt over månedene fra firstMonth til desember. #### updateAccount Oppdater en eksisterende konto (navn, kode, åpningssaldo, mål, notater). Omberegner månedlige budsjetter for gjenværende måneder. mutation { updateAccount(input: { organizationId: "..." year: 2026 accountId: "konto-id" sequence: "6200" description: "Klær og sko" openingBalance: 0 target: 15000 firstMonth: 1 }) { accountId sequence description yearlyBudget } } Samme felter som createAccount, pluss accountId for å identifisere kontoen som skal oppdateres. #### deleteAccount Slett en konto. Kontoen må ha deletable=true (ingen transaksjoner bokført på den). mutation { deleteAccount( organizationId: "..." year: 2026 accountId: "konto-id" ) { deletedAccountId } } Kontoen kan bare slettes hvis det ikke finnes transaksjoner bokført på den. Bruk accounts-queryen for å finne kontoer, og sjekk at kontoen ikke har transaksjoner (change = 0) før du sletter. #### updateMonthlyBudget Oppdater månedlig budsjett for en konto. Tre moduser tilgjengelig. **THIS_MONTH** — Sett budsjett kun for angitt måned: mutation { updateMonthlyBudget(input: { organizationId: "..." year: 2026 accountId: "konto-id" month: 3 budget: 1500 notes: "Økt budsjett for mars" mode: THIS_MONTH }) { accountId month budget accountBudget } } **THIS_MONTH_AS_ACTUAL** — Sett budsjett lik faktisk transaksjonsbeløp for måneden: mutation { updateMonthlyBudget(input: { organizationId: "..." year: 2026 accountId: "konto-id" month: 3 mode: THIS_MONTH_AS_ACTUAL }) { accountId month budget accountBudget } } Nyttig for å justere budsjettet til det faktiske forbruket etter at måneden er over. **ALL_FOLLOWING_MONTHS** — Sett samme budsjett for denne og alle følgende måneder: mutation { updateMonthlyBudget(input: { organizationId: "..." year: 2026 accountId: "konto-id" month: 3 budget: 2000 mode: ALL_FOLLOWING_MONTHS }) { accountId month budget accountBudget } } Felter: - month: Måned (1-12) - budget: Ny budsjettverdi. Påkrevd for THIS_MONTH og ALL_FOLLOWING_MONTHS, ignoreres for THIS_MONTH_AS_ACTUAL. - notes: Valgfrie notater for måneden - mode: THIS_MONTH, THIS_MONTH_AS_ACTUAL, eller ALL_FOLLOWING_MONTHS - accountBudget i responsen er det oppdaterte totale årsbudsjettet for kontoen ## Typiske arbeidsflyter ### 1. Månedlig budsjettoppfølging Steg 1: Hent organisasjoner → organizations { id, name, years } Steg 2: Hent dashboard for gjeldende måned → dashboard(organizationId, year, month) { incomeAndExpenses, assetsAndLiabilities } Steg 3: Analyser budsjett vs faktisk - Se på budgetUsedPercent for hver konto - Identifiser konti som er over budsjett (actual > budget) - Sjekk totalBudget vs totalActual per gruppe ### 2. Hente og bokføre banktransaksjoner Steg 1: Hent fra banken → fetchBankTransactions(organizationId, year, accountId, month) (Auto-bokfører transaksjoner med 1 forslag) Steg 2: Se umatchede transaksjoner → bankTransactions(organizationId, year, accountId, month) Filtrer på matched: false Steg 3: For hver umatchet transaksjon med forslag: → createTransactionFromBank(input: { bankAccountId: accountId, counterAccountId: suggestions[0].accountId, date, description, amount }) Steg 4: For transaksjoner uten forslag: - Bruk accounts-queryen for å finne riktig motkonto basert på beskrivelsen - Velg konto fra riktig kategori (4xxx-8xxx for utgifter, 3xxx for inntekter) Steg 5: Verifiser → bankTransactions(...) { unmatchedCount } unmatchedCount bør være 0 ### 3. Sjekke resultatregnskap og balanse Steg 1: Hent resultatregnskap → profitAndLoss(organizationId, year) { name, total, accounts { change, monthlyChanges } } Steg 2: Hent balanse → balance(organizationId, year) { name, total, accounts { closingBalance } } Steg 3: Analyser - Sammenlign inntekter vs utgifter i resultatregnskapet - Sjekk utvikling av eiendeler og gjeld i balansen - Se månedlige trender via monthlyChanges ### 4. Slette en transaksjon Steg 1: Finn transaksjons-ID → transactions(organizationId, year, accountId) { transactions { id, description } } eller → allTransactions(organizationId, year) { id, description } Steg 2: Slett transaksjonen → deleteTransaction(id: "transaksjon-id") { deletedTransactionId } Transaksjonen og alle tilhørende poster (entries) slettes permanent. ### 5. Opprette manuell transaksjon Steg 1: Finn konto-IDer → accounts(organizationId, year) { id, name, sequence } Steg 2: Opprett transaksjon (entries må summere til 0) → createTransaction(input: { organizationId, year, date: "2026-03-15", description: "Beskrivelse", entries: [ { accountId: "fra-konto-id", amount: 1000 }, { accountId: "til-konto-id", amount: -1000 } ] }) ### 6. Administrere kontoplan og budsjett Steg 1: Se eksisterende konti → accounts(organizationId, year) { id, name, sequence, category, budget } Steg 2: Opprett ny konto → createAccount(input: { organizationId, year, sequence: "6200", description: "Klær", target: 12000 }) Steg 3: Oppdater budsjett for en spesifikk måned → updateMonthlyBudget(input: { organizationId, year, accountId, month: 3, budget: 1500, mode: THIS_MONTH }) Steg 4: Sett budsjett basert på faktisk forbruk → updateMonthlyBudget(input: { organizationId, year, accountId, month: 3, mode: THIS_MONTH_AS_ACTUAL }) Steg 5: Oppdater konto → updateAccount(input: { organizationId, year, accountId, sequence: "6200", description: "Klær og sko", target: 15000 }) Steg 6: Slett konto (kun hvis ingen transaksjoner) → deleteAccount(organizationId, year, accountId)