In English →

Altinn 3, Maskinporten og systembruker — slik fungerer maskinell innsending

En teknisk gjennomgang av hvordan et fagsystem sender skattekort, MVA-melding, næringsspesifikasjon, skattemelding og årsregnskap maskinelt på vegne av kunder — via Digdir (Maskinporten), Altinn 3 og data fra Brønnøysundregistrene. Med konkrete scopes, tilgangspakker, token-utveksling, API-kall og de fallgruvene som er greie å vite om før du starter.

Hva integrasjonen gjør

Macct sender inn til det offentlige på vegne av kunden, uten at kunden deler passord eller logger inn manuelt. Følgende går maskinelt:

  • Skattekort til arbeidsgiver — henter trekkprosent/tabellkort fra Skatteetaten.
  • MVA-melding — leveres via en Altinn 3-app hos Skatteetaten.
  • Næringsspesifikasjon + skattemelding (AS) — RF-1167-grunnlaget og selskapets skattemelding.
  • Årsregnskap — RR0002 til Regnskapsregisteret i Brønnøysund via Altinn.
  • A-melding og aksjonærregisteroppgave — til Skatteetaten.

Tre byggeklosser gjør dette mulig: Maskinporten (maskin-til-maskin- autentisering fra Digdir), en systembruker (kundens fullmakt til fagsystemet, godkjent med BankID i Altinn), og Altinn 3 / Skatteetatens API-er (selve innsendingen). Brønnøysundregistrene brukes til validering av organisasjonsnummer, rolle og status ved registrering.

Digdir / Maskinporten: klient, JWT-grant og scopes

Maskinporten er Digdirs OAuth2-tjeneste for maskin-til-maskin (M2M). Fagsystemet har én klient per miljø (test og produksjon hver for seg), autentisert med et virksomhetssertifikat / en nøkkel registrert i Samarbeidsportalen. Tokens hentes med grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer: et signert JWT-assertion byttes mot et access token for de scopene klienten har fått tildelt.

POST https://maskinporten.no/token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion=<signert JWT: iss=clientId, aud=maskinporten, scope=...>

Scopene vi bruker

ScopeTil hva
skatteetaten:skattekorttilarbeidsgiverHente elektronisk skattekort
skatteetaten:mvameldingvalideringForhåndsvalidering av MVA-melding (se fallgruve)
altinn:instances.writeOpprette/skrive Altinn 3-app-instanser (MVA, skattemelding, årsregnskap)
altinn:authentication/systemregister.writeRegistrere/oppdatere systemet i System Register
altinn:authentication/systemuser.request.read / .writeOpprette og lese systembruker-forespørsler
Greit å vite: scope-navnene er bokstavelige. Det riktige er skatteetaten:skattekorttilarbeidsgiver — et lite avvik gir invalid_scope og null forklaring. Maskinporten avviser dessuten hele token-forespørselen hvis bare ett scope i settet mangler tildeling, så test- og prod-klienten bør ha hvert sitt scope-sett (prod har f.eks. MVA-scopene som test ikke har).

Systembruker: System Register, request og BankID-godkjenning

En systembruker er kundens fullmakt til fagsystemet i Altinn. Flyten er tre steg:

1. Registrer systemet (én gang per miljø)

Fagsystemet registreres i Altinns System Register med en systID på formen <leverandør-orgnr>_macct, klient-ID-en(e) fra Maskinporten, og hvilke rettigheter og tilgangspakker systemet forvalter.

POST {altinn}/authentication/api/v1/systemregister/vendor
{ "id": "<orgnr>_macct", "vendor": { "ID": "0192:<orgnr>" },
  "clientId": ["..."], "rights": [...], "accessPackages": [...],
  "allowedRedirectUrls": ["https://macct.no/altinn/callback"] }

2. Opprett en systembruker-forespørsel per kunde

POST {altinn}/authentication/api/v1/systemuser/request/vendor
{ "systemId": "<orgnr>_macct",
  "partyOrgNo": "<kundens orgnr>",
  "externalRef": "selskap-123",
  "rights": [ { "resource": [ { "id": "urn:altinn:resource", "value": "app_skd_formueinntekt-skattemelding-v2" } ] }, ... ],
  "accessPackages": [ { "urn": "urn:altinn:accesspackage:merverdiavgift" }, ... ],
  "redirectUrl": "https://macct.no/altinn/callback" }
→ svar inneholder en confirmUrl (am.ui.altinn.no/.../systemuser/request?id=...)

3. Kunden godkjenner med BankID

Kunden åpner confirmUrl og godkjenner i Altinn. Etter godkjenning slås den faktiske systembrukeren opp («bysystem»-listen), og en systemUserId lagres på kunden. Den brukes ikke direkte i tokenet — selve fullmakten bæres av externalRef + kundens orgnr (under).

Greit å vite: externalRef må være unik per systembruker. Skal en kunde få en ny systembruker (f.eks. ved utvidet tilgang) uten å miste den gamle, må den nye opprettes med en annen externalRef — ellers svarer Altinn at det allerede finnes en systembruker for system-ID-en. En ryddig konvensjon (selskap-123, selskap-123-mva) holder dette oversiktlig.

Tilgangspakker vs. rettigheter (rights)

Altinn 3 skiller mellom to fullmaktstyper, og innsending krever ofte begge:

  • Rettigheter (rights) — peker på en konkret ressurs/app, f.eks. app_skd_formueinntekt-skattemelding-v2 (skattemelding), app_brg_aarsregnskap-vanlig-202406 (årsregnskap), ske-innrapportering-amelding (a-melding).
  • Tilgangspakker (access packages) — rollebaserte «bunter» som Altinns policy-motor (PDP) krever for å instansiere enkelte apper. Vi bruker urn:altinn:accesspackage:regnskap-okonomi-rapport og urn:altinn:accesspackage:merverdiavgift.
Greit å vite: en tilgangspakke må ligge på systemet i samme miljø (test vs. prod) før en systembruker-forespørsel kan be om den — ellers svarer Altinn AUTH-00063 «accesspackage is not found in the referenced system». System Register er miljødelt, så pakker lagt i test må også legges i prod. Bare rettigheter (uten tilgangspakke) gir gjerne 403 fra PDP-en når appen skal instansieres.

Tokens: Maskinporten-token og Altinn-token-utveksling

For å handle på vegne av en annen virksomhet enn klient-eieren binder vi tokenet til systembrukeren via authorization_details (RAR-typen urn:altinn:systemuser):

authorization_details = [{
  "type": "urn:altinn:systemuser",
  "systemuser_org": { "authority": "iso6523-actorid-upis", "ID": "0192:<kundens orgnr>" },
  "externalRef": "selskap-123"
}]

Maskinporten-tokenet byttes deretter mot et Altinn-token for å nå Storage/App-API-ene:

GET {altinn}/authentication/api/v1/exchange/maskinporten
Authorization: Bearer <maskinporten-token med altinn:instances.write>
→ Altinn-JWT brukt mot app-instanser
Greit å vite: prod- og test-selskap rutes til hvert sitt miljø — prod-kunder mot maskinporten.no + platform.altinn.no, test/demo mot test.maskinporten.no + platform.tt02.altinn.no. Blandes miljøene, resolver ikke systembrukeren (404 / MP-303). Vi velger miljø per selskap, ikke globalt.

Per tjeneste: API-kall og parametere

Skattekort til arbeidsgiver

Direkte mot Skatteetatens «Skattekort for arbeidsgivere» (v3, forskudd-API) med et systembruker-bundet Maskinporten-token og scope skatteetaten:skattekorttilarbeidsgiver. Vert: api.skatteetaten.no (prod) / api-test.sits.no (test). Parametere: inntektsår, arbeidsgivers orgnr og den ansattes fødselsnummer. Svar: trekktype (tabell/prosent), tabellnummer og trekkprosent — som skrives på den ansatte og brukes i lønnskjøringen.

MVA-melding

Leveres via Altinn 3-appen mva-melding-innsending-v1 (instances.write + systembruker), ikke det avviklede direkte-API-et. To XML-dokumenter bygges: selve meldingen (mvamelding, namespace skattemeldingformerverdiavgift) og en innsendings-wrapper (mvameldinginnsending). Flyt:

1) POST .../instances              (opprett instans, instanceOwner = kundens orgnr)
2) PUT/POST data: mvamelding + wrapper  (erstatt auto-opprettet element)
3) PUT .../process/next            (data → confirmation → feedback)
→ kvittering: instanceOwnerPartyId/instanceGuid

Meldingen inneholder bl.a. skattleggingsperiode (to-måneders termin + år), fastsattMerverdiavgift, mvaSpesifikasjonslinje[], meldingskategori=alminnelig og skattepliktig>organisasjonsnummer. Valgfri forhåndsvalidering finnes på /api/mva/grensesnittstoette/mva-melding/valider.

Årsregnskap (RR0002)

Til Regnskapsregisteret via Altinn-appen app_brg_aarsregnskap-vanlig-202406. To dataTypes lastes opp: Hovedskjema (RR0002H_M — metadata) og Underskjema (RR0002U_M — resultat/balanse med detaljlinjer). Prosessen føres til PROSESS_FULLFORT, som er kvitteringen på at innsendingen er gjennomført.

Næringsspesifikasjon og skattemelding (AS)

Næringsspesifikasjonen (RF-1167-grunnlaget) bygges og godkjennes først; deretter genereres selskapets skattemelding (v2-format, skattemeldingForFormuesOgInntektsskatt, pakket i skattemeldingOgNaeringsspesifikasjonRequest med base64-kodede deldokumenter) og leveres via app_skd_formueinntekt-skattemelding-v2. Innsending er aldri automatisk: status-løpet er DRAFT → READY_FOR_REVIEW → APPROVED → SUBMITTED med SHA-256- integritetssjekk i hvert steg og en obligatorisk preflight-kontroll (krever bl.a. fullført årsavslutning og eksplisitt godkjenning) før noe sendes.

Felles for alle: hovedboken føres i NOK, beløp i BigDecimal med to desimaler, og fremmedvaluta omregnes med Norges Banks kurs på transaksjonsdato. Ingen innsending skjer uten at den er trigget og godkjent — systemet er bygd for å aldri sende noe «av seg selv».

Fallgruver verdt å unngå

Punktene under er de som typisk koster mest tid. Alle er håndtert i Macct.

Riktig vert for M2M. Skattekort- og MVA-API-ene nås på api.skatteetaten.no. Verten idporten.api.skatteetaten.no validerer ID-porten-nøkler og svarer 401 på et Maskinporten-token — riktig vert er avgjørende.
MVA-validering vs. -innsending. Forhåndsvaliderings-API-et («grensesnittstøtte») krever et ID-porten-token (interaktiv pålogging) og svarer 403 på et maskin-token. Selve innsendingen går helmaskinelt via Altinn 3-appen og er uavhengig av valideringen — så validering er en valgfri for-sjekk, ikke et hinder for å levere.
Verifiser app-navn og dataType. Altinn 3-appenes navn og dataTypes må stemme med applicationmetadata — f.eks. årsregnskapets hoveddokument heter Hovedskjema (ikke «Skjema»), og MVA- appen heter mva-melding-innsending-v1.
Choice-typer i XML. Skatteetatens skjemaer bruker «choice»-elementer: norskIdentifikator skal pakke en <organisasjonsnummer>, ikke ren tekst. Manglende obligatoriske felt (som skattepliktig>organisasjonsnummer) gir interne app-feil i prosess-steget snarere enn en tydelig valideringsfeil.
Tilgangspakke per miljø. Se over: pakker må ligge på System Register i samme miljø som forespørselen (AUTH-00063 ellers).
Unik externalRef. Gjenbruk gir AUTH-00004; bruk en distinkt referanse for nye/utvidede systembrukere.

Hva en Macct-kunde må gjøre

For at Macct skal kunne sende inn MVA-melding, årsregnskap, skattemelding m.m. på vegne av selskapet ditt, trenger vi én engangsgodkjenning fra deg:

  1. Du får en lenke til Altinn (am.ui.altinn.no) fra Macct.
  2. Du logger inn med BankID og godkjenner systembruker-forespørselen — du må ha en rolle på selskapet (typisk daglig leder eller styreleder, eller en delegert rolle) i Brønnøysund/Altinn.
  3. Godkjenningen gir Macct en systembruker med nøyaktig de tilgangspakkene og rettighetene som står i forespørselen — verken mer eller mindre.

Du deler aldri passord, BankID-koder eller API-nøkler. Fullmakten er avgrenset, sporbar, og du kan når som helst trekke den tilbake i Altinn under Tilgangsstyring → Systemtilgang. Og selv med fullmakt på plass sender Macct aldri noe inn uten at det er utløst og godkjent — innsending krever alltid et eksplisitt menneskelig «send».

Vil du se hvordan det ser ut i praksis?

Macct fører regnskapet og forbereder innsendingene — du godkjenner én gang og trykker «send» når du er klar.

Prøv gratis i 30 dager Se Altinn-statusen