@broberg/complimenta-sdk
v0.2.0
Published
Typed SDK for the Complimenta (ComplimentaWork) booking API — read therapists/services/clinics/calendar-slots and create/cancel bookings. Generated from Complimenta's OpenAPI spec; OAuth2 client-credentials; runs in Next.js and Bun.
Readme
@broberg/complimenta-sdk
Typed SDK for the Complimenta (ComplimentaWork) booking system — read
therapists / services / clinics / calendar-slots and create + cancel bookings.
Types are generated from Complimenta's own OpenAPI spec, so the contract is
exact and complete. Zero runtime dependencies, native fetch → runs unchanged
in Next.js and Bun.
Built in the fdaa monorepo (packages/complimenta), published to npm as
@broberg/complimenta-sdk. One SDK, consumed across the FysioDanmark Aalborg
fleet: the fdaa platform, the future fdaa-sundhed repo, and the native apps.
Auth
OAuth2 client-credentials: the SDK exchanges clientId+clientSecret at the
auth host's /oauth2/token for a Bearer JWT (cached + auto-refreshed) and sends
it on every /api/v1/* call.
import { createComplimentaClient } from "@broberg/complimenta-sdk";
const cam = createComplimentaClient({
baseUrl: process.env.COMPLIMENTA_BASE_URL!, // scheme+host, no path
clientId: process.env.COMPLIMENTA_CLIENT_ID!,
clientSecret: process.env.COMPLIMENTA_CLIENT_SECRET!,
});
const therapists = await cam.listUsers(); // GET /api/v1/users
const services = await cam.listClinicServices(); // GET /api/v1/clinic-services
const slots = await cam.listUserCalendarSlots( // GET /api/v1/users/{userId}/calendar-slots
therapists.items[0].id,
{ endsOnOrAfter: "2026-06-16T08:00:00", endsBefore: "2026-06-23T17:00:00" }, // end-time window (required)
);
const bookings = await cam.listBookings({ // GET /api/v1/bookings
startsAtOrAfter: "2026-06-16T00:00:00", // from-date window (required, ≤ 3 months)
startsBefore: "2026-06-23T00:00:00",
});
// also: listClinics/getClinic · listPublicServices · getBooking ·
// createBooking(body) · cancelBooking(id)cam.request(method, path, { query, body }) is the typed escape hatch for any of
the ~40 endpoints not yet wrapped in a convenience method.
Types generated from the spec
The full contract lives in openapi/complimenta-external.json (vendored from
GET {host}/v3/api-docs/external). Regenerate the types whenever Complimenta
updates their API:
pnpm generate # openapi-typescript → src/schema.ts (paths · components · operations)src/schema.ts is generated — do not hand-edit. The convenience methods
derive their request/response types from it, so a spec change surfaces as a
type error at the call-site.
Smoke test (proves the live connection)
cp .env.example .env # COMPLIMENTA_BASE_URL + COMPLIMENTA_CLIENT_ID + COMPLIMENTA_CLIENT_SECRET
bun scripts/smoke.ts # token exchange + GET /calendar-slots