Guide
Å gjøre kall
Alle kall følger samme oppskrift: URL-en med instansnavnet først, bearer-tokenet ditt, JSON inn, JSON ut. Denne siden følger én personoppføring gjennom oppretting, lesing, oppdatering og sletting, og stopper ved det ene som er verdt å lese to ganger — hva PUT og PATCH gjør forskjellig.
Anatomien i en URL
Alle forretningsendepunkter er bygget av de samme delene i samme rekkefølge. Ingenting må oppdages under kjøring: kan du skrive URL-en, kan du kalle API-et.
Instansnavnet kommer først, og det er nettopp det som gjør at én integrasjon kan betjene flere Visena-instanser ved å bytte ett enkelt segment. Tokenet ditt utstedes for én instans, så tokenet og stien må stemme — er de ulike, får du 403, ikke en stille lesing på tvers av instanser.
Locale-segmentet (en eller no) velger språket i den menneskelesbare teksten i svaret, tydeligst i detail på en feil. Det endrer aldri feltnavn, formater eller oppførsel, så velg ett og bruk det konsekvent. Så kommer ressursen, og etter den en maskert id.
Ressurser er i entall, og stien har ikke noe partner/-segment: den er /{instanceName}/api/v1/{locale}/person. Ni ressursstier utgjør flaten i dag — person, company, company-template, project, project-template, activity, document, document/folder og document/changes. Hver av dem er dokumentert endepunkt for endepunkt i endepunktreferansen.
Headere på alle kall
Tre headere avgjør om et kall i det hele tatt blir forstått. To av dem setter du selv; den tredje er verdt å kjenne fordi det er slik en feil melder seg.
| Header | Verdi |
|---|---|
Authorization |
Bearer <access_token> — på alle kall, uten unntak. Tokener er kortlevde og bundet til én instans; se Legitimasjon og tokener. |
Content-Type |
application/json på POST og PUT · application/merge-patch+json på PATCH · multipart/form-data når du laster opp et dokument · utelat den helt på GET og DELETE. |
Accept |
Valgfri. Et vellykket svar er application/json; en feil er application/problem+json — problemdokumentet etter RFC 9457, beskrevet i Feil og feilsøking. |
Opprette
POST /{instanceName}/api/v1/{locale}/person
curl -X POST "https://api.visena.example/acme/api/v1/en/person" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Kari",
"lastName": "Nordmann",
"primaryEmail": "kari.nordmann@example.com",
"jobTitle": "Operations Manager"
}'
HTTP/1.1 201 Created
Location: /acme/api/v1/en/person/xK9mQ2
{
"id": "xK9mQ2",
"firstName": "Kari",
"lastName": "Nordmann",
"primaryEmail": "kari.nordmann@example.com",
"jobTitle": "Operations Manager",
"created": "2026-08-21T08:02:44Z",
"createdBy": "pQ7hL4",
"modified": null,
"modifiedBy": null
}
To ting i det svaret former resten av integrasjonen din. Location bærer stien til den nye ressursen, og id er den maskerte id-en du bruker fra nå av: lagre den akkurat som du fikk den, og send den tilbake ordrett. Den er opak — den har ingen rekkefølge, ingen betydning utenfor API-et, og kan ikke konstrueres. Alle de andre feltene på ressursen ligger også i svaret, og de du ikke sendte kom tilbake som null; tidsstempler er RFC 3339, normalisert til UTC av serveren.
En import kan beholde sin egen historikk: send created, createdBy, modified eller modifiedBy, og de blir oppføringens attribusjon i stedet for «nå» og eieren av legitimasjonen. En createdBy eller modifiedBy som ikke lar seg slå opp som en person i instansen avvises med 422, og ingenting skrives.
Sjekk for duplikater før du oppretter. GET /…/person/duplicates?email=kari.nordmann@example.com (eller navn pluss fødselsdato) returnerer sannsynlige treff, slik at en synk ikke oppretter samme person to ganger. Selskaper har samme sjekk med organisasjonsnummer som nøkkel — og der er det mer enn et råd: å opprette et selskap med et organisasjonsnummer som allerede finnes, avvises med 409.
Lese
GET /{instanceName}/api/v1/{locale}/person/{personId}
curl "https://api.visena.example/acme/api/v1/en/person/xK9mQ2" \
-H "Authorization: Bearer $TOKEN"
Et oppslag på id returnerer hele entiteten, samme kropp som en oppretting eller en oppdatering returnerer. En id som ikke finnes gir 404; en streng som ikke er en maskert id i det hele tatt gir 400, fordi den feiler før noe oppslag. Å lese mange oppføringer — offset-paginering, cursor-paginering og endringsstrømmen — er et eget tema: se Lister, paginering og synk.
Oppdatere — to varianter
Begge verbene adresserer samme oppføring med id, og begge svarer 200 med den oppdaterte entiteten. De skiller seg i hva som skjer med feltene du ikke nevner, og det er forskjellen du må avklare før du skriver en synk.
PUT erstatter
PUT med Content-Type: application/json er en full erstatning: alle skrivbare felt du utelater blir tømt. Send hele oppføringen hver gang. Bruk det når systemet ditt eier oppføringen fullt ut og kopien der er sannheten.
curl -X PUT "https://api.visena.example/acme/api/v1/en/person/xK9mQ2" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Kari",
"lastName": "Nordmann",
"primaryEmail": "kari.nordmann@example.com",
"jobTitle": "Head of Operations"
}'
Det kallet setter stillingstittelen — og hadde denne personen en directPhone, er nummeret nå borte, fordi kroppen ikke nevnte det. created og createdBy er det ene unntaket: de er uforanderlige ved oppdatering og blir stille ignorert.
PATCH fletter
PATCH er en JSON Merge Patch (RFC 7396), sendt som application/merge-patch+json. Den endrer bare det kroppen nevner, og tre regler dekker det:
- Et felt du tar med og gir en verdi settes til den verdien.
- Et felt du setter til
nullblir tømt. - Et felt du utelater står akkurat som det sto.
# sets jobTitle, clears directPhone, touches nothing else
curl -X PATCH "https://api.visena.example/acme/api/v1/en/person/xK9mQ2" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/merge-patch+json" \
-d '{
"jobTitle": "Head of Operations",
"directPhone": null
}'
Ordet å passe på er null. Under PUT betyr en eksplisitt null og et utelatt felt det samme — begge tømmer verdien — fordi en erstatning ikke har noen måte å si «la denne være» på. Under PATCH er de motsetninger: null tømmer, utelatelse bevarer. Derfor er en klient som bygger én forespørselskropp og gjenbruker den for begge verbene den klassiske måten å viske ut et felt ingen mente å ta i. Har systemet ditt bare deler av oppføringen, bruk PATCH.
Medietypen for PATCH er ikke application/json. Den må være application/merge-patch+json; ren JSON avvises med 415 før kroppen leses i det hele tatt. En tom kropp {} er lovlig og en ren nulloperasjon — oppføringen kommer tilbake uendret, og ingenting skrives.
Slette
DELETE /{instanceName}/api/v1/{locale}/person/{personId}
curl -X DELETE "https://api.visena.example/acme/api/v1/en/person/xK9mQ2" \
-H "Authorization: Bearer $TOKEN"
# 204 No Content
Ikke alle slettinger ødelegger, og standardvalgene er bevisst de trygge. Å slette et selskap deaktiverer det med mindre du sier noe annet: ?mode=deactivate er standard og reversibelt, ?mode=delete er den harde slettingen. For en aktivitet er standarden ?mode=close. Å slette et prosjekt er alltid en myk lukking. En mode endepunktet ikke kjenner igjen gir 400 i stedet for en gjetning.
Ingenting kaskaderer i stillhet. Å slette en dokumentmappe som fortsatt inneholder dokumenter, eller et dokument med plasseringer under andre oppføringer, avvises med 409, og detail teller opp nøyaktig hva som ville fulgt med. Send på nytt med acknowledgeCascade=true for å bekrefte.
Svarkonvensjoner det er verdt å kjenne
- Et tomt felt er
null, ikke fraværende. En full entitetskropp bærer alle feltene på ressursen, og de uten verdi er JSONnull. At en nøkkel finnes forteller deg derfor ingenting — les verdien. Listekonvoluttene er det bevisste unntaket: en pagineringslenke eller cursor som ikke gjelder utelates, og fraværet er signalet om at det ikke finnes flere sider. created/modifiedogcreatedBy/modifiedBybærer den lagrede revisjonsattribusjonen: RFC 3339-tidsstempler normalisert til UTC, og maskerte person-id-er. Sender du dem ved en skriving, blir de attribusjonen; utelater du dem, stempler serveren «nå» og eieren av legitimasjonen.actedByer den maskerte id-en til brukeren en endring ble gjort som. Den fylles bare ut for kall gjort med en på-vegne-av-legitimasjon; en vanlig legitimasjon lar den stå somnull.- Referanser slås opp, ikke stoles på. En
companyId,groupId,responsiblePersonIdellermodifiedBysom ikke lar seg slå opp i instansen feiler hele kallet med 422. En avvist skriving etterlater ingenting halvskrevet. - Maskerte id-er er strenger. Sammenlign dem for likhet og ingenting annet: ingen rekkefølge, ingen regning, ingen konstruksjon av én fra et tall du har et sted.