Core Primitive
Background Jobs
Lightweight scheduled tasks that trigger HTTP requests. No servers to manage, no cron syntax to remember.
Active Jobs
fetch-market-dataEvery 15m•Next: 13 min
sync-user-analyticsEvery 60m•Next: 15 min
generate-daily-reportEvery 1440m•Next: -
Recent Executions
fetch-market-data234ms2 min ago
sync-user-analytics1.2s45 min ago
fetch-market-data189ms17 min ago
fetch-market-data5.1s32 min ago
Skip the Infrastructure Hassle
No more managing queues, workers, or Redis. Just tell us what endpoint to call and when.
Without OpenSink
worker.ts
// worker.ts - Set up BullMQ workerimport { Worker, Queue } from "bullmq";import Redis from "ioredis";const connection = new Redis(process.env.REDIS_URL);const queue = new Queue("scheduled-jobs", { connection });// Add recurring jobawait queue.add("fetch-market-data",{ symbols: ["AAPL", "GOOGL"] },{ repeat: { every: 15 * 60 * 1000 } });// Process jobsconst worker = new Worker("scheduled-jobs",async (job) => {await fetchMarketData(job.data.symbols);},{ connection });worker.on("failed", (job, err) => {console.error(`Job ${job?.id} failed:`, err);});// Don't forget: Run Redis, handle restarts,// monitor workers, manage retries...
- • Requires Redis infrastructure
- • Worker process management
- • Manual retry & error handling
- • No built-in monitoring UI
With OpenSink
route.ts
// api/fetch-market-data/route.tsexport async function POST(req: Request) {const { symbols } = await req.json();const data = await fetchMarketData(symbols);// Store results in your sinkawait opensink.items.create("market-data", {title: "Market update",fields: data});return Response.json({ success: true });}
- • Just write your endpoint
- • We handle the scheduling
- • Automatic retries on failure
- • Full execution history in dashboard
Simple Yet Powerful
Interval-Based
Run every N minutes, from 1 to 1440 (daily)
HTTP Triggers
Call any HTTP endpoint when triggered
Execution History
Full logs of every run with status codes
Failure Alerts
Get notified when jobs fail
Jobs trigger endpoints — they don't run code
Your logic lives on your servers, serverless functions, or cloud services. Jobs handle scheduling and retries.
Flexible Scheduling
From every minute to once daily — pick what works for your use case.
Choose Your Interval
Every 15 min — Best for: Regular syncs
Code Examples
Creating a Job
create-job.ts
import { OpenSink } from "@opensink/sdk";const client = new OpenSink({apiKey: process.env.OPENSINK_API_KEY});// Create a job that runs every 15 minutesconst job = await client.jobs.create({name: "fetch-market-data",description: "Fetches latest stock prices",intervalMinutes: 15,endpoint: "https://api.example.com/fetch-prices",method: "POST",headers: {"Authorization": "Bearer ${API_TOKEN}","Content-Type": "application/json"},body: JSON.stringify({symbols: ["AAPL", "GOOGL", "MSFT"]})});
Managing Jobs
manage-jobs.ts
// List all jobsconst jobs = await client.jobs.list();// Pause a jobawait client.jobs.pause("fetch-market-data");// Resume a jobawait client.jobs.resume("fetch-market-data");// Trigger manually (outside schedule)await client.jobs.trigger("fetch-market-data");// Get execution historyconst executions = await client.jobs.executions("fetch-market-data",{ limit: 10 });
Jobs vs. Traditional Cron
Traditional Cron
- Requires server management
- Complex cron syntax (* * * * *)
- No built-in execution history
- Manual failure handling
OpenSink Jobs
- Fully managed, no servers
- Simple interval configuration
- Complete execution logs
- Automatic retries & alerts
Common Use Cases
Data Sync
Pull data from external APIs into your Sinks
Agent Triggers
Periodically run AI agents to process new data
Report Generation
Generate daily/weekly summaries
Health Checks
Monitor external services and log status