Referanse
API-referanse
Kontrakten for Partner API, endepunkt for endepunkt: hver rute, parameter, forespørselskropp, svarstruktur og statuskode, med et kopiklart eksempel på hvert endepunkt. Denne siden bærer det de alle deler.
Endepunktreferansen står på engelsk i begge språktrærne. Den gjengir API-kontrakten ordrett, og det finnes ingen generator å bygge den på nytt fra, så en oversatt kopi ville drevet fra API-et første gang et endepunkt endres.
Base-URL-en
Eksemplene bruker plassholderen https://api.visena.example som base-URL og instansnavnet acme; bytt ut begge med verdiene du fikk under onboarding. Alle forretningsstier starter med instansnavnet, så API-versjonen, så en locale, så ressursen:
Ressursnavnene er i entall, og stien har ikke noe partner/-segment: den er /{instanceName}/api/v1/{locale}/person, aldri /partner/api/v1/en/persons. Hvert endepunkt i referansen er skrevet ut med de to første stiparameterne på plass.
Token-endepunktet er det ene unntaket, fordi det ikke er et forretningsendepunkt: det ligger på /{instanceName}/auth/api/v1/token — instansnavnet, så den faste autentiseringsflaten, og ingen locale.
Ressurser
Ni ressurser utgjør flaten i dag. Hver av dem har sin egen side med en endepunktliste, den fulle kontrakten for hvert endepunkt, og objektstrukturene endepunktene utveksler.
Person →
Kontakter, ansatte og brukerkontoer. Full CRUD, duplikatsøk, planlagt slettedato og en funksjonsstyrt GDPR-sletting.
Les og skrivCompany →
Full CRUD og duplikatsøk. Et organisasjonsnummer er unikt per instans, og sletting deaktiverer som standard.
Kun lesingCompany template →
Listing og oppslag. Malen refereres fra kroppene som oppretter og oppdaterer et selskap.
Les og skrivProject →
Full CRUD. Oppretting krever en templateId, og sletting lukker prosjektet istedenfor å fjerne det.
Project template →
Listing og oppslag. Prosjektets mal bestemmer typen og hvilke klassifiseringer det har tilgjengelig.
Les og skrivActivity →
Arbeidspostene på et prosjekt. Full CRUD; sletting lukker som standard, og kan be om permanent fjerning.
Les og skrivDocument →
Opplasting og nedlasting med multipart, endring av metadata, utbytting av innholdet, og flytting mellom mapper.
Les og skrivDocument folder →
Mappetreet under en eiende enhet: opprette, liste, gi nytt navn, flytte, laste ned som zip, og en sletting som bekrefter hva den tar med seg.
Kun lesingDocument changes →
Endringsstrømmen bak dokumentsynkronisering: registrerte endringer på dokumenter og mapper, paginert med markør.
Å lese denne referansen
Alle ressurssidene er bygget likt, så den andre du leser trenger ingen orientering:
- En endepunktliste øverst — metode, sti og sammendrag, hver med lenke ned til endepunktet.
- Én seksjon per endepunkt: metoden og den fulle stien, hva det gjør, parameterne, forespørselskroppen, en tabell over svarene det kan gi, og et curl-eksempel.
- Objektstrukturer nederst: hver forespørsels- og svarkropp siden viser til, felt for felt.
Ankrene til endepunktene er stabile. Id-en til en seksjon er operasjons-id-en fra kontrakten — #createPerson, #listPersonsByCursor — og den er den samme i begge språktrærne, så en dyplenke du limer inn i en sak fortsetter å virke.
Det ressurssidene med vilje utelater: de to første stiparameterne, som står på denne siden, og de fire fellesfeilene, som står under Feil og feilsøking. For gjennomgåtte eksempler, integrasjonsmønstre og den veiledede introduksjonen leser du guiden først — Kom i gang er den korte veien fra en legitimasjon til det første svaret.
Den samme flaten finnes som et OpenAPI 3.0-dokument for import i Postman, Insomnia eller en kodegenerator — spør Visena-kontakten din om partner-openapi.json.
Autentisering
Én standard OAuth 2.0-forespørsel gjør clientId og clientSecret om til et kortlevd bearer-token, avgrenset til nøyaktig det du ber om. Alle andre endepunkter i denne referansen krever det tokenet. Hvordan du oppretter legitimasjonen i grensesnittet, og en token-cache verdt å kopiere, står under Legitimasjon og tokener.
Scopes
Skjemafeltet scope er obligatorisk — en token-forespørsel uten det avvises med 400 invalid_scope. Du kan be om hele scope-settet legitimasjonen din har, eller en delmengde av det:
| Scope | Tillater |
|---|---|
read |
All safe methods — GET reads, lists, downloads and change feeds. |
write |
All mutations — POST, PUT, PATCH, DELETE. |
act-as-user:read |
Safe methods with an on-behalf credential (one issued to act for a specific named user). |
act-as-user:write |
Mutations with an on-behalf credential. Mutation responses carrying an entity body echo the acting user's masked id in actedBy. |
De to familiene blandes aldri: en vanlig legitimasjon hører til read/write-familien, en på-vegne-av-legitimasjon til act-as-user:*-familien — og innenfor familien har en legitimasjon opprettet som Bare lesing bare lese-scopet. Ber du om et scope legitimasjonen ikke har, får du 400 invalid_scope. Be bare om det jobben trenger — en eksportjobb har ingenting å gjøre med write.
Tokenets livsløp
- Tokener er ugjennomsiktige. Dekod eller inspiser aldri et
access_token; behandle det som tilfeldig tekst. expires_iner autoritativ. Les levetiden fra hvert svar; ikke hardkod den.- Det finnes ikke noe refresh token. Når et token utløper, kjører du samme forespørsel på nytt — utvekslingen er billig.
- Cache og gjenbruk. Utsted én gang, gjenbruk til omtrent 60 sekunder før utløp, og utsted så på nytt. Utsted aldri per forespørsel.
Å bruke tokenet
Send det på hver forespørsel som Authorization: Bearer <access_token>. Tokenet virker bare på instansen det ble utstedt for, og scopene håndheves per forespørsel: trygge metoder krever read-scopet, endringer krever write-scopet.
Exchange a credential for an access token
POST /{instanceName}/auth/api/v1/token
Standard OAuth 2.0 client_credentials grant. Authenticate with HTTP Basic (clientId as user name, clientSecret as password) or with client_id/client_secret form fields. The scope parameter is mandatory and must be a subset of the scopes the credential holds — the platform never picks a default.
There is no refresh token: when the token expires, run the same request again. Cache the token and reuse it until shortly before expires_in runs out.
Forespørselskropp
application/x-www-form-urlencoded → object
Svar
| Status | Beskrivelse |
|---|---|
| 200 | The access token. TokenResponse · application/json |
| 400 | invalid_scope — scope missing or not held by this credential; invalid_request/invalid_grant — malformed body or wrong grant type. |
| 401 | invalid_client — wrong client_id/client_secret, or the credential was revoked. |
Dette endepunktet svarer ikke med et problemdokument. Det feiler på OAuth 2.0-måten, med en error-kode og en error_description — se Feil og feilsøking.
Eksempel
curl -X POST https://api.visena.example/acme/auth/api/v1/token \
-u "acme-partner-3f9a:$CLIENT_SECRET" \
-d "grant_type=client_credentials" \
-d "scope=read write"
{
"access_token": "PhVYGf3qK9t2Zx0CmW8rNbL5aTuJdEwSyAoQiHkXgMfDzUcRvBnOl46E…",
"scope": "read write",
"token_type": "Bearer",
"expires_in": 86399
}
Objektstrukturer
Kroppene tokenutvekslingen returnerer. Alle andre objektstrukturer er dokumentert på ressurssiden som bruker dem.
TokenResponse
| Felt | Type | Beskrivelse |
|---|---|---|
access_token required |
string |
The bearer token. Opaque — send it back verbatim. |
token_type required |
string |
|
expires_in required |
integer |
Seconds until the token expires. Read it from every response; never hardcode a lifetime. |
scope required |
string |
The scopes actually granted, space-separated. |
OAuthError
| Felt | Type | Beskrivelse |
|---|---|---|
error required |
string |
Machine-readable OAuth 2.0 error code, e.g. invalid_client, invalid_scope. |
error_description |
string |
Human-readable explanation. |
URL-struktur
Alt herfra og ned deles av hvert endepunkt på hver ressursside. Ressurssidene tar det for gitt og gjentar det aldri.
Forretningsendepunktene ligger på /{instanceName}/api/v1/{locale}/…, og de to stiparameterne er grunnen til at ingen endepunkttabell lister dem. {instanceName} er kundeinstansen legitimasjonen din hører til — et token utstedt for én instans får 403 alle andre steder, og et instansnavn som ikke finnes får 404 på alle endepunkter samtidig. {locale} (en eller no) velger språket i den menneskelesbare teksten, tydeligst i detail på en feil; det endrer aldri feltnavn, formater eller oppførsel.
Headere
| Header | Verdi |
|---|---|
Authorization |
Bearer <access_token> — on every request. |
Content-Type |
application/json on POST and PUT · application/merge-patch+json on PATCH · multipart/form-data on file uploads · omit on GET and DELETE. |
Id-er, tidsstempler, felter
- Maskerte id-er. Hver id er en ugjennomsiktig streng som
xK9mQ2. Lagre og send den tilbake ordrett; parse, sorter eller konstruer aldri en. En feilformet id svarer 400; en velformet id som ikke finnes svarer 404 som sti-id, eller 422 som referanse inne i en kropp. - Tidsstempler.
createdogmodifieder ISO-8601-tidspunkter med offset. Rene datofelter, for eksempeldueDate, erYYYY-MM-DD. - Fraværende betyr fraværende. Valgfrie felter uten verdi utelates fra svar-JSON, de sendes ikke som
null. - Overstyring av sporingsdata. Kropper som oppretter tar valgfrie
created/createdBy, og kropper som oppdaterermodified/modifiedBy, for å tilskrive en endring når du migrerer data; standardverdiene er tjener-nå og eieren av legitimasjonen. En personreferanse som ikke finnes svarer 422. actedBy. Endringer gjort med et på-vegne-av-token gjengir den handlende brukerens maskerte id i svarkroppen.
Oppdateringer: PUT mot PATCH
PUT erstatter hele posten — alt du utelater behandles som tomt. PATCH er JSON Merge Patch etter RFC 7396 og krever Content-Type: application/merge-patch+json; alt annet svarer 415. Et felt du tar med oppdateres, et felt du setter til null tømmes, et felt du utelater røres ikke, og en tom kropp {} er en gyldig ikke-endring.
Paginering — tre lesemoduser
Hver samling tilbyr opptil tre listevarianter. Kontrakten er den samme på tvers av ressurser, så strukturen nedenfor er den du får på /company og /activity også; ressurssidene legger bare til sine egne filtre og projeksjoner. Hvilken modus som passer til hvilken jobb — og hvordan du bygger en synk som ikke mister rader — står under Lister, paginering og synk.
| Modus | Sti | Pagineringsparametere | Svarkonvolutt |
|---|---|---|---|
| Offset | GET /person |
offset (standard 0) · limit |
Elementer, et reelt totalantall og navigasjonslenker. |
| Cursor | GET /person/cursor |
cursor · limit |
Elementer, nextCursor/prevCursor og lenker. Ingen totalsum — keyset-paginering hopper over opptellingen. |
| Timeline | GET /person/timeline |
since · key (created eller modified) · cursor · limit |
Markørkonvolutten, over alt som er opprettet eller endret siden den nedre grensen. |
Utelat cursor for den første siden; en markør utstedt for én key avvises på en annen med 400. På person og company tar alle tre variantene også view, som velger projeksjonen av hvert element: lean (standarden) gir den kompakte listeraden, full gir for hver rad den samme kroppen som oppslaget på én post gir, og view=full setter et tak på limit på 100.
{
"totalItems": 143,
"totalPages": 8,
"page": 0,
"size": 20,
"items": [ { "id": "xK9mQ2", … }, … ],
"links": {
"self": "/acme/api/v1/en/person?offset=0&limit=20",
"first": "/acme/api/v1/en/person?offset=0&limit=20",
"next": "/acme/api/v1/en/person?offset=20&limit=20",
"last": "/acme/api/v1/en/person?offset=140&limit=20"
}
}
{
"items": [ { "id": "xK9mQ2", … }, … ],
"nextCursor": "Qm5PbDQ2RXhLOW1RMnRaeDBDbVc4…",
"prevCursor": "TmJMNWFUdUpkRXdTeUFvUWlIa1hn…",
"links": {
"self": "/acme/api/v1/en/person/cursor?limit=20",
"next": "/acme/api/v1/en/person/cursor?cursor=Qm5PbDQ2RXhLOW1RMnRaeDBDbVc4…&limit=20"
}
}
| Medlem | Hva det er |
|---|---|
items |
Radene på denne siden, i projeksjonen ressursens view-parameter velger der den finnes. Markør- og tidslinjesider er i stigende nøkkelrekkefølge. |
totalItems totalPages page size |
Bare i offset-modus: antall rader som matcher, antall sider ved gjeldende sidestørrelse, nullbasert indeks for denne siden, og sidestørrelsen som faktisk ble brukt. |
nextCursor prevCursor |
Bare i markør- og tidslinjemodus. Ugjennomsiktige sidemarkører; nextCursor mangler på den siste siden og prevCursor på den første. |
links |
Navigasjonslenker etter RFC 8288 i kroppen: self, next og prev der de gjelder, og i tillegg first og last på offset-endepunktet. |
Følg links, ikke bygg URL-er. Hver lenke tar vare på filtrene dine og er en gyldig sti mot samme base-URL. Mangler next, er dette den siste siden, og markørene er ugjennomsiktige — rediger aldri en. Dokumenter har i tillegg en egen endringsstrøm på plasseringsnivå oppå disse tre: Document changes.
Feil
Alt som ikke er 2xx fra forretnings-API-et er et problemdokument etter RFC 9457, med Content-Type: application/problem+json. Forgren på status og type; vis detail til mennesker — den oversettes av {locale}-segmentet og navngir feltet som feilet ved validering — men parse den aldri.
{
"timestamp": "2026-08-21T11:58:21.123Z",
"status": 422,
"type": "urn:visena:validation:illegal-argument",
"errorType": "ILLEGAL_ARGUMENT",
"title": "Unprocessable Entity",
"detail": "companyId 'bQ4wR8' does not resolve to an existing company",
"instance": "/acme/api/v1/en/person"
}
Dokumentet medlem for medlem, hva du gjør med hver statuskode, og en gjenforsøkspolicy verdt å kopiere står under Feil og feilsøking. Token-endepunktet er unntaket beskrevet over: det feiler på OAuth 2.0-måten istedenfor med et problemdokument.
Fellesfeil — alle endepunkter
Ressurssidene lister bare svarene som er spesifikke for et endepunkt. I tillegg til dem kan hvert endepunkt svare med disse fire:
| Status | Betydning |
|---|---|
| 401 | Missing, expired or revoked token. Mint a fresh token and retry once. |
| 403 | The token lacks the scope this method requires, or it was minted for another instance. |
| 404 | Unknown instance name in the URL. |
| 500 | Unexpected server error. Retry with exponential backoff, and report the problem body's timestamp if it persists. |
Et endepunkt kan gi den samme koden en smalere betydning — de fleste 404 handler om id-en i stien, ikke om instansnavnet. Der et endepunkt dokumenterer en kode selv, er dets egen svartabell autoriteten; de fire over er dokumentert én gang, i sin helhet, under Fellesfeil.