@onecal/unified-calendar-api-node-sdk
v1.0.0
Published
Official Node.js SDK for OneCal Unified Calendar API - A type-safe client for managing calendars, events, and integrations across Google, Microsoft, and other providers
Readme
OneCal Unified Calendar API - Node.js SDK
Official Node.js/TypeScript SDK for the OneCal Unified Calendar API. Manage calendars, events, and integrations across Google Calendar, Microsoft Outlook, and other providers with a single, unified interface.
Features
✨ Unified Interface - Work with multiple calendar providers through one consistent API
🔒 Type-Safe - Full TypeScript support with comprehensive type definitions
📦 Modern - ESM and CommonJS support
🚀 Simple - Intuitive, promise-based API
📚 Well-Documented - Extensive documentation and examples
🧪 Tested - Comprehensive test coverage
Installation
npm install @onecal/unified-calendar-api-node-sdkOr using yarn:
yarn add @onecal/unified-calendar-api-node-sdkOr using pnpm:
pnpm add @onecal/unified-calendar-api-node-sdkQuick Start
import { UnifiedCalendarApi } from '@onecal/unified-calendar-api-node-sdk';
// Initialize the client
const client = new UnifiedCalendarApi({
apiKey: 'your-api-key-here',
});
// List calendars
const calendars = await client.calendars.list('endUserAccountId');
// Create an event
const event = await client.events.create('endUserAccountId', 'calendarId', {
title: 'Team Meeting',
start: {
dateTime: '2026-01-20T10:00:00Z',
timeZone: 'UTC',
},
end: {
dateTime: '2026-01-20T11:00:00Z',
timeZone: 'UTC',
},
attendees: [{ email: '[email protected]', name: 'Team Member' }],
});
console.log(`Created event: ${event.title}`);Configuration
const client = new UnifiedCalendarApi({
apiKey: 'your-api-key', // Required: Your Unified Calendar API key
unifiedApiBaseUrl: 'https://api.onecalunified.com', // Optional: API base URL
timeout: 30000, // Optional: Request timeout in ms
debug: false, // Optional: Enable debug logging
});API Reference
End User Accounts
Manage end user accounts that connect to calendar providers.
// List all end user accounts
const accounts = await client.endUserAccounts.list({
limit: 20,
search: '[email protected]',
statusFilter: 'active',
});
// Get a specific account
const account = await client.endUserAccounts.get('accountId');
// Create a new account
const newAccount = await client.endUserAccounts.upsert({
email: '[email protected]',
refreshToken: 'refresh-token',
providerType: ProviderType.GOOGLE,
externalId: 'user-123',
});
// Get account credentials (automatically refreshes if expired)
const credentials = await client.endUserAccounts.getCredentials('accountId');
// Delete an account
await client.endUserAccounts.delete('accountId');Calendars
Manage calendars for end user accounts.
// List calendars
const calendars = await client.calendars.list('endUserAccountId', {
pageSize: 20,
});
// Get a specific calendar
const calendar = await client.calendars.get('endUserAccountId', 'calendarId');
// Create a calendar
const newCalendar = await client.calendars.create('endUserAccountId', {
name: 'My Calendar',
hexColor: '#FF5733',
timeZone: 'America/New_York',
});
// Update a calendar
const updated = await client.calendars.update(
'endUserAccountId',
'calendarId',
{
name: 'Updated Calendar Name',
}
);
// Delete a calendar
await client.calendars.delete('endUserAccountId', 'calendarId');Events
Create, read, update, and delete calendar events.
// List events
const events = await client.events.list('endUserAccountId', 'calendarId', {
startDateTime: new Date('2026-01-01'),
endDateTime: new Date('2026-12-31'),
search: 'meeting',
orderBy: EventOrderBy.START_TIME,
pageSize: 50,
});
// Get a specific event
const event = await client.events.get(
'endUserAccountId',
'calendarId',
'eventId'
);
// Create an event
const newEvent = await client.events.create('endUserAccountId', 'calendarId', {
title: 'Product Launch',
description: 'Launch event for new product',
start: {
dateTime: '2026-02-15T14:00:00Z',
timeZone: 'UTC',
},
end: {
dateTime: '2026-02-15T16:00:00Z',
timeZone: 'UTC',
},
location: '123 Main St, San Francisco, CA',
attendees: [
{ email: '[email protected]', name: 'Alice' },
{ email: '[email protected]', name: 'Bob' },
],
reminders: {
useDefault: false,
overrides: [
{ method: 'email', minutes: 24 * 60 }, // 1 day before
{ method: 'popup', minutes: 30 }, // 30 minutes before
],
},
});
// Update an event
const updated = await client.events.update(
'endUserAccountId',
'calendarId',
'eventId',
{
title: 'Updated Event Title',
location: 'New Location',
}
);
// Delete an event
await client.events.delete('endUserAccountId', 'calendarId', 'eventId');
// Get recurring event occurrences
const occurrences = await client.events.getOccurrences(
'endUserAccountId',
'calendarId',
'recurringEventId',
{
startDateTime: new Date('2026-01-01'),
endDateTime: new Date('2026-03-31'),
}
);
// RSVP to an event
await client.events.rsvp('endUserAccountId', 'calendarId', 'eventId', {
responseStatus: 'accepted',
});Free/Busy
Query free/busy availability across calendars.
const freeBusy = await client.freeBusy.get('endUserAccountId', {
startDateTime: new Date(),
endDateTime: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // Next 7 days
timeZone: 'America/New_York',
calendarIds: ['calendar1', 'calendar2'],
});
// Response is an array of FreeBusySlot objects
console.log('Free/Busy results:', freeBusy);
// Example: [{ calendarId: 'calendar1', busySlots: [{ start: {...}, end: {...} }] }]Calendar Subscriptions
Subscribe to calendar event notifications via webhooks.
// List subscriptions
const subscriptions =
await client.calendarSubscriptions.list('endUserAccountId');
// Create a subscription for calendar events
const subscription = await client.calendarSubscriptions.create(
'endUserAccountId',
{
webhookUrl: 'https://your-app.com/webhooks',
calendarId: 'calendarId',
subscriptionType: 'event', // 'event' for calendar events, 'calendar' for calendar changes
rateLimit: 100, // Optional: requests per second limit
}
);
// Returns: { webhookSubscriptionId: string, endpointSecret: string }
// Create a subscription for calendar list changes
const calendarSub = await client.calendarSubscriptions.create(
'endUserAccountId',
{
webhookUrl: 'https://your-app.com/webhooks/calendars',
subscriptionType: 'calendar',
}
);
// Delete a subscription
await client.calendarSubscriptions.delete('endUserAccountId', 'subscriptionId');OAuth
Generate OAuth authorization URLs for connecting user calendars.
import { getOAuthUrl } from '@onecal/unified-calendar-api-node-sdk/oauth';
// Get OAuth URL for Google
const googleUrl = getOAuthUrl('your-app-id', 'GOOGLE', {
redirectUrl: 'https://your-app.com/callback',
externalId: 'user-123',
loginHint: '[email protected]',
unifiedApiBaseUrl: 'https://api.onecalunified.com', // Optional: defaults to production
});
// Get OAuth URL for Microsoft
const microsoftUrl = getOAuthUrl('your-app-id', 'MICROSOFT', {
redirectUrl: 'https://your-app.com/callback',
externalId: 'user-456',
});
// Redirect user to the OAuth URL
// After authorization, they'll be redirected back to your redirectUrlError Handling
The SDK provides specific error types for different scenarios:
import {
UnifiedCalendarApiError,
APIRequestError,
AuthenticationError,
AuthorizationError,
NotFoundError,
RateLimitError,
} from '@onecal/unified-calendar-api-node-sdk';
try {
const event = await client.events.get('accountId', 'calendarId', 'eventId');
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof NotFoundError) {
console.error('Event not found');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
} else if (error instanceof APIRequestError) {
console.error(`API error: ${error.message} (${error.status})`);
} else {
console.error('Unexpected error:', error);
}
}TypeScript Support
This SDK is written in TypeScript and provides comprehensive type definitions:
import type {
Calendar,
Event,
EndUserAccount,
CreateEventInput,
ListEventsParams,
EventOrderBy,
ProviderType,
} from '@onecal/unified-calendar-api-node-sdk';Examples
See the examples/ directory for more usage examples:
quickstart.ts- Complete quick start guide
Development
# Install dependencies
npm install
# Build the SDK
npm run build
# Run tests
npm test
# Run linter
npm run lint
# Format code
npm run format
# Type check
npm run typecheck
# Watch mode (for development)
npm run devSupport
- 📧 Email: [email protected]
- 📚 Documentation: https://docs.onecalunified.com
