Skip to main content
The Zenoti integration provides a complete TypeScript client for syncing spa and wellness center data from Zenoti’s REST API into the Etienne Intelligence Platform (EIP).

Architecture

The integration consists of five core modules:
  1. HTTP Client (client.ts) — Authentication, request handling, retries, and rate-limiting
  2. API Endpoints (endpoints.ts) — Type-safe methods for all Zenoti REST endpoints
  3. Data Mappers (mappers.ts) — Transform Zenoti response types into EIP domain models
  4. React Query Hooks (hooks.ts) — Cached data fetching with automatic fallback to seed data
  5. TypeScript Types (types.ts) — Complete type definitions for all Zenoti API responses

Key Features

  • Automatic token management — Bearer tokens are cached and refreshed at 90% of their 24-hour lifetime
  • Exponential backoff — Automatic retry on 429 rate-limit and 5xx errors with configurable delays
  • Type safety — Full TypeScript coverage for requests, responses, and domain mappings
  • Demo mode fallback — Seamlessly switches between live Zenoti data and seed data based on connection state
  • Multi-center support — Aggregate data across all locations or filter by specific center ID

Quick Start

import { 
  listCenters, 
  listAppointments, 
  mapAppointments 
} from '@/integrations/zenoti'

// Fetch and transform appointments
const raw = await listAppointments({
  centerId: 'abc123',
  startDate: '2026-03-01',
  endDate: '2026-03-31',
})

const appointments = mapAppointments(raw)

Configuration

The integration reads configuration from Vite environment variables:
VITE_ZENOTI_BASE_URL
string
default:"https://api.zenoti.com"
Base URL for the Zenoti API. Varies by data center:
  • US: https://api.zenoti.com
  • EU: https://api-eu.zenoti.com
  • AU: https://api-au.zenoti.com
VITE_ZENOTI_API_KEY
string
Long-lived API key for server-to-server authentication. Valid for ~1 year. Preferred method for production use.
VITE_ZENOTI_APP_ID
string
Application ID from Zenoti Admin > Setup > Apps. Required for bearer token authentication.
VITE_ZENOTI_SECRET_KEY
string
Secret key generated alongside the Application ID. Required for bearer token authentication.
VITE_ZENOTI_ACCOUNT_NAME
string
Organization/account name in Zenoti. Required for bearer token authentication.

Authentication Methods

Zenoti supports two authentication methods: Long-lived key for server-to-server calls. Set VITE_ZENOTI_API_KEY and the client will use it automatically.

Bearer Token

Generated dynamically from Application ID + Secret Key. The client caches tokens and refreshes them at 90% of their 24-hour lifetime.

Error Handling

All API methods throw typed errors:
  • ZenotiApiError — HTTP errors (4xx, 5xx) with status code and response body
  • ZenotiAuthError — Authentication failures during token generation
See Error Handling for complete reference.

Data Flow

  1. Fetchendpoints.ts methods call Zenoti REST API via zenotiRequest()
  2. Mapmappers.ts functions transform Zenoti types into EIP domain models
  3. Cache — React Query hooks provide cached, auto-refreshing data with seed fallback
  4. Render — Dashboard components consume EIP-typed data uniformly

API Coverage

Zenoti ResourceEndpoint MethodEIP TypeMapper
CenterslistCenters()LocationmapCenter()
ServiceslistServices()ServicemapService()
GuestssearchGuests()ClientmapGuest()
AppointmentslistAppointments()AppointmentmapAppointment()
InvoicesgetInvoice()
CollectionslistCollections()DailyMetricsmapCollection()
Sales ReportsgetSalesReport()DailyMetricsmapSalesReport()
EmployeeslistEmployees()

Next Steps

HTTP Client

Authentication, retries, and rate-limiting

API Endpoints

All available endpoint methods

Data Mappers

Zenoti to EIP type transformations

React Hooks

Query hooks with caching and fallback

Build docs developers (and LLMs) love