Guide 2 af 9
På denne side
Autentificering og scopes
Bearer-nøglen
Hvert kald bærer nøglen i en standard Authorization-header:
GET /api/v1/invoices?per_page=50 HTTP/1.1
Host: app.levano.io
Authorization: Bearer lev_live_...
Accept: application/jsonDer er ingen alternativ. Nøglen må ikke lægges i en query-parameter: den ender i adgangslogs, i browserhistorik og i referer-headere, og den kan ikke roteres væk fra dem igen.
Mangler headeren, eller er nøglen ukendt, spærret eller udløbet, får du 401 med {"message": "Unauthenticated."}.
Én organisation pr. nøgle
Nøglen bærer organisationen. Du sender aldrig et organisations-id, og der er ingen parameter der kan skifte den.
Det er ikke bare en konvention i controllerne. Tenant-afgrænsningen sidder på modellerne, og uden en gyldig nøgle er der ingen tenant, så en forespørgsel uden autentificering rammer nul rækker frem for alle. Konsekvensen i praksis: et id fra en anden organisation opfører sig præcis som et id der ikke findes.
Scopes
Scopes hedder ressource:handling. Nøglen får dem tildelt ved oprettelsen, og hvert endpoint kræver præcis ét.
| Scope | Åbner |
|---|---|
matters:read |
/matters, /matters/{id} |
clients:read |
/clients, /clients/{id}, /people, /people/{id}, /companies, /companies/{id} |
time:read |
/time-entries |
invoices:read |
/invoices, /invoices/{id} |
documents:read |
/documents, /documents/{id}. Kun metadata, aldrig filens indhold |
signing:read |
/signing-flows, /signing-flows/{id} og flowets bevisspor |
signing:write |
Opret, ret, send, annullér og slet et underskriftsflow, og hele underskriverlisten |
reports:read |
/reports/{type} |
webhooks:manage |
Hele /webhooks-familien, både læsning og skrivning |
clients:read dækker både engagementet og parterne bag det, altså personer og virksomheder. Det er ét scope, ikke tre, fordi de tre lister beskriver den samme relation set fra hver sin side.
signing:write er den eneste skrivning i v1 der ikke er create only, fordi et underskriftsflow er en arbejdsgang du driver. Se Underskrifter. Den bærer også dokumentet på flowet: at uploade en PDF eller pege på et dokument fra biblioteket kræver hverken documents:read eller dokumentmodulet, for Sign sælges for sig.
To navne er reserveret i kataloget, men har ingen endpoints: settings:read og settings:write. Du kan sætte dem på en nøgle i dag, og de åbner ikke noget før de gør. Byg ikke logik på dem endnu.
Den autoritative liste står på hver enkelt operation i referencen. Bliver tabellen her uenig med den, er referencen den der er rigtig.
Et modul du ikke har svarer 404
Nogle endpoints hører til et modul en advokatvirksomhed køber for sig. Har organisationen det ikke, er svaret 404, præcis som in-app-ruten giver, og ikke 403. Det er med vilje: svaret må ikke afsløre hvilke moduler en virksomhed har.
| Scope | Kræver modulet |
|---|---|
time:read, time:write |
time_tracking |
invoices:read |
billing |
reports:read |
reports |
signing:read, signing:write |
sign |
En nøgle med det rigtige scope kan altså stadig få 404 på hele familien. Rammer du det på alle stier under ét scope på én gang, er det modulet og ikke nøglen.
Et udløbet abonnement spærrer kun skrivninger
Er organisationens abonnement ikke aktivt, afvises POST, PATCH og DELETE med 403 og code: "subscription_inactive". GET bliver ved med at virke.
Den asymmetri er bevidst: en virksomhed skal altid kunne hente sine egne data ud, også efter at have sagt op.
Giv den mindst mulige nøgle
Et scope kan ikke tilføjes til en nøgle bagefter. Det er med vilje: en nøgle der stille voksede sig større er svær at revidere. Skal integrationen kunne mere, opretter du en ny nøgle med det rigtige sæt og udfaser den gamle.
Så vælg smalt fra start. En rapporteringsintegration skal have invoices:read og reports:read, ikke også clients:read, fordi det var nemmere at klikke alle af.
Rotation sker med overlap
En klient kan have flere aktive hemmeligheder på én gang, og det er hele pointen med rotationsflowet. Under Indstillinger, API-nøgler kan en administrator:
- Rotere: der udstedes en ekstra hemmelighed. Den gamle bliver ved med at virke, indtil nogen spærrer den. Så rækkefølgen er: rotér, udrul den nye nøgle, kontrollér at trafikken er flyttet, spær så den gamle.
- Spærre en hemmelighed: netop den streng holder op med at virke. Klienten og dens øvrige hemmeligheder er upåvirkede.
- Spærre klienten: alle dens hemmeligheder dør sammen med den.
401fra første kald efter.
Spærring slår igennem med det samme, uden nådeperiode. En nøgle kan også have en udløbsdato ved oprettelsen. Efter det tidspunkt svarer den 401 uden yderligere varsel, så sæt en påmindelse hvis du bruger udløb.
Manglende scope svarer 403
Har nøglen ikke det scope endpointet kræver, får du 403 med navnet på det scope der mangler:
{
"message": "Insufficient scope.",
"required_scope": "invoices:read"
}Feltet er der så du kan skrive en brugbar fejl i din egen log frem for "adgang nægtet". Se Fejl og rate limits for de øvrige koder.
KYC-API'en har sine egne tokens
/api/kyc/v1 er en selvstændig kontrakt med sit eget token, oprettet under Indstillinger, KYC API. En åben-API-nøgle virker ikke der, og omvendt. KYC-tokens har ikke scopes: tokenet giver adgang til hele KYC-kontrakten for den ene organisation.