npm.io
0.1.0-beta.2 • Published 10h ago

@schedule-x-cloud/sdk

Licence
MIT
Version
0.1.0-beta.2
Deps
0
Size
136 kB
Vulns
0
Weekly
0

Schedule-X Cloud SDK

TypeScript client and Schedule-X calendar preset for Schedule-X Cloud.

The SDK defaults to the hosted Schedule-X Cloud API at https://cloud.schedule-x.com and stays close to the HTTP API:

  • Backend code maps authenticated app users and issues short-lived frontend sessions.
  • Browser code supplies one async frontend-token function to a Cloud calendar factory.
  • The Cloud calendar loads visible-range events and persists changes automatically.
  • The calendar preset wires the loaded config into Schedule-X Calendar with default views, recurrence, and the interactive event modal.

Hosted frontend-token routes support direct cross-origin browser requests without cookies. Before starting Google authorization, register the application's OAuth return origin for the selected environment in the Cloud console.

Install

Server-only integrations can install the SDK and import its UI-free entry point:

npm install @schedule-x-cloud/sdk temporal-polyfill
import { ScheduleXServerClient } from '@schedule-x-cloud/sdk/server'

For the calendar integration, install the Schedule-X peer packages too. Configure your @sx-premium registry token before running this command:

npm install @schedule-x-cloud/sdk temporal-polyfill @schedule-x/calendar @schedule-x/calendar-controls @schedule-x/event-recurrence @schedule-x/theme-default @schedule-x/translations @sx-premium/interactive-event-modal @sx-premium/sidebar

Auth Flow

Customer integrations use two token types:

  • Organization API token: secret owned by one organization, used only on your server.
  • Frontend token: short-lived bearer token for one organization user, used by the browser.

The normal implementer flow is:

  1. Your backend stores the organization API token as a server-side secret.
  2. Your backend creates or maps a Cloud user for your signed-in app user.
  3. Your backend exchanges the organization API token and Cloud user id for a frontend token.
  4. Your frontend uses the frontend token with ScheduleXBrowserClient.

Never expose an organization API token to browser code.

Server-Side Session Bootstrap

import { ScheduleXServerClient } from '@schedule-x-cloud/sdk/server'

const serverClient = new ScheduleXServerClient({
  apiKey: process.env.SCHEDULE_X_ORG_API_TOKEN,
  organizationId: process.env.SCHEDULE_X_ORGANIZATION_ID,
})

export async function createScheduleXFrontendSession(appUser) {
  return serverClient.auth.createFrontendSession({
    externalUserId: appUser.id,
    email: appUser.email,
    displayName: appUser.name,
  })
}

The operation idempotently creates or updates the organization-scoped external-user mapping and returns a fresh one-hour frontend token. Call it only from an authenticated backend route.

Cloud Calendar

import 'temporal-polyfill/global'
import '@schedule-x/theme-default/dist/index.css'
import '@sx-premium/interactive-event-modal/index.css'

import { createScheduleXCloudCalendar } from '@schedule-x-cloud/sdk'

const calendarApp = createScheduleXCloudCalendar({
  getFrontendToken: async () => {
    const response = await fetch('/api/schedule-x/token', { method: 'POST' })
    return (await response.json()).token
  },
})

The factory returns a normal CalendarApp synchronously. It shows a loading overlay until the first visible range is available, retains loaded events during later range refreshes, wires event CRUD, caches the token, and requests a fresh token after a 401 before retrying once.

The app exposes its framework-neutral Cloud lifecycle at calendarApp.scheduleXCloud. Subscribe when your application needs its own UI:

const unsubscribe = calendarApp.scheduleXCloud.subscribe((state) => {
  console.log(state.phase, state.providerSync.pendingCalendarCount)
})

await calendarApp.scheduleXCloud.retry()
unsubscribe()

Phases are loading, partial, ready, refreshing, and error. hasLoadedData distinguishes a blocking initial error from a non-blocking refresh or provider error. Set loadingUI: false to keep the lifecycle without the built-in UI, or pass loadingUI.render to render into the SDK-owned status container. The renderer may return a cleanup function.

The hosted API URL is used automatically. Pass baseUrl only when targeting another deployment:

const serverClient = new ScheduleXServerClient({
  apiKey: process.env.SCHEDULE_X_ORG_API_TOKEN,
  baseUrl: 'https://calendar-api.example.com',
})

Browser Config

import 'temporal-polyfill/global'
import { ScheduleXBrowserClient } from '@schedule-x-cloud/sdk'

const client = new ScheduleXBrowserClient({
  token: frontendToken.token,
})

const config = await client.scheduleX.getCalendarAppConfig({
  from: Temporal.ZonedDateTime.from('2026-05-01T00:00:00+00:00[UTC]'),
  to: Temporal.ZonedDateTime.from('2026-06-01T00:00:00+00:00[UTC]'),
})

Browser clients do not need an organization id for the default config and event endpoints. The API resolves the organization and user from the frontend token.

Public SDK date-time values use Temporal objects. Timed events use Temporal.ZonedDateTime, all-day events use Temporal.PlainDate, and absolute metadata timestamps use Temporal.Instant. The raw HTTP API uses ISO strings; the SDK handles that transport conversion.

Google Calendar Sync

After a user connects Google Calendar through getConnectUrl, let the Cloud calendar enable every visible provider calendar and own the initial import:

const calendarApp = createScheduleXCloudCalendar({
  getFrontendToken,
  initialProviderSync: true,
})

initialProviderSync is opt-in because it enables all visible provider calendars. The initial config is displayed as partial data while imports run. If the normal sync wait times out, the lifecycle remains partial and continues polling until each calendar is synced or failed. One failed provider calendar is reported as a non-blocking error and does not prevent the loaded calendars from rendering.

listProviderCalendars() returns calendars from all active Google account connections for the frontend token user. Each item includes connectionId and providerEmail if you need to show which Google account it came from. For selective sync, keep using the lower-level APIs.

Calendar Preset

import 'temporal-polyfill/global'
import '@schedule-x/theme-default/dist/index.css'
import '@sx-premium/interactive-event-modal/index.css'

import { createCalendar } from '@schedule-x/calendar'
import {
  ScheduleXBrowserClient,
  loadScheduleXCloudCalendarPreset,
} from '@schedule-x-cloud/sdk'

const client = new ScheduleXBrowserClient({
  token: frontendToken.token,
})

const preset = await loadScheduleXCloudCalendarPreset({
  client,
  configQuery: {
    from: Temporal.ZonedDateTime.from('2026-05-01T00:00:00+00:00[UTC]'),
    to: Temporal.ZonedDateTime.from('2026-06-01T00:00:00+00:00[UTC]'),
  },
})

const calendarApp = createCalendar(preset.calendarOptions)

The preset creates the default day, week, month grid, and month agenda views. It also wires browser create, update, and delete calls for events. You can override calendar options, modal fields, plugins, persistence checks, and event mapping through createScheduleXCloudCalendarPreset or loadScheduleXCloudCalendarPreset.

Event Persistence

await client.events.create({
  calendarId,
  end: Temporal.ZonedDateTime.from(
    '2026-05-14T11:00:00+02:00[Europe/Berlin]'
  ),
  isPrivate: false,
  start: Temporal.ZonedDateTime.from(
    '2026-05-14T10:00:00+02:00[Europe/Berlin]'
  ),
  title: 'New event',
})

await client.events.update(eventId, {
  calendarId,
  end: Temporal.ZonedDateTime.from(
    '2026-05-14T12:00:00+02:00[Europe/Berlin]'
  ),
  isPrivate: false,
  start: Temporal.ZonedDateTime.from(
    '2026-05-14T10:00:00+02:00[Europe/Berlin]'
  ),
  title: 'Updated event',
})

await client.events.delete(eventId)

Both values in an event range must use the same Temporal type. Timed ranges must also use the same timezone; the SDK derives timeZone and isAllDay for the HTTP request.

Errors

Failed API responses throw ScheduleXApiError.

import { ScheduleXApiError } from '@schedule-x-cloud/sdk'

try {
  await client.events.create(request)
} catch (error) {
  if (error instanceof ScheduleXApiError) {
    console.error(error.status, error.responseBody)
  }
}

Package Status

The beta publish target is npm package @schedule-x-cloud/sdk, with public access and version 0.1.0-beta.0.

Keywords