Spring til indholdet
Sprog: Dansk

Det åbne API

Samme API som Terapeutbooking — på jeres egen adresse

Et regnskabsprogram, en hjemmeside eller et andet system, der allerede taler med Terapeutbooking/EasyPractice, skal kun skifte adresse og nøgle. Ruterne, felterne og fejlene er de samme.

Kom i gang

Ét kald, og I er i gang

Adressen er klinikkens egen: https://klinik.anotera.clinic/api/v1 — eller jeres eget domæne, hvis klinikken kører på det. Nøglen sendes som Bearer-token. JSON ind, JSON ud, UTF-8, tider i ISO 8601 med klinikkens tidszone.

curl https://klinik.anotera.clinic/api/v1/clients?active \
  -H "Authorization: Bearer an_…" \
  -H "Accept: application/json"

Lister kommer sideinddelt som hos dem: data, links og meta, med page og page_size (højst 100) i forespørgslen.

{
  "data": [
    { "id": "k-3f9a1c2b7d10", "name": "Anna Berg",
      "email": "anna@eksempel.dk", "phone": "+45 20 00 00 00",
      "address": "Gammelvej 1", "zip": "2000", "city": "Frederiksberg",
      "status": "active", "tags": [],
      "created_at": "2026-09-01T10:12:00+02:00" }
  ],
  "links": { "first": "…?page=1", "last": "…?page=1", "prev": null, "next": null },
  "meta": { "current_page": 1, "per_page": 15, "total": 1 }
}

Der er plads til 60 kald i minuttet pr. nøgle. Svaret bærer X-RateLimit-Limit og X-RateLimit-Remaining; over grænsen svares 429 med Retry-After.

API'et her er til programmer, der skal tale med Anotera. Skal klinikkens egne klienter, aftaler og notater med over fra det gamle system, er det en anden side: Flyt data ind fra Terapeutbooking.

Nøglen

Personlig, med præcis de rettigheder, I giver den

Nøglen laves i arbejdsbordet under Mere → Integrationer → Det åbne API. Den vises én gang og gemmes kun som et fingeraftryk hos os. Den gør det, psykologen selv må — og kun inden for de områder, der er krydset af:

  • clients-read · clients-readwrite — stamkort, mærkater og henvisninger
  • bookings-read · bookings-readwrite — aftaler, ledige tider og ydelser
  • calendars-read · calendars-readwrite — kalendere, åbningstider og pauser
  • journals-read · journals-readwrite — journalnotater — læse, eller skrive nye kladder ind
  • journal-files-read — filer på journalen, kun læse
  • invoices-read · invoices-readwrite — fakturaer, markér som betalt, send, hent PDF

Et kald uden for rettighederne svares 403 og nævner, hvilken rettighed der manglede. En nøgle kan trækkes tilbage i samme skærm; den holder op med at virke med det samme.

Formen

Felterne hedder det samme

En aftale oprettes som hos dem: start, end, client_id, products, eventuelt calendar_id, heading, notes, status og type (client_booking, blocked, other).

POST /api/v1/bookings
{
  "start": "2026-10-02T10:00:00+02:00",
  "end":   "2026-10-02T10:50:00+02:00",
  "client_id": "k-3f9a1c2b7d10",
  "products": [{ "id": "individuel" }],
  "notes": "Første samtale"
}

Fejl i det, der sendes, svares 422 med feltet og forklaringen — på klinikkens sprog:

HTTP 422
{
  "error": { "message": "The given data was invalid.",
             "status_code": 422 },
  "data":  { "start": ["Tiden ligger uden for åbningstiden"] }
}

Status på en aftale: pending, confirmed, finished, no_show, cancelled. Findes noget ikke, svares 404; kan det ikke lade sig gøre (et låst notat, en klient med journal), svares 409.

Ruterne

Alle ruter

Rettigheden i tredje kolonne er den, nøglen skal have. Alle stier ligger under /api/v1.

Nøglen

  • GET/me—Hvem nøglen er, og hvad den må

Klienter

  • GET/clientsclients-readListen. Filtre: active, inactive, has_email, has_phone, email, cpr, tag_id, search, order_by_created|updated|email
  • POST/clientsclients-readwriteOpret. name er krævet; email, phone, address, zip, city, cpr, date_of_birth, notes, tags, ean
  • GET/clients/{id}clients-readÉt stamkort
  • PUT/clients/{id}clients-readwriteRet. Kun de felter, der sendes, ændres
  • DELETE/clients/{id}clients-readwriteSlet — kun en klient uden journal; ellers 409
  • GET/client-tagsclients-readKlinikkens mærkater
  • GET/client-vouchersclients-readHenvisninger og forløb med klip
  • GET/client-custom-attributesclients-readEgne felter (tom liste — vi har ingen)

Kalender

  • GET/calendarscalendars-readKlinikkens behandlere som kalendere
  • GET/calendars/{id}calendars-readÉn kalender
  • GET/calendars/{id}/opening-timescalendars-readUgen: monday_start, monday_end, monday_closed … og pausen efter hver samtale
  • PUT/calendars/{id}/opening-timescalendars-readwriteRet ugen — kun sin egen kalender
  • GET/calendars/{id}/pausescalendars-readLukninger: ferie, kursus, en fridag
  • POST/calendars/{id}/pausescalendars-readwriteNy lukning: date, start_time, end_time, reason
  • DELETE/calendars/{id}/pauses/{pause}calendars-readwriteFjern en lukning
  • GET/servicesbookings-readYdelser med varighed og pris (/products virker også)

Aftaler

  • GET/bookingsbookings-readAftaler i et vindue: start, end; filtre client_id, calendar_id, product_id, status
  • POST/bookingsbookings-readwriteNy aftale — se formen ovenfor
  • POST/bookings/bulkbookings-readwriteFlere på én gang; hver får sit eget svar
  • GET/bookings/{id}bookings-readÉn aftale, med video_link, hvis den er et videomøde
  • PUT/bookings/{id}bookings-readwriteFlyt (start/end), skift status, ret overskrift og noter
  • DELETE/bookings/{id}bookings-readwriteAflys — aftalen står tilbage som cancelled
  • GET/online-booking/available-datesbookings-readDage med ledig tid: product_id, from, to
  • GET/online-booking/available-timesbookings-readLedige tider på én dag: product_id, date

Journal

  • GET/clients/{id}/journalsjournals-readNotater på klienten; filtre locked, draft
  • POST/clients/{id}/journalsjournals-readwriteNyt notat: content, date, draft. Uden draft låses det med det samme
  • GET/clients/{id}/journals/{journal}journals-readÉt notat
  • PUT/clients/{id}/journals/{journal}journals-readwriteRet en kladde — eller lås den med locked: true. Et låst notat kan ikke rettes: 409
  • DELETE/clients/{id}/journals/{journal}journals-readwriteSlet en kladde. Et låst notat kan ikke slettes: 409
  • GET/clients/{id}/journal-filesjournal-files-readFiler på journalen
  • GET/clients/{id}/journal-files/{file}journal-files-readÉn fil: navn, type, størrelse
  • GET/clients/{id}/journal-files/{file}/downloadjournal-files-readSelve filen

Fakturaer

  • GET/invoicesinvoices-readFakturaer; filtre client_id, paid, unpaid, number, include_credit_notes
  • GET/invoices/{id}invoices-readÉn faktura med linjer og sum
  • POST/invoices/{id}/mark-as-paidinvoices-readwriteMarkér som betalt: date, payment_type, eventuelt amount (ellers resten)
  • POST/invoices/{id}/sendinvoices-readwriteSend på mail til modtageren: subject, text
  • GET/invoices/{id}/pdfinvoices-readFakturaen som PDF

Forskellene

Det, der er anderledes — med vilje

  • Id’erne er tekst, ikke tal. k-3f9a1c2b7d10, ikke 4711. Et system, der regner med heltal, skal bruge en streng.
  • Journalen er krypteret med psykologens nøgle. Et notat, der skrives ind udefra, ligger i journalen som ethvert andet — og et låst notat kan hverken rettes eller slettes, uanset hvem der spørger. Det er journalføringsbekendtgørelsen, ikke en teknisk begrænsning.
  • Der er intet EasyPay. /easypay/* svarer 404 med en forklaring. Betalinger går gennem fakturaerne.
  • Kalendere oprettes ikke gennem API’et. En kalender er en behandler, og behandlere kommer ind gennem arbejdsbordet.
  • En aftale slettes ikke — den aflyses. Den står tilbage som cancelled, så tallene og journalen stemmer bagefter.

Mangler I en rute, I bruger hos dem? Skriv til kontakt@anoteraclinic.com med kaldet, så ser vi på det.