# Kom i gang

Sidst opdateret 10. september 2026
Kilde: https://plas.redia.dk/kom-i-gang/

Det du skal vide før det første kald mod et bibliotekssystem der implementerer PLAS Provider API — og hvor referencen tager over derfra.

PLAS Provider API er den grænseflade et bibliotekssystem stiller til rådighed, så biblioteksprodukter kan læse og skrive lånere, lån, reserveringer og beholdning uden at kende systemet bagved. Den der implementerer grænsefladen kaldes *provideren*; den der kalder den, kaldes *klienten*. Denne side er skrevet til klienten — det sidste afsnit til provideren.

Siden beskriver **Provider API v0.6.5**, den version *PLAS Status* kalder i produktion. v0.6.6 er i specifikation. Spec'en siger selv at den stadig er under arbejde, og at felter og struktur kan ændre sig.

## Indhold

- [Forudsætninger](#forudsætninger)
- [Base-URL](#base-url)
- [Autentificering](#autentificering)
- [Første kald](#første-kald)
- [Fælles regler for alle kald](#fælles-regler-for-alle-kald)
- [Fejl](#fejl)
- [Implementerer du selv API'et?](#implementerer-du-selv-apiet)
- [Næste skridt](#næste-skridt)

## Forudsætninger

- Et bibliotekssystem der implementerer Provider API v0.6.5.
- Systemets **base-URL** og et sæt **client credentials** (`client_id` og `client_secret`). Begge udleveres af provideren — det er den der afgør hvem der må kalde.
- Et værktøj der kan sende HTTP-kald og læse JSON.

## Base-URL

Spec'en har ingen `servers`-blok. Base-URL'en er providerens, ikke PLAS', og den aftales med provideren. Alle stier i referencen — `/version`, `/patron/{patronId}`, `/authentication/oauth2/token` — er relative til den.

Spec'en beskriver to måder en provider kan kende sine kaldere på: en **base-URL pr. bibliotek** (så samme produkt kalder forskellige adresser hos forskellige biblioteker) eller **én base-URL for alle**, hvor credentials afgør både bibliotek og leverandør. Regn derfor ikke med at base-URL'en er den samme fra bibliotek til bibliotek, selv hos samme provider.

## Autentificering

Provider API'et bruger OAuth 2.0 med *client credentials*. Ét kald giver et token; tokenet sendes med på alle øvrige kald.

**Hent et token.** Send et `POST` til `/authentication/oauth2/token` med `Content-Type: application/x-www-form-urlencoded` og tre felter: `client_id`, `client_secret` og `grant_type` med værdien `client_credentials`. Kaldet kræver ikke selv et token.

```http
POST /authentication/oauth2/token
Content-Type: application/x-www-form-urlencoded

client_id=<client_id>&client_secret=<client_secret>&grant_type=client_credentials
```

Svaret er JSON med tre felter — alle påkrævede:

- `access_token` — selve tokenet. Spec'en anbefaler provideren at udstede et JWT, så en tredjepart (fx en søge-API) kan validere det uden at spørge provideren.
- `token_type` — altid `Bearer`.
- `expires_in` — tokenets levetid i sekunder.

**Brug tokenet.** Sæt det i `Authorization`-headeren på hvert kald: `Authorization: Bearer <access_token>`.

**Når det udløber.** HTTP `401` betyder at tokenet mangler, er ugyldigt eller er udløbet. Hent et nyt og prøv igen. Skemaerne står i referencen: [AuthenticationClientCredentialsRequestBody](/provider/v0.6.5/schemas/#AuthenticationClientCredentialsRequestBody) og [AuthenticationClientResponseBody](/provider/v0.6.5/schemas/#AuthenticationClientResponseBody); operationen er [AuthenticateClient](/provider/v0.6.5/authentication/#AuthenticateClient).

## Første kald

Start med `GET /version`. Det er det ene kald der ikke kræver et token, og svaret siger hvilken version af API'et provideren anbefaler — så du ved at base-URL'en er rigtig, og hvilken version du skal bede om, før du autentificerer.

Svaret har ét felt, `version`. Operationen er [GetVersion](/provider/v0.6.5/version/#GetVersion).

Hent derefter et token, og kald den første operation i den gruppe dit produkt har brug for — fx [Patron](/provider/v0.6.5/patron/) for lånerdata eller [Holding](/provider/v0.6.5/holding/) for beholdning. Hver gruppe har sin egen side i referencen med parametre, request body og svar pr. operation.

## Fælles regler for alle kald

Disse regler står én gang i spec'en og gælder overalt. Den delte kontrakt — parametre og fejlsvar som næsten alle operationer deler — står på [versionsoversigten](/provider/v0.6.5/).

- **`version`** (query, valgfri) — den API-version klienten forventer. Understøtter provideren den ikke, svarer den med fejlkode `600`. Send den; så opdager du en versionsforskel som en fejl i stedet for som et forkert felt.
- **`ui_language`** (query, valgfri) — det sprog provideren returnerer tekster i. Koderne følger [MARC-sproglisten](https://www.loc.gov/marc/languages/).
- **URL- og query-parametre** skal være URL-encodede. Et id med komma i en kommasepareret liste encodes derfor til `%2C`.
- **Datoer og tidspunkter** følger RFC 3339. Et tidspunkt skrives som `date-time` med stort `T` og eksplicit tidszone — spec'en antager ingen. En ren dato skrives `YYYY-MM-DD`.
- **Svar indeholder ikke HTML**, medmindre operationen udtrykkeligt siger det.
- **Opslag på en liste af id'er** returnerer kun de id'er provideren kender. Ukendte id'er udelades; er alle ukendte, er svaret et tomt map.

## Fejl

Et fejlsvar har to felter, `code` og `info` ([Error](/provider/v0.6.5/schemas/#Error)). Koden er et tal, og den fulde liste står i skemaet [ErrorCode](/provider/v0.6.5/schemas/#ErrorCode). De tre du møder først:

- `500` — systemfejl hos provideren.
- `600` — den version du bad om, understøttes ikke.
- `10001` — operationen er slået fra hos denne provider.

Resten er domænespecifikke — fx `100023` for et ukendt `patronId` og `102001` for et ukendt lån — og står på den operation de hører til. HTTP-koderne `400`, `401` og `404` er delte svar og beskrives på [versionsoversigten](/provider/v0.6.5/).

## Implementerer du selv API'et?

Så er du provideren, og spec'en giver tre anbefalinger ud over selve operationerne:

- **Brug UUID som `patronId`.** Bruger systemet heltal som låner-id, så læg et UUID ved siden af og brug kun det i PLAS.
- **Beskyt låner-login mod brute force.** `POST /patron/authentication` og `POST /patron/authentication/no-password` skal have rate limiting pr. låner-identifikator.
- **Vælg hvordan du kender dine kaldere** — base-URL pr. bibliotek, credentials pr. leverandør, eller begge. Token-endpointet `/authentication/oauth2/token` er dit at implementere.

## Næste skridt

- [Versionsoversigten](/provider/v0.6.5/) — den delte kontrakt og alle 21 grupper.
- [Skema-indekset](/provider/v0.6.5/schemas/) — alle 379 skemaer, ét niveau dybt.
- [API-referencen](/apier/) — de fire API’er, og hvordan de hænger sammen.
