Getting Started | Locci Scheduler
Locci Scheduler is a webhook scheduling platform that allows you to schedule HTTP requests to be executed at specific times or intervals.
1. Create an Account
curl -X POST https://api.scheduler.locci.cloud/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "your-email@example.com", "password": "your-secure-password"}'
2. Login
curl -X POST https://api.scheduler.locci.cloud/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "your-email@example.com", "password": "your-secure-password"}'
Save the access_token from the response.
3. Generate an API Key
curl -X POST https://api.scheduler.locci.cloud/api/v1/auth/key \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"expiry_time_days": 60}'
Save the api_key securely - this is what you'll use in your applications.
4. Install an SDK
JavaScript/TypeScript:
npm install @locci/scheduler
Rust:
Add with Cargo toolchain
cargo add locci-scheduler
Or add the crate in Cargo.toml file
[dependencies]
locci-scheduler = "0.1.0"
tokio = { version = "1", features = ["full"] }
5. Configure Environment
# .env
LOCCI_SCHEDULER_URL=https://api.scheduler.locci.cloud
LOCCI_SCHEDULER_TOKEN=your-api-key-here
Next Steps
For detailed SDK usage, examples, and API reference:
- JavaScript/TypeScript SDK - Full documentation for the JS/TS SDK
- Rust SDK - Full documentation for the Rust SDK
Support
- GitHub Issues: github.com/MikeTeddyOmondi/locci-scheduler/issues
- Email: support@locci.cloud
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
Rust SDK
The official Rust SDK for Locci Scheduler provides a type-safe, async API for scheduling webhook tasks using the Tokio runtime.
Installation
Add to your Cargo.toml:
[dependencies]
locci-scheduler = "0.1.0"
tokio = { version = "1", features = ["full"] }
chrono = "0.4"
serde_json = "1.0"
Or add with Cargo toolchain
cargo add locci-scheduler
Quick Start
use locci_scheduler::{LocciScheduler, SchedulerConfig, WebhookConfig, HttpMethod}; use chrono::Utc; #[tokio::main] async fn main() -> locci_scheduler::Result<()> { let config = SchedulerConfig { base_url: "https://api.scheduler.locci.cloud".to_string(), api_token: "your-api-key".to_string(), timeout: 30000, retries: 3, }; let scheduler = LocciScheduler::new(config)?; // Create a one-time task let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: None, payload: Some(serde_json::json!({ "message": "Hello!" })), timeout_seconds: Some(30), retry_config: None, authentication: None, webhook_secret: None, }; let execute_at = Utc::now() + chrono::Duration::minutes(5); let task = scheduler.schedule_once( "My First Task".to_string(), webhook, execute_at, Some("A test task".to_string()), None, ).await?; println!("Task created: {}", task.id); Ok(()) }
Configuration
#![allow(unused)] fn main() { use locci_scheduler::SchedulerConfig; let config = SchedulerConfig { base_url: "https://api.scheduler.locci.cloud".to_string(), api_token: "your-api-key".to_string(), timeout: 30000, // Request timeout in milliseconds retries: 3, // Number of retry attempts }; let scheduler = LocciScheduler::new(config)?; }
Environment Variables
For production, use environment variables:
#![allow(unused)] fn main() { use std::env; let config = SchedulerConfig { base_url: env::var("LOCCI_SCHEDULER_URL") .unwrap_or_else(|_| "https://api.scheduler.locci.cloud".to_string()), api_token: env::var("LOCCI_SCHEDULER_TOKEN") .expect("LOCCI_SCHEDULER_TOKEN must be set"), timeout: 30000, retries: 3, }; }
Task Management
Create a Task
#![allow(unused)] fn main() { use locci_scheduler::{CreateTaskOptions, WebhookConfig, ScheduleConfig, HttpMethod}; use chrono::Utc; use std::collections::HashMap; let webhook = WebhookConfig { url: "https://your-app.com/api/reports".to_string(), method: Some(HttpMethod::Post), headers: Some({ let mut h = HashMap::new(); h.insert("X-Custom-Header".to_string(), "value".to_string()); h }), payload: Some(serde_json::json!({ "reportType": "sales", "period": "daily" })), timeout_seconds: Some(30), retry_config: None, authentication: None, webhook_secret: None, }; let task = scheduler.create_task(CreateTaskOptions { name: "Daily Report".to_string(), description: Some("Send daily sales report".to_string()), webhook, schedule: ScheduleConfig::Recurring { cron_expression: "0 9 * * *".to_string(), timezone: Some("Africa/Nairobi".to_string()), end_date: None, }, metadata: Some({ let mut m = HashMap::new(); m.insert("department".to_string(), serde_json::json!("sales")); m }), }).await?; }
Get a Task
#![allow(unused)] fn main() { let task = scheduler.get_task("task-id-here").await?; println!("Task: {} - Status: {:?}", task.name, task.status); }
List Tasks
#![allow(unused)] fn main() { use locci_scheduler::PaginationOptions; let task_list = scheduler.list_tasks(PaginationOptions { page: Some(1), per_page: Some(10), }).await?; println!("Total tasks: {}", task_list.total); for task in &task_list.tasks { println!("- {} ({:?})", task.name, task.status); } }
Update a Task
#![allow(unused)] fn main() { use locci_scheduler::UpdateTaskOptions; let updated_task = scheduler.update_task("task-id", UpdateTaskOptions { name: Some("Updated Task Name".to_string()), description: Some("New description".to_string()), ..Default::default() }).await?; }
Delete a Task
#![allow(unused)] fn main() { scheduler.delete_task("task-id").await?; }
Task Lifecycle
Pause a Task
#![allow(unused)] fn main() { let task = scheduler.pause_task("task-id").await?; println!("Task status: {:?}", task.status); // Paused }
Resume a Task
#![allow(unused)] fn main() { let task = scheduler.resume_task("task-id").await?; println!("Task status: {:?}", task.status); // Active }
Cancel a Task
#![allow(unused)] fn main() { let task = scheduler.cancel_task("task-id").await?; println!("Task status: {:?}", task.status); // Cancelled }
Manually Trigger a Task
#![allow(unused)] fn main() { scheduler.trigger_task("task-id").await?; }
Scheduling Methods
One-Time Execution
#![allow(unused)] fn main() { use chrono::{Utc, TimeZone}; let webhook = WebhookConfig { url: "https://your-app.com/api/emails/welcome".to_string(), method: Some(HttpMethod::Post), headers: None, payload: Some(serde_json::json!({ "userId": "user123" })), timeout_seconds: Some(30), retry_config: None, authentication: None, webhook_secret: None, }; let execute_at = Utc.with_ymd_and_hms(2024, 12, 25, 9, 0, 0).unwrap(); let task = scheduler.schedule_once( "Send Welcome Email".to_string(), webhook, execute_at, Some("Send welcome email to new user".to_string()), Some({ let mut m = HashMap::new(); m.insert("userId".to_string(), serde_json::json!("user123")); m }), ).await?; }
Recurring with Cron Expression
#![allow(unused)] fn main() { let task = scheduler.schedule_recurring( "Weekly Backup".to_string(), webhook, "0 2 * * 0".to_string(), // Sundays at 2 AM Some("UTC".to_string()), Some(Utc.with_ymd_and_hms(2025, 12, 31, 23, 59, 59).unwrap()), // End date Some("Weekly database backup".to_string()), None, ).await?; }
Interval-Based
#![allow(unused)] fn main() { let task = scheduler.schedule_interval( "Health Check".to_string(), webhook, 300, // Every 5 minutes (300 seconds) Some(Utc::now()), // Start immediately None, // No end date Some("Monitor API health".to_string()), None, ).await?; }
Daily at Specific Time
#![allow(unused)] fn main() { let task = scheduler.schedule_daily( "Daily Sales Report".to_string(), webhook, "09:00", // 9:00 AM (24-hour format) Some("Africa/Nairobi".to_string()), Some("Generate and send daily sales report".to_string()), None, ).await?; }
Weekly
#![allow(unused)] fn main() { let task = scheduler.schedule_weekly( "Weekly Team Standup Reminder".to_string(), webhook, 1, // Monday (0 = Sunday, 1 = Monday, etc.) "09:45", Some("Africa/Nairobi".to_string()), Some("Remind team about standup".to_string()), None, ).await?; }
Convenience Methods
#![allow(unused)] fn main() { // Every minute let task = scheduler.schedule_every_minute( "Minute Task".to_string(), webhook.clone(), None, None, ).await?; // Every hour let task = scheduler.schedule_every_hour( "Hourly Task".to_string(), webhook, None, None, ).await?; }
Webhook Configuration
Basic Webhook
#![allow(unused)] fn main() { use std::collections::HashMap; let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: Some({ let mut h = HashMap::new(); h.insert("Content-Type".to_string(), "application/json".to_string()); h.insert("X-Custom-Header".to_string(), "value".to_string()); h }), payload: Some(serde_json::json!({ "key": "value" })), timeout_seconds: Some(30), retry_config: None, authentication: None, webhook_secret: None, }; }
With Retry Configuration
#![allow(unused)] fn main() { use locci_scheduler::RetryConfig; let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: None, payload: None, timeout_seconds: Some(30), retry_config: Some(RetryConfig { max_attempts: 5, backoff_seconds: 2, backoff_multiplier: 2.0, max_backoff_seconds: 300, }), authentication: None, webhook_secret: None, }; }
Authentication Types
API Key
#![allow(unused)] fn main() { use locci_scheduler::AuthConfig; let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: None, payload: None, timeout_seconds: Some(30), retry_config: None, authentication: Some(AuthConfig::ApiKey { header_name: "X-API-Key".to_string(), key: "your-api-key-value".to_string(), }), webhook_secret: None, }; }
Bearer Token
#![allow(unused)] fn main() { let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: None, payload: None, timeout_seconds: Some(30), retry_config: None, authentication: Some(AuthConfig::BearerToken { token: "your-bearer-token".to_string(), }), webhook_secret: None, }; }
Basic Auth
#![allow(unused)] fn main() { let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: None, payload: None, timeout_seconds: Some(30), retry_config: None, authentication: Some(AuthConfig::BasicAuth { username: "user".to_string(), password: "password".to_string(), }), webhook_secret: None, }; }
HMAC Webhook Signature
For secure webhook verification:
#![allow(unused)] fn main() { let webhook = WebhookConfig { url: "https://your-app.com/webhook".to_string(), method: Some(HttpMethod::Post), headers: None, payload: Some(serde_json::json!({ "data": "sensitive" })), timeout_seconds: Some(30), retry_config: None, authentication: None, webhook_secret: Some("your-webhook-secret".to_string()), }; }
The scheduler will include an X-Locci-Signature header with an HMAC-SHA256 signature. Verify on your server:
#![allow(unused)] fn main() { use hmac::{Hmac, Mac}; use sha2::Sha256; type HmacSha256 = Hmac<Sha256>; fn verify_signature(payload: &str, signature: &str, secret: &str) -> bool { let mut mac = HmacSha256::new_from_slice(secret.as_bytes()) .expect("HMAC can take key of any size"); mac.update(payload.as_bytes()); let expected = hex::encode(mac.finalize().into_bytes()); signature == expected } }
Execution History
#![allow(unused)] fn main() { let history = scheduler.get_task_history("task-id").await?; println!("Total executions: {}", history.total); for exec in &history.executions { println!("- {:?}: {:?}", exec.executed_at, exec.status); if let Some(ref error) = exec.error_message { println!(" Error: {}", error); } } }
Billing & Subscription
Get Current Subscription
#![allow(unused)] fn main() { let subscription = scheduler.get_subscription().await?; println!("Plan: {:?}", subscription.plan); println!("Status: {}", subscription.status); }
Subscribe to a Plan
#![allow(unused)] fn main() { use locci_scheduler::SubscriptionPlan; let subscription = scheduler.subscribe( SubscriptionPlan::Pro, "254712345678".to_string(), // M-Pesa phone number ).await?; }
Get Usage
#![allow(unused)] fn main() { let usage = scheduler.get_usage().await?; println!("Tasks created: {}", usage.current_usage.tasks_created); println!("Webhook executions: {}", usage.current_usage.webhook_executions); println!("API calls: {}", usage.current_usage.api_calls); println!("Max tasks: {:?}", usage.limits.max_tasks); }
Cancel Subscription
#![allow(unused)] fn main() { let subscription = scheduler.cancel_subscription().await?; }
Error Handling
The SDK provides a comprehensive error type:
#![allow(unused)] fn main() { use locci_scheduler::SchedulerError; match scheduler.create_task(options).await { Ok(task) => println!("Task created: {}", task.id), Err(SchedulerError::AuthenticationError(msg)) => { eprintln!("Authentication failed: {}", msg); } Err(SchedulerError::ValidationError(msg)) => { eprintln!("Invalid configuration: {}", msg); } Err(SchedulerError::NotFoundError(msg)) => { eprintln!("Resource not found: {}", msg); } Err(SchedulerError::RateLimitError(msg)) => { eprintln!("Rate limit exceeded: {}", msg); } Err(SchedulerError::ApiError { status, message }) => { eprintln!("API error ({}): {}", status, message); } Err(e) => eprintln!("Unexpected error: {}", e), } }
Error Types
#![allow(unused)] fn main() { pub enum SchedulerError { AuthenticationError(String), ValidationError(String), NotFoundError(String), RateLimitError(String), ApiError { status: u16, message: String }, NetworkError(reqwest::Error), JsonError(serde_json::Error), } }
Types Reference
Task Status
#![allow(unused)] fn main() { pub enum TaskStatus { Active, Paused, Completed, Failed, Cancelled, } }
Execution Status
#![allow(unused)] fn main() { pub enum ExecutionStatus { Success, Failed, Retrying, TimedOut, } }
HTTP Methods
#![allow(unused)] fn main() { pub enum HttpMethod { Get, Post, Put, Patch, Delete, } }
Schedule Config
#![allow(unused)] fn main() { pub enum ScheduleConfig { Once { execute_at: DateTime<Utc>, }, Recurring { cron_expression: String, timezone: Option<String>, end_date: Option<DateTime<Utc>>, }, Interval { interval_seconds: u64, start_at: Option<DateTime<Utc>>, end_date: Option<DateTime<Utc>>, }, } }
Subscription Plans
#![allow(unused)] fn main() { pub enum SubscriptionPlan { Free, Starter, Pro, Business, } }
Complete Example
use locci_scheduler::{ LocciScheduler, SchedulerConfig, WebhookConfig, HttpMethod, PaginationOptions, SchedulerError, }; use chrono::Utc; use std::collections::HashMap; use std::env; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { // Initialize client let config = SchedulerConfig { base_url: env::var("LOCCI_SCHEDULER_URL") .unwrap_or_else(|_| "https://api.scheduler.locci.cloud".to_string()), api_token: env::var("LOCCI_SCHEDULER_TOKEN") .expect("LOCCI_SCHEDULER_TOKEN must be set"), timeout: 30000, retries: 3, }; let scheduler = LocciScheduler::new(config)?; // Create webhook config let webhook = WebhookConfig { url: "https://httpbin.org/post".to_string(), method: Some(HttpMethod::Post), headers: Some({ let mut h = HashMap::new(); h.insert("Content-Type".to_string(), "application/json".to_string()); h }), payload: Some(serde_json::json!({ "message": "Hello from Locci Scheduler!", "timestamp": Utc::now().to_rfc3339() })), timeout_seconds: Some(30), retry_config: None, authentication: None, webhook_secret: None, }; // Schedule a task let task = scheduler.schedule_interval( "Test Task".to_string(), webhook, 60, // Every minute Some(Utc::now()), None, Some("Test task for demonstration".to_string()), None, ).await?; println!("Created task: {}", task.id); // List all tasks let tasks = scheduler.list_tasks(PaginationOptions { page: Some(1), per_page: Some(10), }).await?; println!("\nAll tasks ({}):", tasks.total); for t in &tasks.tasks { println!(" - {} ({:?})", t.name, t.status); } // Get usage information match scheduler.get_usage().await { Ok(usage) => { println!("\nUsage:"); println!(" Tasks created: {}", usage.current_usage.tasks_created); println!(" Webhook executions: {}", usage.current_usage.webhook_executions); println!(" Plan: {:?}", usage.subscription.plan); } Err(e) => eprintln!("Failed to get usage: {}", e), } // Pause the task let paused_task = scheduler.pause_task(&task.id).await?; println!("\nTask paused: {:?}", paused_task.status); // Resume the task let resumed_task = scheduler.resume_task(&task.id).await?; println!("Task resumed: {:?}", resumed_task.status); // Delete the task scheduler.delete_task(&task.id).await?; println!("Task deleted"); Ok(()) }
Resources
- Crates.io: https://crates.io/crates/locci-scheduler
- docs.rs: https://docs.rs/locci-scheduler
- GitHub: https://github.com/MikeTeddyOmondi/locci-scheduler/tree/main/sdk/rust
- Examples: Check the
examples/directory in the SDK - API Documentation: https://docs.scheduler.locci.cloud
- Support: support@locci.cloud