Gå til hovedinnhold

Fra FSWS-BAS til FS GraphQL API

⚠ FSWS-BAS avvikles etter 31. mars 2027. Flere av operasjonene under er allerede slått av og returnerer feil i dag — se Operasjoner som allerede er avviklet. Se Sikts avviklingspraksis og avviklingsloggen. Kilde: Teknisk dokumentasjon for FSWS-BAS (REST)

Denne guiden hjelper deg migrere fra FSWS-BAS til FS GraphQL API.

BAS-tjenesten består av endepunkter laget til litt forskjellige formål:

  • Oppdatering av brukernavn, e-post, bilder og fagpersoner
  • Oppslag på fagpersoner, kull og steder
  • Full- og inkrementell eksport av brukerdata (basData og basEksport)

Under gir vi et eksempel per endepunkt. Listen er ikke komplett, og GraphQL gir større fleksibilitet enn BAS gjorde: du bestemmer selv hvilke felt som skal med, og kan hente data som i BAS krevde flere kall i én spørring. Ta kontakt med fs-support@sikt.no dersom du trenger hjelp til å finne en spørring eller mutasjon som passer ditt behov.

Før du starter​

Sett deg inn i disse tingene før du går videre:

Migrerer du fra FS-APIet i samme integrasjon, finner du tilsvarende eksempler i Fra FS-APIet til FS GraphQL API.

Kontraktsnivå i eksemplene​

Eksempler som krever headeren Feature-Flags: beta,experimental er merket med kontraktsnivå rett over kodeblokken. Er et eksempel ikke merket, ligger alt det bruker på stable og virker uten header.

  • stable — dekket av API-kontrakten. Bygg produksjonsintegrasjoner på dette.
  • beta — kan endres, men med varslingsfrist.
  • experimental — kan endres eller forsvinne uten varsel. Ikke bygg produksjonsintegrasjoner på dette. Trenger du et experimental-felt i produksjon, ta kontakt med fs-support@sikt.no og be om at det løftes til beta.

Flere av BAS-feltene har i dag bare en experimental-erstatning. Det er markert eksplisitt der det gjelder, slik at du kan planlegge rundt det.

Institusjonsnummer i eksemplene​

De fleste spørringene i FS GraphQL API krever at du oppgir hvilket lærested dataene tilhører. Argumentet heter eierOrganisasjonskode, og tar institusjonsnummeret til lærestedet som eier dataene — samme verdi som BAS brukte som institusjonsnr. Eksemplene under bruker eierOrganisasjonskode: "1234" — bytt ut «1234» med institusjonsnummeret til ditt lærested.

Paginering: nytt i forhold til BAS​

BAS returnerte hele resultatsettet i ett XML-svar. FS GraphQL API paginerer listespørringer etter Relay-standarden: du får et Connection-objekt med edges { node } (eller kortformen nodes), pageInfo og totalCount, og henter neste side ved å sende endCursor fra forrige svar inn som after. Standard sidestørrelse er 100. Se Spørringer § Paginering for det fullstendige mønsteret.

Eksemplene under bruker små first-verdier for å holde svarene lesbare. I en reell eksport må du paginere gjennom alle sidene.

IDer: er de samme som i FSWS-BAS?​

Nei. BAS identifiserer objekter med nøkler hentet rett fra FS: fødselsnummer for en person, en firedelt stedkode (institusjonsnr_faknr_instituttnr_gruppenr) for et sted, og STUDIEPROGRAMKODE_ÅRSTALL_TERMIN for et kull. FS GraphQL API bruker i stedet én ID-verdi per objekt.

Behandle disse ID-ene som ugjennomsiktige. Du kan riktignok base64-dekode dem, men innholdet og formatet er en intern implementasjonsdetalj som kan endres uten varsel — ikke konstruer dem selv, og ikke parse dem for å hente ut de gamle nøklene. Bruk dem kun slik du fikk dem.

FS GraphQL API skiller mellom personprofilen (grunndataene om personen ved ett lærested — navn, fødselsnummer, e-post, Feide-bruker) og rollene personen har der: StudentVedLarested og FagpersonVedLarested. BAS blandet disse i ett objekt. Hver av dem har sin egen ID, og mutasjonene under tar den ene eller den andre — sjekk hvilken før du sender inn.

Har du en BAS-nøkkel og trenger tilsvarende GraphQL-ID, bruker du en oppslagsspørring:

BAS-nøkkelOppslagsspørringKontraktsnivå
Fødselsnummer → personprofilpersonProfilerGittFodselsnumrestable
Fødselsnummer → studentstudenter med fodselsnumre-filterstable
Fødselsnummer → fagpersonfagpersoner med fodselsnumre-filterstable
Feide-brukernavn → personprofilpersonProfilerGittFeideBrukerestable
Stedkode (4-delt) → organisasjonsenhetorganisasjonsenheterGittOrganisasjonsenhetskoderstable
Studieprogramkode + årstall + termin → kullkullGittLegacyIderexperimental

Eksempel — fra fødselsnummer til personprofil-ID, som du trenger for mutasjonene under:

query PersonProfilId {
personProfilerGittFodselsnumre(
eierOrganisasjonskode: "1234"
fodselsnumre: ["XXXXXXXXXXX"]
) {
id
navn {
fornavn
etternavn
}
}
}

Eksempel på svar:

{
"data": {
"personProfilerGittFodselsnumre": [
{
"id": "NzY6MTIzNCw4ODE",
"navn": {
"fornavn": "Njål",
"etternavn": "Øye"
}
}
]
}
}

Trenger du oppslag fra andre gamle nøkkeltyper, finner du en fullstendig gjennomgang under Klienten må bruke FS GraphQL APIs ID for objektet i FS-API-guiden.

Tilgang: hvilken RAS-rolle trenger du?​

FSWS-BAS ga deg hele datasettet med én tjenestetilgang. FS GraphQL API styrer i stedet tilgang på rad- og kolonnenivå med Oracle RAS, og de ulike delene av BAS treffer forskjellige roller. Du må derfor be om flere roller — én per datasett du faktisk bruker. Se Tilgangsstyring med RAS for bestillingsrutine.

Manglende rolle gir ingen feilmelding når du leser. Spørringen går gjennom, men du får færre rader, eller null i feltene rollen ikke dekker. Ser et uttrekk for lite ut etter migrering, er manglende rolle den vanligste årsaken — sjekk totalCount mot forventet volum. Ved skriving er oppførselen motsatt: mutasjonen feiler, eller endrer ingenting.

RAS-roller per datasett i denne guiden
Datasett i denne guidenLesingSkriving
Fødselsnummer — alle fodselsnumre-filtre og personProfil { fodselsnummer }PERSONDATA_LES2, eller STUDENTDATA_LES2 hvis du bare slår opp studenter—
Personprofil: feideBruker, e-postfeltene, navn, personlopenummerPERSONDATA_LES1PERSONDATA_SKRIV1
Fagperson: fagpersoner, opprettelse, aktivering/deaktivering, rom, campus, arbeidsadresseFAGPERSONDATA_LES1FAGPERSONDATA_SKRIV1
Fagpersonens roller: studieprogramroller, emneroller, klasserollerPERSONROLLE_LES1—
Bilde av fagpersonFAGPERSON_BILDE_LES1ikke mulig i dag
Bilde av student: angiStudentbilder, slettPersonbilderSTUDENT_BILDE_LES1STUDENT_BILDE_SKRIV1
Student: studentnummer, lanetakerIdSTUDENTDATA_LES1STUDENTDATA_SKRIV1
Semesterregistrering og semesteravgiftSTUDENT_SEMESTERREGISTRERING_LES1STUDENT_SEMESTERREGISTRERING_SKRIV1
StudentkortSTUDENT_STUDENTKORT_LES1STUDENT_STUDENTKORT_SKRIV1
Vurderingsmeldinger (vurderingsmeldingerV2)STUDENT_VURDERING_LES1—
KullSTUDIEELEMENTER_LES2—
Steder (organisasjonsenheter)ingen egen rolle — dekkes av STUDIEELEMENTER_LES1—

Tre ting er lette å gå i baklås på:

  • Kull krever STUDIEELEMENTER_LES2. Alle får automatisk STUDIEELEMENTER_LES1, men den dekker ikke kull. Uten LES2 returnerer kull tomt, uten feilmelding. Se Grunnleggende tilgang.
  • Fagpersonroller gir ikke fødselsnummer. FAGPERSONDATA_LES1 og LES2 dekker ikke fødselsnummer for noen. Skal du slå opp en fagperson på fødselsnummer — altså erstatte BAS' nin-parameter — trenger du PERSONDATA_LES2. Uten den returnerer fodselsnumre-filteret tomt, og personProfil { fodselsnummer } gir null. Se Tilgang til persondata.
  • Skriverollene gir ikke lesetilgang. PERSONDATA_SKRIV1 lar deg oppdatere personprofilen, men ikke lese den. Mutasjonene i denne guiden returnerer det oppdaterte objektet i svaret, så du trenger som regel den tilhørende lese-rollen i tillegg.

For hendelsesspørringene (basEksport-erstatningen) er tilgangen delt opp per hendelseskategori, ikke samlet i én rolle:

RAS-roller for hendelsestypene brukt i denne guiden
HendelsestyperRolle
PERSONPROFIL_ENDRET_INSTITUSJONSEPOST, PERSONPROFIL_ENDRET_PRIVAT_EPOST, PERSONPROFIL_ENDRET_ARBEIDSEPOST, PERSONPROFIL_ENDRET_NAVN, PERSONPROFIL_ENDRET_FODSELSNUMMER, PERSONPROFIL_ENDRET_FEIDE_BRUKERPERSONPROFIL_HENDELSER_LES1
SLUTTET_PA_STUDIEPROGRAM, STARTET_PA_STUDIEPROGRAM, STUDIERETT_FORLENGET, PROGRAM_STUDIERETT_OPPRETTETSTUDENT_STUDIERETT_HENDELSER_LES1
ENDRET_FEIDE_BRUKER, ENDRET_LANETAKER_ID, ENDRET_NAVN, ENDRET_EPOSTADRESSE, ENDRET_MOBILNUMMER, DODSFALLSTUDENTDATA_HENDELSER_LES1
SEMESTERREGISTRERT, SEMESTERREGISTRERING_UGYLDIGGJORT, SEMESTERAVGIFT_BETALT, STUDENT_FRITATT_FRA_SEMESTERAVGIFTSTUDENT_SEMESTERREGISTRERING_HENDELSER_LES1
STUDENTKORT_UTSTEDT, STUDENTKORT_FORLENGET, STUDENTKORT_GYLDIGGJORT, STUDENTKORT_UGYLDIGGJORT, STUDENTKORT_UTGATTSTUDENT_STUDENTKORT_HENDELSER_LES1

Mangler du rollen for en kategori, forsvinner hendelsene i den kategorien fra svaret — uten varsel. Be om alle rollene du trenger samtidig når du bestiller tilgang.

Operasjoner som allerede er avviklet​

Disse BAS-operasjonene er slått av og returnerer feil i dag. Har integrasjonen din fortsatt kall mot dem, er dette det mest akutte å rette.

BAS-operasjoner som er avviklet, med avviklingsdato og erstatning
BAS-operasjonAvvikletErstatning i FS GraphQL API
Hent fagpersoner (GET /bas/hent/fagpersoner)25.03.2026Query.fagpersoner
Hent en fagperson (GET /bas/hent/fagperson)25.03.2026Query.fagpersoner med fodselsnumre-filter
Hent alle kull (GET /bas/hent/kull)25.03.2026Query.kull
Oppdater epost for person (POST /bas/oppdater/email)25.03.2026Mutation.endreEpostadresserForPersonProfiler
Hent alle fagpersoner26.01.2026Query.fagpersoner
Hent eposter for person26.01.2026PersonProfil.privatEpost / .arbeidsEpost / .institusjonsEpost
Hent bilde for person26.01.2026StudentVedLarested.bilde / FagpersonVedLarested.bilde (experimental)
Oppdater bilde for studenter26.01.2026Mutation.angiStudentbilder (beta)
Slett bilde for person26.01.2026Mutation.slettPersonbilder (beta)
/hent/brukernavn26.01.2026PersonProfil.feideBruker
/hent/personid26.01.2026PersonProfil.personlopenummer
/hent/rom26.01.2026FagpersonVedLarested.romPlassering
/oppdater/lanetakerid26.01.2026Mutation.endreLanetakerIdForStudenter (experimental)
/oppdater/semesteravgift26.01.2026Mutation.registrerSemesteravgiftBetaltForStudenter / registrerFritakFraSemesteravgift (experimental)
/oppdater/studentkort26.01.2026Mutation.registrerStudentkort / endreStudentkort (beta)

To operasjoner har passert støttefristen (end of service 31.03.2025) uten å være slått av. De virker fortsatt, men Sikt gir ikke lenger brukerstøtte på dem: Hent steder ved institusjon og Oppdater en fagperson.

Resten av BAS — blant annet GET /hent/basdata, GET /hent/baseksport, POST /oppdater/bilde/form og POST /oppdater/brukernavn — har støttefrist 31. mars 2027.

Sjekk alltid avviklingsloggen for den gjeldende statusen. Datoene over var korrekte da guiden sist ble oppdatert.

POST /bas/oppdater/brukernavn — Oppdater brukernavn​

Avvikles etter 31. mars 2027.

FSWS-BAS tillot oppdatering av en persons brukernavn ved å oppgi fødselsnummer. I FS GraphQL API erstattes dette av mutasjonen angiBrukerinformasjonForPersonProfiler.

Viktige forskjeller:

  • FS GraphQL API bruker personprofil-ID i stedet for fødselsnummer. Slå opp ID-en med personProfilerGittFodselsnumre — se IDer
  • Feltet heter feideBruker i stedet for brukernavn
  • Du kan oppdatere institusjonsEpost i samme kall
  • Mutasjonen tar en liste, så du kan oppdatere flere personer i ett kall. BAS krevde ett kall per person
  • Utelater du et felt, beholdes verdien som ligger inne. Sender du null eller tom streng "", tømmes feltet
  • Feil rapporteres i errors i svaret, ikke som HTTP-statuskode. Se Mutasjoner § Feilhåndtering

Eksempel på mutasjon:

mutation AngiBrukerinformasjon {
angiBrukerinformasjonForPersonProfiler(
input: [
{
id: "NzY6MTIzNCw4ODE"
feideBruker: "test"
institusjonsEpost: "bruker@institusjon.no"
}
]
) {
personProfiler {
id
feideBruker
institusjonsEpost
}
errors {
__typename
... on Error {
message
path
}
... on BrukernavnErIkkeUnikt {
message
}
... on InstitusjonsEpostErIkkeUnik {
message
}
}
}
}

errors er en union-type, ikke et vanlig objekt. Du må derfor selektere feltene gjennom inline fragments (... on ...) — errors { message } alene er ugyldig GraphQL. __typename forteller deg hvilken konkret feiltype du fikk. For denne mutasjonen er det én av UgyldigInput, BrukernavnErIkkeUnikt eller InstitusjonsEpostErIkkeUnik. Alle tre har feltene message og path, så ... on Error { message path } dekker dem samlet.

Eksempel på svar:

{
"data": {
"angiBrukerinformasjonForPersonProfiler": {
"personProfiler": [
{
"id": "NzY6MTIzNCw4ODE",
"feideBruker": "test@spusers.feide.no",
"institusjonsEpost": "bruker@institusjon.no"
}
],
"errors": null
}
}
}

Merk at feideBruker returneres med domene (test@spusers.feide.no) selv om du sendte inn brukernavnet uten. FS legger til lærestedets Feide-domene.

Blanke ut brukernavn og e-post​

Sett feltene til null for å tømme dem. En tom streng "" gir samme resultat.

mutation BlankUtBrukerinformasjon {
angiBrukerinformasjonForPersonProfiler(
input: [
{
id: "NzY6MTIzNCw4ODE"
feideBruker: null
institusjonsEpost: null
}
]
) {
personProfiler {
id
feideBruker
institusjonsEpost
}
errors {
__typename
... on Error {
message
path
}
}
}
}

Eksempel på svar:

{
"data": {
"angiBrukerinformasjonForPersonProfiler": {
"personProfiler": [
{
"id": "NzY6MTIzNCw4ODE",
"feideBruker": null,
"institusjonsEpost": null
}
],
"errors": null
}
}
}

POST /bas/oppdater/bilde — Last opp/oppdater bilde​

«Oppdater bilde for studenter» ble avviklet 26.01.2026. Varianten POST /oppdater/bilde/form har støttefrist 31. mars 2027.

FSWS-BAS tillot opplasting av bilder for personer. I FS GraphQL API erstattes dette av mutasjonen angiStudentbilder.

Viktige forskjeller:

  • Krever student-ID (StudentVedLarested) i stedet for fødselsnummer. Slå den opp med studenter-spørringen og fodselsnumre-filteret
  • Mutasjonen gjelder kun studenter. BAS kunne sette bilde på en person uavhengig av rolle
  • Bildet må sendes som Base64-kodet streng i selve GraphQL-forespørselen — det finnes ikke et multipart-alternativ tilsvarende /oppdater/bilde/form
  • Filtype angis eksplisitt som enum-verdi JPG eller PNG
  • Finnes det allerede et bilde for studenten, erstattes det. Mutasjonen er altså «opprett eller oppdater», ikke bare opprett

Kontraktsnivå: beta. Krever headeren Feature-Flags: beta.

Eksempel på mutasjon:

mutation AngiStudentbilde {
angiStudentbilder(
input: [
{
studentVedLarestedId: "OTk6MTIzNCwxNDQw"
bilde: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
filtype: PNG
}
]
) {
studentbilder {
id
filtype
}
errors {
__typename
... on Error {
message
path
}
}
}
}

Eksempel på svar:

{
"data": {
"angiStudentbilder": {
"studentbilder": [
{
"id": "MTY1OjEyMzQsMTQ0MA",
"filtype": "PNG"
}
],
"errors": null
}
}
}

Merk at filtype i input er en enum (JPG eller PNG), mens filtype i svaret er en tekststreng med filendelsen. Vil du ha bildet tilbake, selekterer du også bilde — den returnerer hele den Base64-kodede fila, som fort blir mange hundre kilobyte. Ikke ta den med i spørringer der du bare trenger metadata.

Skal du slette et bilde, bruker du mutasjonen slettPersonbilder (beta), som tar ID-en til selve personbildet.

POST /bas/oppdater/email — Oppdater e-postadresse​

Denne operasjonen er avviklet (25.03.2026) og returnerer feil i dag.

FSWS-BAS tillot oppdatering av en persons e-postadresse (PERSON.EMAILADRESSE) ved å oppgi fødselsnummer. I FS GraphQL API erstattes dette av mutasjonen endreEpostadresserForPersonProfiler.

Oppdatering av en persons e-postadresse er en del av tilgangsstyringsprosessen. Se Tilgangstyring for studenter og ansatte for en beskrivelse av prosessen og tilhørende GraphQL-mutasjoner.

Viktige forskjeller:

  • FS GraphQL API bruker personprofil-ID i stedet for fødselsnummer
  • BAS hadde ett e-postfelt. FS GraphQL API skiller mellom tre: institusjonsEpost (tildelt av lærestedet — dette tilsvarer BAS' felt), privatEpost og arbeidsEpost. Du kan oppdatere alle tre i samme kall
  • Utelater du et felt, beholdes verdien som ligger inne. Sender du null eller tom streng, tømmes adressen

Eksempel på mutasjon:

mutation EndreEpostadresser {
endreEpostadresserForPersonProfiler(
input: [
{
id: "NzY6MTIzNCw4ODM"
privatEpost: "bruker@example.com"
arbeidsEpost: "bruker@arbeid.no"
}
]
) {
personProfiler {
id
privatEpost
arbeidsEpost
institusjonsEpost
}
errors {
__typename
... on Error {
message
path
}
... on InstitusjonsEpostErIkkeUnik {
message
}
... on PrivatEpostErIkkeUnik {
message
}
}
}
}

Eksempel på svar:

{
"data": {
"endreEpostadresserForPersonProfiler": {
"personProfiler": [
{
"id": "NzY6MTIzNCw4ODM",
"privatEpost": "bruker@example.com",
"arbeidsEpost": "bruker@arbeid.no",
"institusjonsEpost": null
}
],
"errors": null
}
}
}

POST /bas/oppdater/lanetakerid og /oppdater/semesteravgift​

Begge operasjonene er avviklet (26.01.2026) og returnerer feil i dag.

Begge har erstatninger i FS GraphQL API, men foreløpig bare på experimental-nivå.

Kontraktsnivå: experimental. Krever headeren Feature-Flags: beta,experimental, og kan endres eller forsvinne uten varsel.

Viktige forskjeller:

  • Begge tar student-ID (StudentVedLarested) i stedet for fødselsnummer. Slå den opp med studenter-spørringen og fodselsnumre-filteret, eller med studenterGittLanetakerIder hvis du allerede har lånetaker-ID-en
  • Semesteravgift registreres per termin. Du må oppgi termin-ID i tillegg til student-ID — BAS hadde ingen termin-parameter
  • FS skiller mellom betalt og fritatt. Det er to ulike mutasjoner, ikke ett statusfelt
  • endreLanetakerIdForStudenter har ingen errors-blokk i svaret. Feil kommer som generelle GraphQL-feil på toppnivå, ikke i payloaden

Eksempel — ny lånetaker-ID:

mutation EndreLanetakerId {
endreLanetakerIdForStudenter(
input: [
{ id: "OTk6MTIzNCwxNDQw", lanetakerId: "987654321" }
]
) {
studenter {
id
lanetakerId
}
}
}

Eksempel — registrer betalt semesteravgift:

mutation RegistrerBetalt {
registrerSemesteravgiftBetaltForStudenter(
input: [
{
studentVedLarested: "OTk6MTIzNCwxNDQw"
termin: "MTA6MTIzNCwyMDI2LEjDmFNU"
betaltSemesteravgiftDato: "2026-09-01"
}
]
) {
semesterregistreringer {
erSemesterregistrert
harBetaltSemesteravgiftV2
}
errors {
__typename
... on Error {
message
path
}
... on SemesterSperretForOppdateringError {
message
}
... on UgyldigBetalingsOrganisasjonError {
message
}
}
}
}

Utelater du betaltSemesteravgiftDato, settes dagens dato. Skal studenten fritas i stedet for å betale, bruker du registrerFritakFraSemesteravgift med samme studentVedLarested og termin.

Trenger du disse i produksjon, ta kontakt med fs-support@sikt.no og be om at de løftes til beta.

POST /bas/oppdater/fagperson — Opprett eller oppdater fagperson​

Støttefristen for «Oppdater en fagperson» (31.03.2025) er passert. Operasjonen virker fortsatt, men Sikt gir ikke lenger brukerstøtte på den.

FSWS-BAS tillot opprettelse og oppdatering av fagpersoner ved å sende inn én XML-representasjon. I FS GraphQL API er dette splittet: én mutasjon for opprettelse, og egne mutasjoner for oppdatering av enkeltområder.

Opprettelse og oppdatering av fagpersoner er en del av tilgangsstyringsprosessen. Se Tilgangstyring for studenter og ansatte for en beskrivelse av prosessen og tilhørende GraphQL-mutasjoner.

Viktige forskjeller:

  • BAS brukte én XML-payload for både opprettelse og oppdatering. I FS GraphQL API må du velge riktig mutasjon for det du faktisk skal gjøre
  • Fire felt er påkrevd ved opprettelse: eierOrganisasjonskode, fodselsnummer, fornavn og etternavn
  • Er det allerede registrert en fagperson på personen, får du feilen FagpersonFinnesForPerson i stedet for en oppdatering. Opprettelsen er ikke en «upsert»
  • Har fagpersonen ikke norsk fødselsnummer, D-nummer, SNR eller FS-fiktivt nummer, bruker du opprettFagpersonerGittPass i stedet

Oppdateringsmutasjonene, med kontraktsnivå:

MutasjonHva den gjørKontraktsnivå
aktiverFagpersonerAktiverer inaktive fagpersoner og vedlikeholder persondatastable
deaktiverFagpersonerDeaktiverer, og fjerner institusjonsepost og Feide-brukerstable
angiBrukerinformasjonForPersonProfilerFeide-brukernavn og institusjons-e-poststable
endreEpostadresserForPersonProfilerPrivat-, arbeids- og institusjons-e-poststable
endreArbeidsadresseForFagpersonerArbeidsadresseexperimental
angiCampusForFagpersonerCampusexperimental
plasserFagpersonerPaaRomKontor-/romplasseringexperimental

De tre experimental-mutasjonene kan endres eller forsvinne uten varsel. Dekker de et behov du har i produksjon, ta kontakt med fs-support@sikt.no og be om at de løftes til beta.

Eksempel på opprettelse av fagperson:

mutation OpprettFagperson {
opprettFagpersonerGittFodselsnumre(
input: [
{
eierOrganisasjonskode: "1234"
fodselsnummer: "XXXXXXXXXXX"
fornavn: "Ola"
etternavn: "Nordmann"
arbeidsEpost: "ola.nordmann@institusjon.no"
feideBruker: "olanord"
}
]
) {
result {
personProfil {
id
navn {
fornavn
etternavn
}
}
fagperson {
id
erAktiv
ansattVed {
id
navnAlleSprak {
nb
}
}
}
}
errors {
__typename
... on Error {
message
path
}
... on FagpersonFinnesForPerson {
message
}
... on UgyldigFodselsnummer {
message
}
}
}
}

Mulige feiltyper er UgyldigInput, UgyldigFodselsnummer, UgyldigFodselsdatoFraFodselsnummer, UgyldigNorskTelefonnummer og FagpersonFinnesForPerson.

Eksempel på svar:

{
"data": {
"opprettFagpersonerGittFodselsnumre": {
"result": [
{
"personProfil": {
"id": "NzY6MTIzNCwzNzgw",
"navn": {
"fornavn": "Ola",
"etternavn": "Nordmann"
}
},
"fagperson": {
"id": "MzE6MTIzNCwzNzgw",
"erAktiv": true,
"ansattVed": null
}
}
],
"errors": null
}
}
}

Svaret gir deg begge ID-ene: personprofil-ID-en og fagperson-ID-en. Mutasjonene over tar den ene eller den andre — sjekk hvilken før du sender inn.

ansattVed er null fordi eksempelet ikke satte ansattVedOrganisasjonsenhetId ved opprettelse. Vil du knytte fagpersonen til en organisasjonsenhet, sender du ID-en med i input — slå den opp med organisasjonsenheterGittOrganisasjonsenhetskoder, se Hent steder.

GET /bas/hent/fagpersoner — Hent alle fagpersoner​

Denne operasjonen er avviklet (25.03.2026) og returnerer feil i dag.

BAS hentet alle aktive fagpersoner med kontaktinfo, tilknytning (stedref) og roller. I FS GraphQL API erstattes dette av spørringen fagpersoner.

Viktige forskjeller:

  • BAS returnerte XML, FS GraphQL API returnerer JSON
  • Stedkoden (stedref) erstattes av det nøstede ansattVed-objektet (en Organisasjonsenhet)
  • Roller (studieprogramroller, emneroller, klasseroller med mer) hentes som nøstede felt på fagpersonen, i samme spørring
  • Resultatet er paginert. BAS ga hele settet i ett svar
  • Som i BAS returneres bare aktive fagpersoner som standard. Filteret har defaultverdiene erAktiv: [true] og erIPermisjon: [false] — sett erAktiv: [true, false] hvis du også vil ha inaktive

Eksempel på spørring:

query AlleFagpersoner($after: String) {
fagpersoner(
filter: {
eierOrganisasjonskode: "1234"
}
first: 3
after: $after
) {
totalCount
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
personProfil {
fodselsnummer
navn {
fornavn
etternavn
}
}
erAktiv
ansattVed {
id
navnAlleSprak {
nb
}
}
}
}
}
}

Eksempel på svar:

{
"data": {
"fagpersoner": {
"totalCount": 412,
"pageInfo": {
"hasNextPage": true,
"endCursor": "Mw"
},
"edges": [
{
"node": {
"id": "MzE6MTIzNCw4ODM",
"personProfil": {
"fodselsnummer": "XXXXXXXXXXX",
"navn": {
"fornavn": "Njål",
"etternavn": "Øye"
}
},
"erAktiv": true,
"ansattVed": {
"id": "Nzk6MTIzNCwxODQsMywwLDA",
"navnAlleSprak": {
"nb": "Det medisinske fakultet, UiB"
}
}
}
}
]
}
}
}

Send endCursor fra svaret inn som $after i neste kall for å hente resten. Fortsett til hasNextPage er false.

Hente roller i samme spørring​

BAS leverte fagpersonens roller i samme XML-dokument. Det kan du også gjøre her — legg rollefeltene til inne i node:

query FagpersonerMedRoller {
fagpersoner(filter: { eierOrganisasjonskode: "1234" }, first: 3) {
edges {
node {
id
studieprogramroller {
nodes {
fsRolle {
kode
}
studieprogram {
kode
}
gyldighetsperiode {
fraDato
tilDato
}
}
}
emneroller {
nodes {
fsRolle {
kode
}
}
}
klasseroller {
fsRolle {
kode
}
}
}
}
}
}

Merk at studieprogramroller og emneroller er paginerte og derfor må selekteres gjennom nodes (eller edges { node }), mens klasseroller returnerer en vanlig liste du selekterer direkte på. Inaktive roller filtreres bort som standard.

GET /bas/hent/fagperson — Hent en fagperson​

Denne operasjonen er avviklet (25.03.2026) og returnerer feil i dag.

BAS hentet én fagperson basert på fødselsnummer (nin-parameteren). I FS GraphQL API bruker du samme fagpersoner-spørring som over, med fodselsnumre i filteret.

Viktige forskjeller:

  • nin-parameteren erstattes av fodselsnumre, som tar en liste. Du kan slå opp flere personer i ett kall
  • BAS returnerte XML, FS GraphQL API returnerer JSON
  • fagpersoner returnerer som standard bare aktive fagpersoner som ikke er i permisjon. BAS' oppslag på fødselsnummer gjorde ikke denne filtreringen. Slår du opp en person som er inaktiv eller i permisjon, får du et tomt resultat med mindre du overstyrer erAktiv og erIPermisjon. Dette er den vanligste årsaken til at et oppslag som virket i BAS ser ut til å «mangle» data etter migrering
  • Resultatet er en paginert Connection, ikke en flat liste — selekter gjennom nodes eller edges { node }

Eksempel på spørring:

query EnFagperson {
fagpersoner(
filter: {
eierOrganisasjonskode: "1234"
fodselsnumre: ["XXXXXXXXXXX"]
erAktiv: [true, false]
erIPermisjon: [true, false]
}
) {
nodes {
id
personProfil {
fodselsnummer
navn {
fornavn
etternavn
}
}
erAktiv
erIPermisjon
ansattVed {
id
navnAlleSprak {
nb
}
}
}
}
}

Eksempel på svar:

{
"data": {
"fagpersoner": {
"nodes": [
{
"id": "MzE6MTIzNCw4ODM",
"personProfil": {
"fodselsnummer": "XXXXXXXXXXX",
"navn": {
"fornavn": "Njål",
"etternavn": "Øye"
}
},
"erAktiv": true,
"erIPermisjon": false,
"ansattVed": {
"id": "Nzk6MTIzNCwxODQsMywwLDA",
"navnAlleSprak": {
"nb": "Det medisinske fakultet, UiB"
}
}
}
]
}
}
}

Bilde av fagpersonen​

BAS leverte fagpersonens bilde i samme oppslag. Det tilsvarende feltet i FS GraphQL API er bilde på fagpersonen:

Kontraktsnivå: experimental. Krever headeren Feature-Flags: beta,experimental, og kan endres eller forsvinne uten varsel. Selve bilde-feltet er experimental, men typen det returnerer ligger på beta — derfor trengs begge flaggene.

query FagpersonMedBilde {
fagpersoner(
filter: {
eierOrganisasjonskode: "1234"
fodselsnumre: ["XXXXXXXXXXX"]
}
) {
nodes {
id
bilde {
bilde
filtype
}
}
}
}

Feltet bilde inne i bilde-objektet returnerer hele den Base64-kodede fila. Ta den bare med når du faktisk trenger bildedataene.

Trenger du fagpersonbilder i en produksjonsintegrasjon, ta kontakt med fs-support@sikt.no — feltet ligger foreløpig kun på experimental-nivå.

GET /bas/hent/kull — Hent alle kull​

Denne operasjonen er avviklet (25.03.2026) og returnerer feil i dag.

BAS hentet alle aktive kull. I FS GraphQL API erstattes dette av spørringen kull.

Viktige forskjeller:

  • BAS returnerte XML med kull-ID på formen STUDIEPROGRAMKODE_ÅRSTALL_TERMIN. FS GraphQL API bruker en ugjennomsiktig ID, og eksponerer studieprogram og termin som egne nøstede felt du kan selektere
  • BAS returnerte bare kullnavnet. Her kan du hente alle feltene på kullet og på objektene det peker til
  • Resultatet er paginert
  • Som i BAS returneres bare aktive kull som standard (erAktiv: [true])
  • Feltet termin er utfaset og fjernes. Bruk terminV2 i stedet — det er samme data, med riktig nullability

Eksempel på spørring:

query AlleAktiveKull {
kull(
filter: {
eierOrganisasjonskode: "1234"
erAktiv: [true]
}
first: 3
) {
edges {
node {
id
studieprogram {
kode
}
terminV2 {
arstall
betegnelse {
kode
navnAlleSprak {
nb
}
}
}
navnAlleSprak {
no
en
}
}
}
}
}

Eksempel på svar:

{
"data": {
"kull": {
"edges": [
{
"node": {
"id": "NTg6MTIzNCwxMCwxOTkzLEjDmFNU",
"studieprogram": {
"kode": "10"
},
"terminV2": {
"arstall": 1993,
"betegnelse": {
"kode": "HØST",
"navnAlleSprak": {
"nb": "Høst"
}
}
},
"navnAlleSprak": {
"no": "Studiekull 1993-HØST",
"en": null
}
}
}
]
}
}
}

Merk at kullnavnet bruker språkkodene no og en, mens terminnavnet bruker nb, nn og en. Hvilke språkkoder som finnes varierer per felt — bruk introspeksjon eller GraphiQL for å se hvilke som er tilgjengelige.

Fra BAS' kull-ID til GraphQL-ID​

Har du lagret kull-ID-er på BAS-formen, kan du slå dem opp med kullGittLegacyIder:

Kontraktsnivå: experimental. Krever headeren Feature-Flags: beta,experimental.

query KullFraLegacyId {
kullGittLegacyIder(
eierOrganisasjonskode: "1234"
legacyIder: [
{ studieprogramkode: "10", arstall: 1993, terminkode: "HØST" }
]
) {
id
navnAlleSprak {
no
}
}
}

Trenger du dette oppslaget i produksjon, ta kontakt med fs-support@sikt.no og be om at det løftes til beta.

GET /bas/hent/sted — Hent steder ved en institusjon​

Støttefristen (31.03.2025) er passert. Operasjonen virker fortsatt, men Sikt gir ikke lenger brukerstøtte på den.

BAS hentet organisasjonsenheter (steder) ved en institusjon. I FS GraphQL API erstattes dette av spørringen organisasjonsenheter.

Viktige forskjeller:

  • BAS identifiserte et sted med den firedelte stedkoden (institusjonsnr_faknr_instituttnr_gruppenr). FS GraphQL API bruker en ugjennomsiktig ID, men de fire delene finnes fortsatt som egne felt du kan selektere
  • Har du en firedelt stedkode og trenger tilsvarende ID, bruker du organisasjonsenheterGittOrganisasjonsenhetskoder — se eksempelet under. Du trenger ikke å bla gjennom hele listen for å finne den
  • BAS returnerte XML, FS GraphQL API returnerer JSON
  • Stedakronymet heter forkortelse. Navneoversettelsene ligger under navnAlleSprak
  • Resultatet er paginert
  • Feltet erAktiv på organisasjonsenhet ligger på beta-nivå, i motsetning til erAktiv på fagperson, som er stable. Skal du selektere det, må du sende Feature-Flags: beta. Filteret erAktiv i organisasjonsenheter er derimot stable, og har defaultverdien [true] — du får altså bare aktive enheter som standard, uten å måtte selektere feltet

Eksempel på spørring:

query AlleSteder {
organisasjonsenheter(
filter: {
eierOrganisasjonskode: "1234"
}
first: 3
) {
edges {
node {
id
navnAlleSprak {
nb
nn
en
}
forkortelse
organisasjon {
organisasjonskode
}
fakultet {
fakultetsnummer
}
instituttnummer
gruppenummer
}
}
}
}

Eksempel på svar:

{
"data": {
"organisasjonsenheter": {
"edges": [
{
"node": {
"id": "Nzk6MTIzNCwxODQsMywwLDA",
"navnAlleSprak": {
"nb": "Det medisinske fakultet",
"nn": null,
"en": "Faculty of Medicine"
},
"forkortelse": "MED",
"organisasjon": {
"organisasjonskode": "1234"
},
"fakultet": {
"fakultetsnummer": "184"
},
"instituttnummer": "3",
"gruppenummer": "0"
}
}
]
}
}
}

De fire feltene organisasjon.organisasjonskode, fakultet.fakultetsnummer, instituttnummer og gruppenummer utgjør til sammen den stedkoden BAS brukte.

Fra BAS' stedkode til GraphQL-ID​

Har du lagret stedkoder på BAS-formen 1234_184_3_0, slår du opp tilsvarende organisasjonsenhet direkte:

query StedFraStedkode {
organisasjonsenheterGittOrganisasjonsenhetskoder(
eierOrganisasjonskode: "1234"
organisasjonsenhetskoder: [
{
organisasjonskode: "1234"
fakultetskode: "184"
instituttkode: "3"
gruppekode: "0"
}
]
) {
id
navnAlleSprak {
nb
}
forkortelse
}
}

Eksempel på svar:

{
"data": {
"organisasjonsenheterGittOrganisasjonsenhetskoder": [
{
"id": "Nzk6MTIzNCwxODQsMywwLDA",
"navnAlleSprak": {
"nb": "Det medisinske fakultet"
},
"forkortelse": "MED"
}
]
}
}

Alle fire kodedelene er påkrevd. Spørringen returnerer en flat liste, ikke en paginert Connection.

GET /bas/hent/baseksport — Inkrementell dataeksport​

Avvikles etter 31. mars 2027.

BAS' basEksport ga deg endringene siden forrige uttrekk. I FS GraphQL API dekkes dette av hendelsesspørringene personProfilhendelser og studenthendelser.

Viktige forskjeller:

  • Dette er polling, ikke push. FS GraphQL API har ingen Subscription-type, og sender ikke hendelser til deg. Du spør med jevne mellomrom, akkurat som du kalte basEksport med jevne mellomrom
  • Du holder styr på hvor du er kommet ved hjelp av paginerings-markøren. Lagre endCursor fra siste side du behandlet, og send den som after neste gang. Da får du bare hendelser som har kommet til siden sist
  • Du må oppgi hvilke hendelsestyper du vil ha. Det finnes ikke et «gi meg alt»-alternativ
  • Hendelsestypene er ulike for personprofil og student, og du må spørre hver av dem for seg
  • Argumentnavnet er forskjellig i de to spørringene. personProfilhendelser bruker hendelsestyper (flertall), studenthendelser bruker hendelsestype (entall). Begge tar en liste og begge er påkrevd. Dette er en kjent inkonsistens — bruk nøyaktig det navnet som hører til spørringen
  • Hendelsestypene er union-/interface-baserte: hendelsestype og tidspunkt finnes på alle, mens feltene som forteller hva som faktisk endret seg ligger på den konkrete typen. Selekter dem gjennom inline fragments

Hendelser krever egen tilgang, og rollen er delt opp per hendelseskategori. Se Tilgang: hvilken RAS-rolle trenger du? for hvilke roller hendelsestypene under krever, og FS GraphQL API: Hendelser for full oversikt over hendelsestypene.

Eksempel — endringer i brukerinformasjon:

query PersonProfilEndringer($after: String) {
personProfilhendelser(
filter: {
eierOrganisasjonskode: "1234"
hendelsestyper: [
PERSONPROFIL_ENDRET_INSTITUSJONSEPOST
PERSONPROFIL_ENDRET_PRIVAT_EPOST
PERSONPROFIL_ENDRET_NAVN
]
}
first: 100
after: $after
) {
pageInfo {
hasNextPage
endCursor
}
nodes {
__typename
hendelsestype
tidspunkt
... on PersonProfilEndretInstitusjonsepost {
personProfil {
id
institusjonsEpost
}
}
... on PersonProfilEndretNavn {
personProfil {
id
navn {
fornavn
etternavn
}
}
}
}
}
}

Eksempel på svar:

{
"data": {
"personProfilhendelser": {
"pageInfo": {
"hasNextPage": false,
"endCursor": "Mg"
},
"nodes": [
{
"__typename": "PersonProfilEndretInstitusjonsepost",
"hendelsestype": "PERSONPROFIL_ENDRET_INSTITUSJONSEPOST",
"tidspunkt": "2026-09-16T08:14:22Z",
"personProfil": {
"id": "NzY6MTIzNCw4ODE",
"institusjonsEpost": "ny.adresse@institusjon.no"
}
}
]
}
}
}

På stabilt nivå finnes disse personprofil-hendelsestypene: PERSONPROFIL_ENDRET_PRIVAT_EPOST, PERSONPROFIL_ENDRET_INSTITUSJONSEPOST, PERSONPROFIL_ENDRET_ARBEIDSEPOST, PERSONPROFIL_ENDRET_NAVN og PERSONPROFIL_ENDRET_FODSELSNUMMER.

Eksempel — studenthendelser (merk hendelsestype i entall):

query StudentEndringer($after: String) {
studenthendelser(
filter: {
eierOrganisasjonskode: "1234"
hendelsestype: [SLUTTET_PA_STUDIEPROGRAM, STUDIERETT_FORLENGET]
}
first: 100
after: $after
) {
pageInfo {
hasNextPage
endCursor
}
nodes {
__typename
hendelsestype
tidspunkt
student {
id
personProfil {
fodselsnummer
}
}
}
}
}

På stabilt nivå finnes bare SLUTTET_PA_STUDIEPROGRAM og STUDIERETT_FORLENGET. Trenger du hendelser som ENDRET_FEIDE_BRUKER, SEMESTERREGISTRERT, ENDRET_LANETAKER_ID, STUDENTKORT_UTSTEDT eller DODSFALL — som ligger tettere opp mot det basEksport dekket — ligger de på beta-nivå og krever headeren Feature-Flags: beta.

GET /bas/hent/basdata — Full dataeksport​

Avvikles etter 31. mars 2027.

BAS' basData ga ett fast, fullt datasett. I FS GraphQL API setter du selv sammen en spørring som henter nøyaktig de feltene du trenger.

Viktige forskjeller:

  • Datasettet er ikke lenger fast. Du velger felt, og får bare det du ber om
  • Resultatet er paginert — du må bla gjennom sidene for å få hele bestanden
  • Studenter og fagpersoner er to adskilte spørringer. BAS leverte begge i samme uttrekk
  • Trenger du bare endringene siden sist, er hendelsesspørringene over et vesentlig billigere alternativ enn å hente alt på nytt

Eksport av studenter​

Eksempelet under bruker studenter med fodselsnumre-filteret for å vise ett bestemt tilfelle. Utelat fodselsnumre for å hente hele bestanden — da må du paginere.

Kontraktsnivå: blandet. vurderingsmeldingerV2 er beta, studentkort er experimental. Send Feature-Flags: beta,experimental for å få begge. Resten er stable — trenger du bare de stabile feltene, kan du droppe de to blokkene og kjøre uten header.

query StudentEksport($after: String) {
studenter(
filter: {
eierOrganisasjonskode: "1234"
fodselsnumre: ["XXXXXXXXXXX"]
}
first: 100
after: $after
) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
studentnummer
lanetakerId
personProfil {
fodselsnummer
feideBruker
institusjonsEpost
navn {
fornavn
etternavn
}
}
semesterregistreringer {
nodes {
termin {
arstall
betegnelse {
kode
}
}
erSemesterregistrert
harBetaltSemesteravgiftV2
}
}
vurderingsmeldingerV2 {
nodes {
id
emne {
kode
versjonskode
navnAlleSprak {
nb
}
}
}
}
studentkort {
studentkortnummer
gyldighetsperiode {
fraDato
tilDato
}
}
}
}
}

Tre ting å merke seg:

  • harBetaltSemesteravgiftV2, ikke harBetaltSemesteravgift. Feltet uten V2 er utfaset og fjernes. V2 er det som gjelder, og dekker både betalt avgift og innvilget fritak
  • vurderingsmeldingerV2, ikke vurderingsmeldinger. Feltet uten V2 hadde fjerningsdato 15.04.2026 og bør ikke brukes i ny kode. V2 er paginert, så du må selektere gjennom nodes eller edges { node }
  • studentkort er experimental og returnerer en liste — en student kan ha flere kort over tid. Trenger du studentkort i produksjon, ta kontakt med fs-support@sikt.no

Eksempel på svar (forkortet):

{
"data": {
"studenter": {
"pageInfo": {
"hasNextPage": false,
"endCursor": "MQ"
},
"nodes": [
{
"id": "OTk6MTIzNCwxNDQw",
"studentnummer": "123456",
"lanetakerId": "987654321",
"personProfil": {
"fodselsnummer": "XXXXXXXXXXX",
"feideBruker": "olanord@spusers.feide.no",
"institusjonsEpost": "ola.nordmann@institusjon.no",
"navn": {
"fornavn": "Ola",
"etternavn": "Nordmann"
}
},
"semesterregistreringer": {
"nodes": [
{
"termin": {
"arstall": 2026,
"betegnelse": { "kode": "HØST" }
},
"erSemesterregistrert": true,
"harBetaltSemesteravgiftV2": true
}
]
},
"vurderingsmeldingerV2": {
"nodes": [
{
"id": "MTE0OjEyMzQsNTU4MQ",
"emne": {
"kode": "INF100",
"versjonskode": "1",
"navnAlleSprak": {
"nb": "Innføring i programmering"
}
}
}
]
},
"studentkort": []
}
]
}
}
}

Eksport av fagpersoner​

query FagpersonEksport($after: String) {
fagpersoner(
filter: {
eierOrganisasjonskode: "1234"
}
first: 100
after: $after
) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
erAktiv
erIPermisjon
personProfil {
fodselsnummer
feideBruker
institusjonsEpost
navn {
fornavn
etternavn
}
}
ansattVed {
id
navnAlleSprak {
nb
}
}
stillingstittelAlleSprak {
no
en
}
studieprogramroller {
nodes {
fsRolle {
kode
}
studieprogram {
kode
}
gyldighetsperiode {
fraDato
tilDato
}
}
}
}
}
}

studieprogramroller er paginert, så feltene må selekteres gjennom nodes (eller edges { node }). Dette gjelder også emneroller. klasseroller er en vanlig liste.

Disse spørringene kan tilpasses videre for å hente akkurat de feltene du trenger. Bruk GraphiQL og introspeksjon for å utforske hvilke felt som finnes.

Kontakt oss for hjelp ved behov​

Ta kontakt med fs-support@sikt.no dersom du trenger hjelp til å komme i gang, eller underveis i migreringen. Det gjelder også hvis du finner at et felt du er avhengig av bare finnes på experimental-nivå — vi trenger å vite om reelle behov for å kunne prioritere å løfte dem.