JavaScript/TypeScript SDK
The official JavaScript/TypeScript SDK for Locci Scheduler provides a type-safe, promise-based API for scheduling webhook tasks.
Installation
npm install @locci/scheduler
Or with other package managers:
bun add @locci/scheduler
pnpm add @locci/scheduler
yarn add @locci/scheduler
Quick Start
import { LocciScheduler } from "@locci/scheduler";
const scheduler = new LocciScheduler({
baseUrl: "https://api.scheduler.locci.cloud",
apiToken: "your-api-key",
});
// Create a one-time task
const task = await scheduler.scheduleOnce({
name: "My First Task",
webhook: {
url: "https://your-app.com/webhook",
method: "POST",
payload: { message: "Hello!" },
},
executeAt: new Date(Date.now() + 5 * 60 * 1000), // 5 minutes from now
});
console.log("Task created:", task.id);
Configuration
import { LocciScheduler } from "@locci/scheduler";
const scheduler = new LocciScheduler({
baseUrl: "https://api.scheduler.locci.cloud", // API base URL
apiToken: "your-api-key", // Your API key from the console
timeout: 30000, // Request timeout in ms (default: 30000)
retries: 3, // Number of retries (default: 3)
});
Environment Variables
For production, use environment variables:
import dotenv from "dotenv";
dotenv.config();
const scheduler = new LocciScheduler({
baseUrl: process.env.LOCCI_SCHEDULER_URL,
apiToken: process.env.LOCCI_SCHEDULER_TOKEN,
});
Task Management
Create a Task
const task = await scheduler.createTask({
name: "Daily Report",
description: "Send daily sales report",
webhook: {
url: "https://your-app.com/api/reports",
method: "POST",
headers: {
"X-Custom-Header": "value",
},
payload: {
reportType: "sales",
period: "daily",
},
timeoutSeconds: 30,
},
schedule: {
type: "recurring",
cronExpression: "0 9 * * *", // Every day at 9 AM
timezone: "Africa/Nairobi",
},
metadata: {
department: "sales",
priority: "high",
},
});
Get a Task
const task = await scheduler.getTask("task-id-here");
console.log(task.name, task.status);
List Tasks
const taskList = await scheduler.listTasks({
page: 1,
perPage: 10,
});
console.log(`Total tasks: ${taskList.total}`);
taskList.tasks.forEach((task) => {
console.log(`- ${task.name} (${task.status})`);
});
Update a Task
const updatedTask = await scheduler.updateTask("task-id", {
name: "Updated Task Name",
description: "New description",
});
Delete a Task
await scheduler.deleteTask("task-id");
Task Lifecycle
Pause a Task
const task = await scheduler.pauseTask("task-id");
console.log(task.status); // "Paused"
Resume a Task
const task = await scheduler.resumeTask("task-id");
console.log(task.status); // "Active"
Cancel a Task
const task = await scheduler.cancelTask("task-id");
console.log(task.status); // "Cancelled"
Manually Trigger a Task
await scheduler.triggerTask("task-id");
Scheduling Methods
One-Time Execution
const task = await scheduler.scheduleOnce({
name: "Send Welcome Email",
webhook: {
url: "https://your-app.com/api/emails/welcome",
method: "POST",
payload: { userId: "user123" },
},
executeAt: new Date("2024-12-25T09:00:00Z"),
description: "Send welcome email to new user",
metadata: { userId: "user123" },
});
Recurring with Cron Expression
const task = await scheduler.scheduleRecurring({
name: "Weekly Backup",
webhook: {
url: "https://your-app.com/api/backup",
method: "POST",
},
cronExpression: "0 2 * * 0", // Sundays at 2 AM
timezone: "UTC",
endDate: new Date("2025-12-31"), // Optional end date
});
Interval-Based
const task = await scheduler.scheduleInterval({
name: "Health Check",
webhook: {
url: "https://your-app.com/health",
method: "GET",
timeoutSeconds: 10,
},
intervalSeconds: 300, // Every 5 minutes
startAt: new Date(), // Start immediately
});
Daily at Specific Time
const task = await scheduler.scheduleDaily({
name: "Daily Sales Report",
webhook: {
url: "https://your-app.com/api/reports/daily",
method: "POST",
},
time: "09:00", // 9:00 AM (24-hour format)
timezone: "Africa/Nairobi",
});
Weekly
const task = await scheduler.scheduleWeekly({
name: "Weekly Team Standup Reminder",
webhook: {
url: "https://your-app.com/api/slack/notify",
method: "POST",
payload: { message: "Team standup in 15 minutes!" },
},
dayOfWeek: 1, // Monday (0 = Sunday)
time: "09:45",
timezone: "Africa/Nairobi",
});
Convenience Methods
// Every minute
await scheduler.scheduleEveryMinute({
name: "Minute Task",
webhook: { url: "https://example.com/ping", method: "GET" },
});
// Every hour
await scheduler.scheduleEveryHour({
name: "Hourly Task",
webhook: { url: "https://example.com/hourly", method: "POST" },
});
Webhook Configuration
Basic Webhook
const webhook = {
url: "https://your-app.com/webhook",
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Custom-Header": "value",
},
payload: {
key: "value",
},
timeoutSeconds: 30,
};
With Retry Configuration
const webhook = {
url: "https://your-app.com/webhook",
method: "POST",
retryConfig: {
maxAttempts: 5,
backoffSeconds: 2,
backoffMultiplier: 2.0,
maxBackoffSeconds: 300,
},
};
Authentication Types
API Key
const webhook = {
url: "https://your-app.com/webhook",
method: "POST",
authentication: {
type: "apiKey",
apiKey: {
headerName: "X-API-Key",
key: "your-api-key-value",
},
},
};
Bearer Token
const webhook = {
url: "https://your-app.com/webhook",
method: "POST",
authentication: {
type: "bearerToken",
bearerToken: {
token: "your-bearer-token",
},
},
};
Basic Auth
const webhook = {
url: "https://your-app.com/webhook",
method: "POST",
authentication: {
type: "basicAuth",
basicAuth: {
username: "user",
password: "password",
},
},
};
HMAC Webhook Signature
For secure webhook verification, use webhookSecret:
const webhook = {
url: "https://your-app.com/webhook",
method: "POST",
payload: { data: "sensitive" },
webhookSecret: "your-webhook-secret",
};
The scheduler will include an X-Locci-Signature header with an HMAC-SHA256 signature of the payload. Verify it on your server:
import crypto from "crypto";
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac("sha256", secret)
.update(JSON.stringify(payload))
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Execution History
const history = await scheduler.getTaskHistory("task-id");
console.log(`Total executions: ${history.total}`);
history.executions.forEach((exec) => {
console.log(`- ${exec.executedAt}: ${exec.status}`);
if (exec.errorMessage) {
console.log(` Error: ${exec.errorMessage}`);
}
});
Error Handling
The SDK provides specific error classes for different scenarios:
import {
SchedulerError,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError,
} from "@locci/scheduler";
try {
const task = await scheduler.createTask({
// ... task configuration
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error("Authentication failed - check your API key");
} else if (error instanceof ValidationError) {
console.error("Invalid task configuration:", error.details);
} else if (error instanceof NotFoundError) {
console.error("Resource not found");
} else if (error instanceof RateLimitError) {
console.error("Rate limit exceeded - please wait and retry");
} else if (error instanceof SchedulerError) {
console.error(`API error (${error.statusCode}):`, error.message);
} else {
console.error("Unexpected error:", error);
}
}
TypeScript Types
All types are exported from the package:
import type {
Task,
TaskExecution,
TaskStatus,
ExecutionStatus,
SchedulerConfig,
CreateTaskOptions,
UpdateTaskOptions,
WebhookConfig,
ScheduleConfig,
AuthConfig,
RetryConfig,
HttpMethod,
PaginationOptions,
TaskListResponse,
TaskHistoryResponse,
} from "@locci/scheduler";
Type Definitions
// Task status values
type TaskStatus = "Active" | "Paused" | "Completed" | "Failed" | "Cancelled";
// Execution status values
type ExecutionStatus = "Success" | "Failed" | "Retrying" | "TimedOut";
// HTTP methods
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
// Schedule types
type ScheduleType = "once" | "recurring" | "interval";
Common Use Cases
User Onboarding Email Sequence
async function scheduleOnboardingEmails(userId: string, email: string) {
const baseTime = new Date();
// Welcome email - 2 minutes after signup
await scheduler.scheduleOnce({
name: `Welcome Email - ${userId}`,
webhook: {
url: "https://your-app.com/api/emails/send",
method: "POST",
payload: { to: email, template: "welcome", userId },
},
executeAt: new Date(baseTime.getTime() + 2 * 60 * 1000),
metadata: { userId, emailType: "welcome" },
});
// Tips email - 1 day after signup
await scheduler.scheduleOnce({
name: `Tips Email - ${userId}`,
webhook: {
url: "https://your-app.com/api/emails/send",
method: "POST",
payload: { to: email, template: "tips", userId },
},
executeAt: new Date(baseTime.getTime() + 24 * 60 * 60 * 1000),
metadata: { userId, emailType: "tips" },
});
// Follow-up email - 3 days after signup
await scheduler.scheduleOnce({
name: `Follow-up Email - ${userId}`,
webhook: {
url: "https://your-app.com/api/emails/send",
method: "POST",
payload: { to: email, template: "followup", userId },
},
executeAt: new Date(baseTime.getTime() + 3 * 24 * 60 * 60 * 1000),
metadata: { userId, emailType: "followup" },
});
}
Health Monitoring
async function setupHealthMonitoring(services: string[]) {
for (const service of services) {
await scheduler.scheduleInterval({
name: `Health Check - ${service}`,
webhook: {
url: `https://${service}.your-domain.com/health`,
method: "GET",
timeoutSeconds: 10,
},
intervalSeconds: 60, // Check every minute
metadata: { service, type: "health-check" },
});
}
}
Subscription Renewal Reminders
async function scheduleRenewalReminder(
userId: string,
email: string,
renewalDate: Date
) {
// Reminder 7 days before
const reminderDate = new Date(renewalDate.getTime() - 7 * 24 * 60 * 60 * 1000);
await scheduler.scheduleOnce({
name: `Renewal Reminder - ${userId}`,
webhook: {
url: "https://your-app.com/api/emails/send",
method: "POST",
payload: {
to: email,
template: "renewal_reminder",
userId,
renewalDate: renewalDate.toISOString(),
},
},
executeAt: reminderDate,
metadata: { userId, type: "renewal_reminder" },
});
}
Resources
- NPM Package: https://www.npmjs.com/package/@locci/scheduler
- GitHub: https://github.com/MikeTeddyOmondi/locci-scheduler/tree/main/sdk/javascript
- API Documentation: https://docs.scheduler.locci.cloud
- Support: support@locci.cloud