@lumbu/client
v0.3.1
Published
TypeScript SDK for the [Lumbu](https://lumbu.pt) salon management API.
Readme
@lumbu/client
TypeScript SDK for the Lumbu salon management API.
Install
npm install @lumbu/clientQuick Start
import { createLumbuClient } from "@lumbu/client";
const client = createLumbuClient({
baseUrl: "https://api.lumbu.pt",
token: "lmb_your_api_key",
});
// Check available slots
const slots = await client.booking.getSlots({
service_id: "svc-1",
from: "2026-04-15",
days: 7,
});
// Book an appointment
const result = await client.booking.book({
service_id: "svc-1",
staff_id: "staff-1",
start_at: "2026-04-15T10:00:00Z",
customer_name: "Maria Silva",
customer_email: "[email protected]",
});Core Features
Every client instance includes these endpoints -- no configuration needed:
| Endpoint | Description |
|---|---|
| client.booking | Slot availability, create/cancel/reschedule bookings |
| client.appointments | List and filter appointments |
| client.services | Service catalog |
| client.serviceCategories | Service categories with nested services |
| client.staff | Staff member listing |
| client.staffHours | Working hours per staff/day |
| client.staffAvailability | Availability blocks for date ranges |
| client.staffTimeOff | Time-off entries |
| client.teamMembers | Team membership |
| client.checkout | Stripe checkout session creation |
| client.orders | Order lookup |
| client.customer | Customer appointment history |
| client.locations | Location listing |
| client.tenant | Tenant metadata, branding, locale |
| client.auth | Sign-in, sign-up, magic link, token refresh |
| client.onboarding | Setup validation helpers |
Plugins
Optional features are enabled per tenant via the plugins config:
const client = createLumbuClient({
baseUrl: "https://api.lumbu.pt",
token: "lmb_your_api_key",
plugins: ["gift-cards", "products"],
});
// These are now available:
await client.giftCards.validate({ code: "GIFT-ABC" });
await client.products.list({ active: true });
// This would be a TypeScript error:
// client.waitlist <-- property does not existAvailable Plugins
| Plugin | Endpoints | Description |
|---|---|---|
| gift-cards | client.giftCards | Validate and apply gift cards |
| referral | client.referral | Validate referral codes |
| waitlist | client.waitlist | Waitlist management |
| products | client.products, client.productCategories | Product catalog and categories |
| feedback | client.appointmentFeedback | Post-appointment ratings |
| webhooks | client.webhooks | Webhook subscription management |
Auto-Discover Plugins
If you don't know which plugins the tenant has enabled, use the async factory:
import { createLumbuClientAsync } from "@lumbu/client";
const client = await createLumbuClientAsync({
baseUrl: "https://api.lumbu.pt",
token: "lmb_your_api_key",
});
// Plugin properties may be undefined -- narrow before use
if (client.giftCards) {
await client.giftCards.validate({ code: "GIFT-ABC" });
}This fetches the tenant's enabled_plugins from the API and builds the client accordingly.
Onboarding
Verify a tenant is properly set up for salon operations:
const status = await client.onboarding.checkSetup();
if (!status.ready) {
for (const [name, check] of Object.entries(status.checks)) {
if (!check.ok) {
console.log(`${name}: ${check.message}`);
}
}
}The checkSetup() method validates 10 aspects of tenant configuration:
| Check | Passes when |
|---|---|
| services | At least 1 active, bookable service |
| staff | At least 1 active staff member |
| staffHours | Staff working hours configured |
| staffServiceMapping | Staff linked to services |
| locations | At least 1 active location |
| businessHours | Business hours set (not all closed) |
| payments | Stripe connected |
| branding | Logo and brand colors set |
| locale | Language configuration present |
| notificationTemplates | Booking email templates ready |
Pagination
List endpoints return paginated responses. Use listAll() to iterate through all pages:
for await (const page of client.appointments.listAll({ status: "confirmed" })) {
for (const appointment of page.data) {
console.log(appointment.id, appointment.start_at);
}
}Error Handling
import { LumbuApiError } from "@lumbu/client";
try {
await client.booking.book(params);
} catch (err) {
if (err instanceof LumbuApiError) {
if (err.isConflict) console.log("Slot already taken");
if (err.isUnauthorized) console.log("Invalid API key");
if (err.isRateLimited) console.log("Too many requests");
}
}Custom Fetch
Pass a custom fetch implementation for edge runtimes or testing:
const client = createLumbuClient({
baseUrl: "https://api.lumbu.pt",
token: "lmb_key",
fetch: myCustomFetch,
});Multilingual Support
Lumbu supports PT, EN, and ES. The tenant's locale configuration is available via:
const tenant = await client.tenant.get();
console.log(tenant.locale.default); // "pt"
console.log(tenant.locale.supported); // ["pt", "en", "es"]