TypeScript SDK for Acuity Scheduling API
npm install acuity-js-sdk
A comprehensive TypeScript SDK for the Acuity Scheduling API.
- Full TypeScript support - Comprehensive type definitions for all API entities
- Universal runtime - Works in Node.js 18+, browsers, and edge runtimes (Cloudflare Workers, Vercel Edge, etc.)
- Zero dependencies - Uses native fetch API
- Dual format - Ships both ESM and CommonJS builds
- Multiple auth methods - Supports both Basic Auth and OAuth2
- Complete API coverage - All Acuity Scheduling API endpoints
``bash`
bun add acuity-js-sdk
`bash`
npm install acuity-js-sdk
`bash`
pnpm add acuity-js-sdk
`typescript
import { AcuityClient } from 'acuity-js-sdk';
const client = new AcuityClient({
auth: {
userId: 'your-user-id',
apiKey: 'your-api-key',
},
});
// List all appointments
const appointments = await client.appointments.list();
`
`typescript
import { AcuityClient } from 'acuity-js-sdk';
const client = new AcuityClient({
auth: {
accessToken: 'your-oauth-access-token',
},
});
`
`typescript
// List appointments with filters
const appointments = await client.appointments.list({
minDate: '2024-01-01',
maxDate: '2024-01-31',
calendarID: 123,
});
// Get a single appointment
const appointment = await client.appointments.get(12345);
// Create an appointment
const newAppointment = await client.appointments.create({
appointmentTypeID: 123,
datetime: '2024-01-15T10:00:00-0500',
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
phone: '555-123-4567',
});
// Update an appointment
const updated = await client.appointments.update(12345, {
notes: 'Updated notes',
});
// Reschedule an appointment
const rescheduled = await client.appointments.reschedule(12345, {
datetime: '2024-01-16T14:00:00-0500',
});
// Cancel an appointment
const canceled = await client.appointments.cancel(12345, {
cancelNote: 'Customer requested cancellation',
});
`
`typescript
// Get available dates for a month
const dates = await client.availability.getDates({
appointmentTypeID: 123,
month: '2024-01',
calendarID: 456, // optional
timezone: 'America/New_York', // optional
});
// Get available times for a specific date
const times = await client.availability.getTimes({
appointmentTypeID: 123,
date: '2024-01-15',
timezone: 'America/New_York',
});
// Get available classes
const classes = await client.availability.getClasses({
appointmentTypeID: 123,
month: '2024-01',
});
`
`typescript
// List clients
const clients = await client.clients.list({
search: 'john',
});
// Get a client
const clientDetails = await client.clients.get(12345);
// Create a client
const newClient = await client.clients.create({
firstName: 'Jane',
lastName: 'Smith',
email: 'jane@example.com',
phone: '555-987-6543',
});
// Update a client
const updatedClient = await client.clients.update(12345, {
notes: 'VIP customer',
});
`
`typescript
// List all appointment types
const types = await client.appointmentTypes.list();
// Get a specific appointment type
const type = await client.appointmentTypes.get(123);
// List addons for an appointment type
const addons = await client.appointmentTypes.listAddons(123);
`
`typescript
// List all calendars
const calendars = await client.calendars.list();
// Get a specific calendar
const calendar = await client.calendars.get(123);
`
`typescript
// List certificates
const certificates = await client.certificates.list({
email: 'customer@example.com',
});
// Check a certificate code
const certificate = await client.certificates.check('ABC123', 456);
// Create a certificate
const newCert = await client.certificates.create({
email: 'customer@example.com',
productID: 789,
});
`
`typescript
// List labels
const labels = await client.labels.list();
// Create a label
const newLabel = await client.labels.create({
name: 'VIP',
color: '#FF0000',
});
`
`typescript
// List blocks
const blocks = await client.blocks.list({
calendarID: 123,
minDate: '2024-01-01',
maxDate: '2024-01-31',
});
// Create a block
const newBlock = await client.blocks.create({
calendarID: 123,
start: '2024-01-15T09:00:00-0500',
end: '2024-01-15T12:00:00-0500',
notes: 'Morning off',
});
`
`typescript
// List webhooks
const webhooks = await client.webhooks.list();
// Create a webhook
const webhook = await client.webhooks.create({
event: 'appointment.scheduled',
target: 'https://your-server.com/webhooks/acuity',
});
// Delete a webhook
await client.webhooks.delete(123);
`
The SDK provides typed error classes for different error scenarios:
`typescript
import {
AcuityClient,
AcuityError,
AuthenticationError,
RateLimitError,
NotFoundError,
ValidationError,
} from 'acuity-js-sdk';
try {
const appointment = await client.appointments.get(99999);
} catch (error) {
if (error instanceof NotFoundError) {
console.log('Appointment not found');
} else if (error instanceof AuthenticationError) {
console.log('Invalid credentials');
} else if (error instanceof RateLimitError) {
console.log(Rate limited. Retry after ${error.retryAfter} seconds);API error: ${error.message} (${error.statusCode})
} else if (error instanceof ValidationError) {
console.log('Validation failed:', error.message);
} else if (error instanceof AcuityError) {
console.log();`
}
}
| Error Class | Status Code | Description |
|------------|-------------|-------------|
| AuthenticationError | 401 | Invalid or missing credentials |AuthorizationError
| | 403 | Insufficient permissions |NotFoundError
| | 404 | Resource not found |ValidationError
| | 400 | Invalid request parameters |RateLimitError
| | 429 | Rate limit exceeded |ServerError
| | 5xx | Server-side error |TimeoutError
| | - | Request timed out |NetworkError
| | - | Network connectivity issue |
`typescript`
const client = new AcuityClient({
auth: {
userId: 'your-user-id',
apiKey: 'your-api-key',
},
// Optional: Custom base URL (default: https://acuityscheduling.com/api/v1)
baseUrl: 'https://acuityscheduling.com/api/v1',
// Optional: Request timeout in milliseconds (default: 30000)
timeout: 60000,
});
| Resource | Description |
|----------|-------------|
| client.appointments | Manage appointments |client.appointmentTypes
| | Manage appointment types and addons |client.availability
| | Check available dates, times, and classes |client.calendars
| | Manage calendars |client.clients
| | Manage client records |client.forms
| | Access intake forms |client.certificates
| | Manage certificates/packages |client.products
| | Manage products and orders |client.labels
| | Manage appointment labels |client.blocks
| | Manage time blocks (time off) |client.webhooks
| | Manage webhooks |
All types are exported from the main package:
`typescript`
import type {
Appointment,
AppointmentType,
Calendar,
Client,
AvailableTime,
CreateAppointmentParams,
} from 'acuity-js-sdk';
`bashBuild the SDK
bun run build
$3
This project uses Vitest for testing:
- Unit tests - Test utilities, auth providers, and error classes
- Integration tests - Test HTTP client and resource classes with mocked fetch
`bash
bun run test # Run all tests
bun run test:watch # Run in watch mode
bun run test:coverage # Generate coverage report
`$3
This project uses Oxc for linting and formatting:
- oxlint - Fast linter (50-100x faster than ESLint)
- oxfmt - Prettier-compatible formatter
$3
This project uses Changesets for versioning and releases.
Adding a changeset (when making changes):
`bash
bun changeset
`Follow the prompts to select the version bump type:
- patch (0.0.X) - Bug fixes, documentation
- minor (0.X.0) - New features (backwards compatible)
- major (X.0.0) - Breaking changes
Release process:
1. Create PR with changes + changeset file
2. Merge to
main
3. CI creates a "Version Packages" PR
4. Merge the Version PR → automatically publishes to NPMRequirements
- Bun 1.0+ or Node.js 18+ (or any environment with native
fetch` support)MIT