Skip to content

Schedule Overrides

Schedule overrides let you temporarily swap who is on-call. Use them for vacation coverage, sick days, or handing off to someone else mid-shift. An override takes effect for a specific time window and automatically expires when the window ends.

Overrides cannot overlap with each other on the same schedule. The maximum duration is 30 days.

import { BeepsClient } from "@beepsdev/sdk";
const client = new BeepsClient({
apiKey: process.env.BEEPS_API_KEY,
});
const override = await client.schedule.createOverride("sch_xyz789", {
userId: "usr_bob",
startAt: "2025-03-15T09:00:00.000Z",
endAt: "2025-03-22T09:00:00.000Z",
reason: "Alice on vacation, Bob covering",
});
console.log(`Override created: ${override.id}`);
console.log(`${override.userId} on-call from ${override.startAt} to ${override.endAt}`);

You can also pass Date objects:

const override = await client.schedule.createOverride("sch_xyz789", {
userId: "usr_bob",
startAt: new Date("2025-03-15T09:00:00.000Z"),
endAt: new Date("2025-03-22T09:00:00.000Z"),
reason: "Alice on vacation, Bob covering",
});
const overrides = await client.schedule.listOverrides("sch_xyz789");
overrides.forEach((override) => {
console.log(`${override.userId}: ${override.startAt} - ${override.endAt}`);
if (override.reason) {
console.log(` Reason: ${override.reason}`);
}
});

Filter by date range to find overrides within a specific window:

const overrides = await client.schedule.listOverrides("sch_xyz789", {
startAt: "2025-03-01T00:00:00.000Z",
endAt: "2025-03-31T23:59:59.999Z",
});

Change the time window or reason for an existing override. All fields are optional—only include what you want to change.

const updated = await client.schedule.updateOverride(
"sch_xyz789",
"ovr_abc123",
{
endAt: "2025-03-25T09:00:00.000Z",
reason: "Extended coverage — Alice returning Thursday",
},
);
console.log(`Override now ends at ${updated.endAt}`);

Cancel an override to restore the normal rotation. The on-call user reverts to whoever the schedule assigns.

const canceled = await client.schedule.cancelOverride("sch_xyz789", "ovr_abc123");
console.log(`Override canceled at ${canceled.canceledAt}`);
type CreateScheduleOverrideInput = {
userId: string;
startAt: string | Date;
endAt: string | Date;
reason?: string;
};
type UpdateScheduleOverrideInput = {
startAt?: string | Date;
endAt?: string | Date;
reason?: string;
};
type ListScheduleOverridesParams = {
startAt?: string | Date;
endAt?: string | Date;
};
type ScheduleOverride = {
id: string;
organizationId: string;
scheduleId: string;
userId: string;
startAt: string;
endAt: string;
reason: string | null;
createdByUserId: string;
createdAt: string;
updatedAt: string;
canceledAt: string | null;
deletedAt: string | null;
};
const vacationStart = new Date("2025-06-01T00:00:00.000Z");
const vacationEnd = new Date("2025-06-14T00:00:00.000Z");
const override = await client.schedule.createOverride(schedule.id, {
userId: "usr_bob",
startAt: vacationStart,
endAt: vacationEnd,
reason: "Covering for Alice — vacation June 1-14",
});
const now = new Date();
const fourHoursLater = new Date(now.getTime() + 4 * 60 * 60 * 1000);
const override = await client.schedule.createOverride(schedule.id, {
userId: "usr_charlie",
startAt: now,
endAt: fourHoursLater,
reason: "Handing off for a few hours",
});

The getOnCall method already accounts for overrides. If an override is active, the returned user will have isOverride: true and overrideId set:

const onCall = await client.schedule.getOnCall(schedule.id);
if (onCall.isOverride) {
console.log(`${onCall.email} is on-call via override ${onCall.overrideId}`);
} else {
console.log(`${onCall.email} is on-call (assignment #${onCall.assignmentNumber})`);
}