Skip to content

Core Workflows

These workflows are the building blocks most applications need after receiving an organization API token.

Default API base URL:

https://cloud.schedule-x.com

The SDK uses this URL automatically. Pass baseUrl only if you need to target another deployment.

Required backend environment:

Terminal window
SCHEDULE_X_ORGANIZATION_ID=<organization-id>
SCHEDULE_X_ORG_API_TOKEN=sx_org_...

Server-to-server organization routes accept the organization API token as the SDK apiKey, which sends the X-ScheduleX-Api-Key header.

import { ScheduleXServerClient } from '@schedule-x-cloud/sdk'
const serverClient = new ScheduleXServerClient({
apiKey: process.env.SCHEDULE_X_ORG_API_TOKEN!,
})

Equivalent HTTP:

GET /v1/orgs/{organizationId}/calendars
X-ScheduleX-Api-Key: sx_org_...

Create a Cloud user when your own application creates or first sees a user. Store the returned id in your database.

const cloudUser = await serverClient.users.create(
process.env.SCHEDULE_X_ORGANIZATION_ID!,
{
email: 'ada@example.com',
displayName: 'Ada Lovelace',
role: 'Member',
}
)

Equivalent HTTP:

POST /v1/orgs/{organizationId}/users
X-ScheduleX-Api-Key: sx_org_...
Content-Type: application/json
{
"email": "ada@example.com",
"displayName": "Ada Lovelace",
"role": "Member"
}

Cloud user authentication happens by issuing a frontend token for that userId after the user has authenticated with your application:

const frontendToken = await serverClient.auth.createFrontendToken({
organizationApiToken: process.env.SCHEDULE_X_ORG_API_TOKEN!,
organizationId: process.env.SCHEDULE_X_ORGANIZATION_ID!,
userId: cloudUser.id,
})

Equivalent HTTP:

POST /v1/orgs/{organizationId}/auth/frontend-token
X-ScheduleX-Org-Token: sx_org_...
Content-Type: application/json
{
"userId": "..."
}

Send the returned token, expiresAt, organizationId, and userId to the browser. Do not send the organization API token.

Calendars belong to an organization. Events can reference a calendar by its id or slug.

const workCalendar = await serverClient.calendars.create(
process.env.SCHEDULE_X_ORGANIZATION_ID!,
{
name: 'Work',
slug: 'work',
colorName: 'work',
lightMainColor: '#2563eb',
lightContainerColor: '#dbeafe',
lightOnContainerColor: '#172554',
}
)

Equivalent HTTP:

POST /v1/orgs/{organizationId}/calendars
X-ScheduleX-Api-Key: sx_org_...
Content-Type: application/json
{
"name": "Work",
"slug": "work",
"colorName": "work",
"lightMainColor": "#2563eb",
"lightContainerColor": "#dbeafe",
"lightOnContainerColor": "#172554"
}

Required fields are name, slug, and colorName. Color values are optional but recommended so Schedule X can render the calendar immediately.

Backend code can list calendars with the organization token:

const calendars = await serverClient.calendars.list(
process.env.SCHEDULE_X_ORGANIZATION_ID!
)

Browser code should usually load the Schedule X-ready config instead:

import { ScheduleXBrowserClient } from '@schedule-x-cloud/sdk'
const browserClient = new ScheduleXBrowserClient({
token: frontendToken.token,
})
const config = await browserClient.scheduleX.getCalendarAppConfig()

To load a bounded event window:

const config = await browserClient.scheduleX.getCalendarAppConfig({
from: '2026-06-01T00:00:00+00:00',
to: '2026-07-01T00:00:00+00:00',
calendarIds: ['work'],
})

Browser event creation uses the frontend token:

const event = await browserClient.events.create({
calendarId: workCalendar.id,
title: 'Planning',
description: 'Weekly planning session',
location: 'Room 12',
start: '2026-06-10T09:00:00+02:00',
end: '2026-06-10T10:00:00+02:00',
timeZone: 'Europe/Berlin',
isAllDay: false,
isPrivate: false,
people: ['ada@example.com'],
})

Equivalent HTTP:

POST /v1/events
Authorization: Bearer sx_front_...
Content-Type: application/json
{
"calendarId": "...",
"title": "Planning",
"start": "2026-06-10T09:00:00+02:00",
"end": "2026-06-10T10:00:00+02:00",
"timeZone": "Europe/Berlin",
"people": ["ada@example.com"]
}

Required fields are calendarId, start, end, and timeZone. start must be before end. timeZone must be a valid IANA or system time zone id.

await browserClient.events.update(event.id, {
calendarId: workCalendar.id,
title: 'Updated planning',
start: '2026-06-10T09:30:00+02:00',
end: '2026-06-10T10:30:00+02:00',
timeZone: 'Europe/Berlin',
})
await browserClient.events.delete(event.id)

Event writes require the frontend-token user to have Owner, Admin, or Member membership in the organization.