Spring til indhold

API og udviklere

Alle klinikkens data. Ind og ud.

Et fuldt REST API til patienter, bookinger, journal, økonomi og HR – med nøgler, I selv styrer, webhooks og eksport af alt.

GET /api/public/v1/patients
export HUBHUS=https://…   # the address you log in on
export TOKEN=hh_live_…

curl "$HUBHUS/api/public/v1/patients?limit=100" \
  -H "Authorization: Bearer $TOKEN"

# → { "data": [ … ], "next_cursor": "4f1c…" }
# next page:     ?cursor=4f1c…
# changed since: ?since=2026-10-01T00:00:00Z

Nøgler med rettigheder og udløb

Nøgler oprettes under Admin → API af brugere med rettigheden til det. Hver nøgle hører til én klinik, har valgte rettigheder pr. område (læse/skrive) og udløber efter højst 365 dage. Den vises kun én gang og kan trækkes tilbage med det samme.

Sider og synkronisering

Lister returnerer op til 500 rækker pr. side sorteret efter id. Brug next_cursor til næste side og since til kun at hente det, der er oprettet eller ændret siden sidst.

Grænser

120 kald pr. minut pr. nøgle. Ved for mange kald svarer API'et 429 med Retry-After. Svar caches aldrig.

Klinikadskillelse og CPR

En nøgle ser kun sin egen kliniks data – også i henvisninger. CPR-numre er maskeret uden rettigheden patients:cpr, og hver fuld visning logges. Valgfri liste over tilladte IP-adresser.

Kom i gang på fem minutter

  1. 1Log ind, gå til Admin → API, og opret en nøgle. Vælg rettigheder og hvor længe den skal virke.
  2. 2Kopiér nøglen med det samme – den vises kun én gang.
  3. 3Send den i Authorization-headeren som Bearer-token.
  4. 4Hent OpenAPI-beskrivelsen og generér en klient i jeres sprog, eller brug eksemplerne her.

Har I ikke en konto endnu? Opret en gratis prøvekonto – den har en demoklinik med opdigtede data, I kan teste mod.

Book en tid
# 1) Free times (UTC) for one or more services
curl "$HUBHUS/api/public/v1/availability?serviceIds=SERVICE_ID&fromDate=2026-11-02&days=7" \
  -H "Authorization: Bearer $TOKEN"

# 2) Book one of them – 409 if someone took it in the meantime
curl -X POST $HUBHUS/api/public/v1/bookings \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"serviceIds":["SERVICE_ID"],"patientType":"new","start":"2026-11-02T08:30:00Z",
       "patient":{"name":"Test Person","phone":"+4512345678","email":"test@example.com"}}'

Endepunkter

24 områder. Rettighederne hedder område:read og område:write – skrive giver også læse. Felterne nedenfor er dem, API'et returnerer.

Patienter

patientsPatientstamdata. CPR vises maskeret, medmindre nøglen har CPR-rettigheden.patients:readpatients:writesince
  • GET /api/public/v1/patients
  • GET /api/public/v1/patients/{id}
  • POST /api/public/v1/patients
  • PATCH /api/public/v1/patients/{id}
FeltType
addressstring · null
archivedboolean
birth_datestring (date) · null
clinic_idstring (uuid) · null
consentsjson
created_atstring (date-time)
emailstring
external_refstring · null
gp_namestring · null
idstring (uuid)
insurance_groupstring
namestring
notestring · null
phonestring
relative_namestring · null
relative_phonestring · null
updated_atstring (date-time)
cprstring · null
medicalAnamnese-versioner. Kan kun tilføjes, aldrig ændres.medical:readsince
  • GET /api/public/v1/medical
  • GET /api/public/v1/medical/{id}
FeltType
author_emailstring
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
datajson
idstring (uuid)
patient_idstring (uuid)
warningsarray
consentsUnderskrevne samtykker til behandlingsplaner med låst kopi af planen.consents:readsince
  • GET /api/public/v1/consents
  • GET /api/public/v1/consents/{id}
FeltType
clinic_idstring (uuid)
idstring (uuid)
patient_idstring (uuid)
plan_idstring (uuid)
plan_snapshotjson
recorded_bystring · null
signature_pngstring
signed_atstring (date-time)
signer_namestring
signer_relationstring
snapshot_sha256string

Booking

bookingsAftaler. Oprettes og flyttes kun gennem kontrollen af ledige tider.bookings:readbookings:writesince
  • GET /api/public/v1/bookings
  • GET /api/public/v1/bookings/{id}
  • POST /api/public/v1/bookings
  • PATCH /api/public/v1/bookings/{id}
  • POST /api/public/v1/bookings/{id}/reschedule
  • GET /api/public/v1/availability
FeltType
acuteboolean
cancelled_atstring (date-time) · null
cancelled_bystring · null
chair_idstring (uuid) · null
clinic_idstring (uuid) · null
created_atstring (date-time)
ends_atstring (date-time)
idstring (uuid)
lead_staff_idstring (uuid) · null
localestring
marker_idstring (uuid) · null
morning_reminder_sent_atstring (date-time) · null
nervousboolean
notestring · null
patient_emailstring
patient_idstring (uuid) · null
patient_namestring
patient_phonestring
patient_typestring
referral_codestring · null
reminder_sent_atstring (date-time) · null
sourcestring
starts_atstring (date-time)
statusstring: confirmed | attended | no_show | cancelled
updated_atstring (date-time)
servicesYdelser med varighed og pris.services:readservices:writesince
  • GET /api/public/v1/services
  • GET /api/public/v1/services/{id}
  • POST /api/public/v1/services
  • PATCH /api/public/v1/services/{id}
FeltType
activeboolean
allowed_chair_idsarray · null
buffer_afternumber
calendar_colorstring
clinic_idstring (uuid) · null
created_atstring (date-time)
descriptionstring · null
duration_existingnumber
duration_newnumber
expected_price_dkknumber · null
idstring (uuid)
namestring
onlineboolean
price_fromstring · null
sort_ordernumber
translationsjson
updated_atstring (date-time)
staffBehandlere og assistenter.staff:readstaff:writesince
  • GET /api/public/v1/staff
  • GET /api/public/v1/staff/{id}
  • POST /api/public/v1/staff
  • PATCH /api/public/v1/staff/{id}
FeltType
activeboolean
authorization_idstring (uuid) · null
bookable_onlineboolean
clinic_idstring (uuid) · null
created_atstring (date-time)
idstring (uuid)
namestring
rolestring: dentist | hygienist | assistant
sort_ordernumber
titlestring · null
updated_atstring (date-time)
user_idstring (uuid) · null
chairsStole og behandlingsrum.chairs:readchairs:writesince
  • GET /api/public/v1/chairs
  • GET /api/public/v1/chairs/{id}
  • POST /api/public/v1/chairs
  • PATCH /api/public/v1/chairs/{id}
FeltType
activeboolean
clinic_idstring (uuid) · null
created_atstring (date-time)
idstring (uuid)
namestring
sort_ordernumber
updated_atstring (date-time)
recallsIndkaldelser pr. patient.recalls:readrecalls:writesince
  • GET /api/public/v1/recalls
  • GET /api/public/v1/recalls/{id}
  • POST /api/public/v1/recalls
  • PATCH /api/public/v1/recalls/{id}
FeltType
clinic_idstring (uuid) · null
created_atstring (date-time)
idstring (uuid)
interval_monthsnumber
last_action_atstring (date-time) · null
last_booking_idstring (uuid) · null
localestring
modestring
next_due_datestring (date)
patient_emailstring
patient_namestring
patient_phonestring
preferred_staff_idstring (uuid) · null
service_idstring (uuid)
stagestring
statusstring
updated_atstring (date-time)
waitlistPatienter på venteliste til en tidligere tid.waitlist:readsince
  • GET /api/public/v1/waitlist
  • GET /api/public/v1/waitlist/{id}
FeltType
booking_idstring (uuid)
clinic_idstring (uuid) · null
created_atstring (date-time)
earlier_slot_atstring (date-time) · null
idstring (uuid)
notified_atstring (date-time) · null
statusstring
updated_atstring (date-time)
callback-requestsØnsker om at blive ringet op fra bookingsiden.callback-requests:readcallback-requests:writesince
  • GET /api/public/v1/callback-requests
  • GET /api/public/v1/callback-requests/{id}
  • PATCH /api/public/v1/callback-requests/{id}
FeltType
clinic_idstring (uuid) · null
created_atstring (date-time)
handled_atstring (date-time) · null
idstring (uuid)
localestring
namestring
nervousboolean
pagestring · null
phonestring
preferred_timestring
statusstring
updated_atstring (date-time)
booking-itemsYdelser på en booking med prisen fra bookingtidspunktet.booking-items:read
  • GET /api/public/v1/booking-items
  • GET /api/public/v1/booking-items/{id}
FeltType
booking_idstring (uuid)
campaign_idstring (uuid) · null
clinic_idstring (uuid) · null
duration_minutesnumber
idstring (uuid)
positionnumber
price_dkknumber · null
service_idstring (uuid) · null
service_namestring

Journal

journal-notesJournalnotater. Rettelser bliver et nyt notat – intet overskrives.journal-notes:readjournal-notes:writesince
  • GET /api/public/v1/journal-notes
  • GET /api/public/v1/journal-notes/{id}
  • POST /api/public/v1/journal-notes
FeltType
author_emailstring
bodystring
booking_idstring (uuid) · null
clinic_idstring (uuid) · null
correction_reasonstring · null
created_atstring (date-time)
created_bystring · null
entry_datestring (date)
idstring (uuid)
import_keystring · null
imported_authorstring · null
imported_sourcestring · null
patient_idstring (uuid)
plan_idstring (uuid) · null
sectionsjson
supersedes_idstring (uuid) · null
teetharray
templatestring
titlestring
treatment-plansBehandlingsplaner og deres status.treatment-plans:readtreatment-plans:writesince
  • GET /api/public/v1/treatment-plans
  • GET /api/public/v1/treatment-plans/{id}
  • POST /api/public/v1/treatment-plans
  • PATCH /api/public/v1/treatment-plans/{id}
FeltType
accepted_atstring (date-time) · null
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
idstring (uuid)
notestring · null
patient_idstring (uuid)
statusstring
titlestring
updated_atstring (date-time)
treatment-plan-itemsLinjer i en behandlingsplan.treatment-plan-items:readsince
  • GET /api/public/v1/treatment-plan-items
  • GET /api/public/v1/treatment-plan-items/{id}
FeltType
clinic_idstring (uuid) · null
created_atstring (date-time)
descriptionstring
finding_idstring (uuid) · null
idstring (uuid)
option_groupstring · null
plan_idstring (uuid)
positionnumber
price_dkknumber
service_idstring (uuid) · null
statusstring
subsidy_dkknumber
toothnumber · null
updated_atstring (date-time)
tooth-findingsFund på tandkortet pr. tand og flade.tooth-findings:readsince
  • GET /api/public/v1/tooth-findings
  • GET /api/public/v1/tooth-findings/{id}
FeltType
author_emailstring
clinic_idstring (uuid) · null
codestring
created_bystring · null
done_atstring (date-time) · null
idstring (uuid)
notestring · null
patient_idstring (uuid)
recorded_atstring (date-time)
removed_atstring (date-time) · null
removed_reasonstring · null
statusstring
surfacesarray
toothnumber
updated_atstring (date-time)
perio-chartsPochemålinger (seks punkter pr. tand, blødning, mobilitet).perio-charts:readsince
  • GET /api/public/v1/perio-charts
  • GET /api/public/v1/perio-charts/{id}
FeltType
author_emailstring
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
datajson
idstring (uuid)
patient_idstring (uuid)
imagesOplysninger om røntgen og billeder. Selve filerne hentes ikke via API'et.images:readsince
  • GET /api/public/v1/images
  • GET /api/public/v1/images/{id}
FeltType
author_emailstring
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
idstring (uuid)
kindstring
notestring · null
patient_idstring (uuid)
storage_pathstring
taken_atstring (date-time)
toothnumber · null
updated_atstring (date-time)

Økonomi

chargesYdelser sat på patienten med pris, tilskud og tredjepartsandel.charges:readcharges:writesince
  • GET /api/public/v1/charges
  • GET /api/public/v1/charges/{id}
  • POST /api/public/v1/charges
FeltType
booking_idstring (uuid) · null
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
descriptionstring
idstring (uuid)
patient_idstring (uuid)
performed_onstring (date)
plan_item_idstring (uuid) · null
price_dkknumber
service_idstring (uuid) · null
staff_idstring (uuid) · null
statusstring
subsidy_dkknumber
third_party_dkknumber
third_party_invoice_idstring (uuid) · null
third_party_payerstring · null
third_party_refstring · null
third_party_statusstring
toothnumber · null
updated_atstring (date-time)
void_reasonstring · null
voided_atstring (date-time) · null
paymentsBetalinger registreret ved skranken.payments:readsince
  • GET /api/public/v1/payments
  • GET /api/public/v1/payments/{id}
FeltType
amount_dkknumber
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
idstring (uuid)
methodstring
notestring · null
patient_idstring (uuid)
reverse_reasonstring · null
reversed_atstring (date-time) · null
reversed_bystring · null
updated_atstring (date-time)
payment-allocationsHvilke ydelser hver betaling dækker.payment-allocations:read
  • GET /api/public/v1/payment-allocations
  • GET /api/public/v1/payment-allocations/{id}
FeltType
amount_dkknumber
charge_idstring (uuid)
clinic_idstring (uuid) · null
idstring (uuid)
payment_idstring (uuid)
invoicesFakturaer og kreditnotaer med fortløbende numre. Kan ikke ændres.invoices:readsince
  • GET /api/public/v1/invoices
  • GET /api/public/v1/invoices/{id}
FeltType
buyerjson
clinic_idstring (uuid)
created_atstring (date-time)
created_bystring · null
credits_invoice_idstring (uuid) · null
currencystring
due_onstring (date) · null
idstring (uuid)
issued_onstring (date)
kindstring
linesjson
numbernumber
payerstring
reasonstring · null
sellerjson
total_minornumber

HR

time-entriesRegistreret arbejdstid.time-entries:readsince
  • GET /api/public/v1/time-entries
  • GET /api/public/v1/time-entries/{id}
FeltType
break_minutesnumber
break_paidboolean
clinic_idstring (uuid) · null
compstring
created_atstring (date-time)
created_bystring · null
end_atstring (date-time) · null
idstring (uuid)
notestring · null
sourcestring
staff_idstring (uuid)
start_atstring (date-time)
statusstring
updated_atstring (date-time)
work_datestring (date)
absencesFerie, sygdom og andet fravær.absences:readsince
  • GET /api/public/v1/absences
  • GET /api/public/v1/absences/{id}
FeltType
block_idstring (uuid) · null
clinic_idstring (uuid) · null
created_atstring (date-time)
created_bystring · null
decided_atstring (date-time) · null
decided_bystring · null
from_datestring (date)
hoursnumber · null
idstring (uuid)
kindstring
notestring · null
staff_idstring (uuid)
statusstring
swornboolean
to_datestring (date)
updated_atstring (date-time)

Klinik

clinicNøglens egen klinik: navn, adresse, land, valuta og tidszone.clinic:read
  • GET /api/public/v1/clinic
FeltType
activeboolean
addressstring · null
bank_accountstring · null
bank_regstring · null
citystring · null
countrystring
created_atstring (date-time)
currencystring
cvrstring · null
default_localestring
emailstring · null
glnstring · null
ibanstring · null
idstring (uuid)
invoice_payment_daysnumber
is_demoboolean
log_retention_yearsnumber
namestring
org_idstring (uuid)
phonestring · null
postal_codestring · null
privacy_urlstring · null
privacy_urlsjson
provider_numberstring · null
slugstring · null
timezonestring
updated_atstring (date-time)

Eksport af alt

Ét kald streamer alle data, nøglen må læse, som NDJSON – side for side, så intet bliver skåret af. Brug det til backup, datavarehus eller flytning til et andet system.

GET /api/public/v1/export
curl -N $HUBHUS/api/public/v1/export \
  -H "Authorization: Bearer $TOKEN" > clinic.ndjson

# one JSON object per line:
# {"type":"meta",…} {"type":"record","resource":"patients","data":{…}} …
# {"type":"summary","resource":"patients","count":1234} … {"type":"end","count":56789}
# no "end" line = interrupted → run again

Webhooks

Få besked med det samme, når en booking ændrer sig. Beskeden indeholder kun bookingens id, status, tider og kilde – aldrig patientdata. Den er signeret med HMAC-SHA256 og forsøges igen ved fejl.

  • booking.created
  • booking.cancelled
  • booking.rescheduled
  • booking.attended
  • booking.no_show
Bekræft signaturen (Node.js)
import { createHmac, timingSafeEqual } from "node:crypto";

// raw = the request body exactly as received (before JSON.parse)
export function verify(raw: string, header: string, secret: string) {
  const expected = "sha256=" + createHmac("sha256", secret).update(raw).digest("hex");
  return header.length === expected.length &&
    timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
// Then use body.delivery (= X-Hubhus-Delivery) to ignore repeats.

Fejlkoder

Fejl returneres som JSON: { "error": "…" }

400
Forkert forespørgsel, felt eller henvisning til en anden kliniks data
401
Nøglen mangler, er ukendt, udløbet eller trukket tilbage
403
Nøglen mangler rettigheden, IP-adressen er ikke tilladt, eller klinikken er skrivebeskyttet
404
Findes ikke i nøglens klinik
409
Tiden er optaget, eller CPR-nummeret findes allerede
429
For mange kald – vent det antal sekunder, Retry-After angiver

Når en gratis prøveperiode er slut, bliver klinikken skrivebeskyttet: læsning og eksport virker fortsat, skrivning giver 403.

Hent den fulde OpenAPI-beskrivelse

Prøv Hubhus Dentist i jeres egen klinik

30 dage gratis med alle funktioner. Intet betalingskort, og jeres data kan altid eksporteres.

Opret gratis prøvekonto