Managing Schedules
Create schedules and add team members to on-call rotations.
Creating a Schedule
Section titled “Creating a Schedule”import { BeepsClient } from "@beepsdev/sdk";
const client = new BeepsClient({ apiKey: process.env.BEEPS_API_KEY,});
const schedule = await client.schedule.create({ name: "Weekly On-Call", relayId: "rly_abc123", // Schedule must belong to a relay type: "weekly", // or "daily" startDay: "monday", // Day of week for weekly schedules startTime: "09:00", // Time when rotation occurs (HH:MM format) externalKey: "prod-oncall", // Optional: custom identifier});
console.log(`Created schedule: ${schedule.id}`);Daily Schedule
Section titled “Daily Schedule”const dailySchedule = await client.schedule.create({ name: "Daily On-Call", relayId: "rly_abc123", type: "daily", startDay: "monday", // Not used for daily schedules startTime: "09:00", // Rotates every day at this time});Weekly Schedule
Section titled “Weekly Schedule”const weeklySchedule = await client.schedule.create({ name: "Weekly On-Call", relayId: "rly_abc123", type: "weekly", startDay: "friday", // Rotates every Friday startTime: "17:00", // at 5:00 PM});curl -X POST https://api.beeps.dev/v0/schedule \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Weekly On-Call", "relayId": "rly_abc123", "type": "weekly", "startDay": "monday", "startTime": "09:00", "externalKey": "prod-oncall" }'Response:
{ "schedule": { "id": "sch_xyz789", "organizationId": "org_abc123", "relayId": "rly_abc123", "name": "Weekly On-Call", "type": "weekly", "startDay": "monday", "startTime": "09:00", "externalKey": "prod-oncall", "createdAt": "2025-01-15T10:30:00Z", "updatedAt": "2025-01-15T10:30:00Z", "deletedAt": null }}Listing Schedules
Section titled “Listing Schedules”const schedules = await client.schedule.list();
console.log(`Found ${schedules.length} schedules:`);schedules.forEach((schedule) => { console.log(`- ${schedule.name} (${schedule.type})`);});curl -X GET https://api.beeps.dev/v0/schedule \ -H "Authorization: Bearer YOUR_API_KEY"Response:
{ "schedules": [ { "id": "sch_xyz789", "organizationId": "org_abc123", "relayId": "rly_abc123", "name": "Weekly On-Call", "type": "weekly", "startDay": "monday", "startTime": "09:00", "externalKey": "prod-oncall", "createdAt": "2025-01-15T10:30:00Z", "updatedAt": "2025-01-15T10:30:00Z", "deletedAt": null } ]}Adding Schedule Members
Section titled “Adding Schedule Members”Members are added to the rotation in the order they’re added. The first member is assignment #1, the second is #2, etc.
const member1 = await client.schedule.addMember(schedule.id, { userId: "usr_alice",});console.log(`Added ${member1.userId} to schedule`);
const member2 = await client.schedule.addMember(schedule.id, { userId: "usr_bob",});console.log(`Added ${member2.userId} to schedule`);curl -X POST https://api.beeps.dev/v0/schedule/sch_xyz789/members \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "userId": "usr_alice" }'Response:
{ "member": { "scheduleId": "sch_xyz789", "userId": "usr_alice", "createdAt": "2025-01-15T10:35:00Z" }}Getting Current On-Call User
Section titled “Getting Current On-Call User”const onCall = await client.schedule.getOnCall(schedule.id);
console.log(`Current on-call: ${onCall.email}`);console.log(`User ID: ${onCall.userId}`);console.log(`Assignment #: ${onCall.assignmentNumber}`);Safe Method
Section titled “Safe Method”const result = await client.schedule.getOnCallSafe(schedule.id);
if (result.error) { console.error("Failed to get on-call:", result.error.message);} else { console.log(`On-call: ${result.data.email}`);}curl -X GET https://api.beeps.dev/v0/schedule/sch_xyz789/on-call \ -H "Authorization: Bearer YOUR_API_KEY"Response:
{ "onCall": { "userId": "usr_alice", "email": "alice@example.com", "assignmentNumber": 1, "scheduleId": "sch_xyz789" }}Type Definitions
Section titled “Type Definitions”CreateScheduleInput
Section titled “CreateScheduleInput”type CreateScheduleInput = { name: string; // Schedule name relayId: string; // Parent relay ID type: "daily" | "weekly"; // Rotation frequency startDay: | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday"; // Day of week (used for weekly schedules) startTime: string; // Time of day in HH:MM format (24-hour) externalKey?: string; // Optional custom identifier};Schedule
Section titled “Schedule”type Schedule = { id: string; organizationId: string; relayId: string; name: string; type: "daily" | "weekly"; startDay: | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday"; startTime: string; externalKey: string | null; createdAt: string; updatedAt: string; deletedAt: string | null;};AddScheduleMemberInput
Section titled “AddScheduleMemberInput”type AddScheduleMemberInput = { userId: string; // ID of the user to add to the rotation};ScheduleMember
Section titled “ScheduleMember”type ScheduleMember = { scheduleId: string; userId: string; createdAt?: string;};BeepsUser
Section titled “BeepsUser”type BeepsUser = { userId: string; // User ID of the person currently on-call email: string; // Email address assignmentNumber: number | null; // Current assignment number in rotation (null when schedule has no members) scheduleId: string; // Schedule ID isOverride?: boolean; // True if user is on-call via schedule override overrideId?: string; // ID of the schedule override (if applicable)};Best Practices
Section titled “Best Practices”Always set externalKey for idempotent configuration. All times are in UTC. See Best Practices for details.
Common Patterns
Section titled “Common Patterns”Setting Up a New Team
Section titled “Setting Up a New Team”const relay = await client.relay.create({ name: "Backend Team Alerts",});
const schedule = await client.schedule.create({ name: "Backend Weekly Rotation", relayId: relay.id, type: "weekly", startDay: "monday", startTime: "09:00",});
const teamMembers = ["usr_alice", "usr_bob", "usr_charlie"];for (const userId of teamMembers) { await client.schedule.addMember(schedule.id, { userId });}
await client.relay.rules.create(relay.id, { name: "Notify on-call engineer", ruleType: "schedule_notify", config: { scheduleId: schedule.id, },});Checking Who’s On Call
Section titled “Checking Who’s On Call”const onCall = await client.schedule.getOnCall(schedule.id);console.log(`${onCall.email} is currently on-call`);