JavaScript SDK

The official Otesse JavaScript SDK provides a type-safe client for the Otesse API with built-in error handling, pagination, and rate limit management.

Installation

npm install @otesse/sdk
# or
yarn add @otesse/sdk
# or
pnpm add @otesse/sdk

Initialization

import { OtesseClient } from '@otesse/sdk';

const otesse = new OtesseClient({
  apiKey: process.env.OTESSE_API_KEY!,
  // Optional configuration
  baseUrl: 'https://api.otesse.com/v1', // default
  timeout: 30000, // 30 seconds, default
  retries: 3, // auto-retry on 429 and 5xx, default
});

Customers

// List customers
const { data: customers, pagination } = await otesse.customers.list({
  status: 'active',
  search: 'john',
  page: 1,
  perPage: 25,
});

// Get a single customer
const customer = await otesse.customers.get('cust_01HQ3K5M7N');

// Create a customer
const newCustomer = await otesse.customers.create({
  firstName: 'Jane',
  lastName: 'Doe',
  email: 'jane@example.com',
  phone: '+15559876543',
  address: {
    label: 'Home',
    street: '456 Oak Ave',
    city: 'Springfield',
    state: 'OR',
    zip: '97477',
  },
});

// Update a customer
await otesse.customers.update('cust_01HQ3K5M7N', {
  phone: '+15551112222',
});

Bookings

// List bookings
const { data: bookings } = await otesse.bookings.list({
  status: 'confirmed',
  dateFrom: '2026-03-01',
  dateTo: '2026-03-31',
});

// Create a booking
const booking = await otesse.bookings.create({
  customerId: 'cust_01HQ3K5M7N',
  industry: 'cleaning',
  configuration: {
    bedrooms: 3,
    bathrooms: 2,
    frequency: 'one-time',
    extras: ['inside_oven'],
  },
  scheduledAt: new Date('2026-03-15T10:00:00Z'),
  addressId: 'addr_01HQ3K5M7N',
});

// Cancel a booking
await otesse.bookings.cancel('bk_01HQ3K5M7N8P9R', {
  reason: 'Customer requested',
});

Invoices

// List invoices
const { data: invoices } = await otesse.invoices.list({
  status: 'pending',
  customerId: 'cust_01HQ3K5M7N',
});

// Refund an invoice
await otesse.invoices.refund('inv_01HQ3K5M7N', {
  amount: 5000, // $50.00 in cents
  reason: 'Partial service credit',
});

Services

// List industries
const industries = await otesse.services.listIndustries();

// Get products for an industry
const products = await otesse.services.getProducts('cleaning');

// Check availability
const availability = await otesse.services.checkAvailability({
  zip: '97401',
  industry: 'cleaning',
  date: '2026-03-15',
});

// Calculate pricing
const pricing = await otesse.services.calculatePricing({
  industry: 'cleaning',
  zip: '97401',
  configuration: { bedrooms: 3, bathrooms: 2, frequency: 'bi-weekly' },
});

Error Handling

import { OtesseError, RateLimitError, NotFoundError } from '@otesse/sdk';

try {
  const booking = await otesse.bookings.get('bk_invalid');
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log('Booking not found');
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof OtesseError) {
    console.log(`API error: ${error.code} — ${error.message}`);
  }
}

Auto-Pagination

Iterate through all records automatically:

for await (const customer of otesse.customers.listAll({ status: 'active' })) {
  console.log(customer.email);
}

The SDK handles pagination automatically, fetching the next page when needed.