Everything you need to integrate Jobs Done into your application. Choose your preferred method: CLI, SDK, or direct API calls.
The jobs_done CLI provides full control from your terminal, CI pipeline, or LLM agent.
Every command outputs clean JSON — pipe it, parse it, automate it.
# x86_64 (amd64)
curl -fsSL https://github.com/jobsdone/cli/releases/latest/download/jobs_done-linux-amd64 \
-o /usr/local/bin/jobs_done && chmod +x /usr/local/bin/jobs_done
# arm64
curl -fsSL https://github.com/jobsdone/cli/releases/latest/download/jobs_done-linux-arm64 \
-o /usr/local/bin/jobs_done && chmod +x /usr/local/bin/jobs_done
jobs_done --version
# Register and get your API key
jobs_done user register "My App"
# Output:
# Name: My App
# API Key: jd_sk_8f3e...c21a
# Set your API key (or export JOBSDONE_API_KEY)
export JOBSDONE_API_KEY="your-api-key"
# Schedule a daily cron (fires at 09:00 UTC every day)
jobs_done cron create \
--name "daily-report" \
--cron "0 9 * * *" \
--url "https://your-domain.com/webhooks/daily"
# Enqueue a one-off job (idempotent — safe to call on every deploy)
jobs_done job enqueue \
--id "send-welcome-email-user-123" \
--url "https://your-domain.com/webhooks/welcome"
# List all your cron jobs
jobs_done cron list
# Pause and resume a cron job
jobs_done cron pause "daily-report"
jobs_done cron resume "daily-report"
LLM & agent-friendly
Every command outputs clean JSON — perfect for piping into jq, scripting in CI, or driving from an AI agent. Pass --output json to suppress decorative output. The CLI reads JOBSDONE_API_KEY from the environment — no interactive prompts in automation mode.
Official SDKs for the Jobs Done API. Select your language below to see install instructions, authentication, and a complete code example.
Official Node.js/TypeScript SDK. Type-safe access to all endpoints with native fetch.
npm install jobsdone-sdk
JOBSDONE_API_KEY=your-api-key
JOBSDONE_BASE_URL=https://api.jobsdone.dev # optional, defaults to http://localhost:4000
This example demonstrates scheduling a daily report cron, enqueueing a one-off job, removing a tenant's schedules using a regex pattern, and handling a webhook.
import { createClient } from 'jobsdone-sdk';
const client = createClient({
apiKey: process.env.JOBSDONE_API_KEY!,
baseUrl: process.env.JOBSDONE_BASE_URL, // optional, defaults to http://localhost:4000
});
// ── 1. Schedule a daily report cron for a specific tenant ──────────────────
const tenantId = 'acme-corp';
const cron = await client.createCron({
logicId: `daily-report-${tenantId}`,
name: `Daily Report: ${tenantId}`,
cronExpression: '0 9 * * *', // 09:00 UTC every day
webhookUrl: 'https://your-domain.com/webhooks/daily-report',
body: {
tenantId,
reportType: 'daily-summary',
format: 'json',
},
maxAttempts: 3,
});
console.log(`Cron scheduled: ${cron.logicId}`);
// ── 2. Enqueue a one-off welcome email job ─────────────────────────────────
// Idempotent: calling this multiple times with the same logic_id is safe.
const job = await client.enqueue({
logicId: `welcome-email-${tenantId}`,
description: {
webhook: 'https://your-domain.com/webhooks/welcome',
userId: tenantId,
},
});
console.log(`Job enqueued: id=${job.id}, state=${job.state}`);
// ── 3. Remove all schedules for a tenant using regex ───────────────────────
// The API supports SQL LIKE patterns in the logic_id filter.
// "%" matches any sequence of characters.
const allJobs = await client.listJobs();
const tenantJobs = allJobs.filter(
(j) => j.logicId != null && j.logicId.startsWith(`daily-report-${tenantId}`)
);
for (const j of tenantJobs) {
await client.cancelJob(j.logicId!);
console.log(`Cancelled job: ${j.logicId}`);
}
// ── 4. Pause and resume a cron ──────────────────────────────────────────────
const paused = await client.pauseCron(`daily-report-${tenantId}`);
console.log(`Cron paused: active=${paused.active}`);
// Later, resume it:
const resumed = await client.resumeCron(`daily-report-${tenantId}`);
console.log(`Cron resumed: active=${resumed.active}`);
Authentication
Set your API key via the JOBSDONE_API_KEY environment variable, or pass it directly to createClient({ apiKey: 'your-key' }).
When a job fires, Jobs Done sends an HTTP POST
to your configured webhook_url.
The request body contains the body you stored
when creating the cron (or the description for one-off enqueued jobs).
# Example webhook request from Jobs Done to your endpoint:
POST /webhooks/daily-report HTTP/1.1
Host: your-domain.com
Content-Type: application/json
X-JobsDone-Signature: sha256=abc123... # future: HMAC signature for verification
X-JobsDone-Logic-ID: daily-report-acme-corp
X-JobsDone-Cron-ID: 42
{
"tenant_id": "acme-corp",
"report_type": "daily-summary",
"format": "json"
}
// Return 2xx to acknowledge. Jobs Done retries on non-2xx responses.
// The number of retries is controlled by max_attempts (default: 3).
app.post('/webhooks/daily-report', async (req, res) => {
const { tenant_id, report_type } = req.body;
// Process the report...
await generateReport({ tenantId: tenant_id, type: report_type });
res.status(200).json({ ok: true });
});
Webhook Security
Configure your webhook endpoint to only accept requests from the Jobs Done domain
(api.jobsdone.dev). This prevents
spoofed job executions. Check the X-JobsDone-Signature
header (future) to verify authenticity.
The full OpenAPI 3.0 specification is available at GET /api/openapi.
Use the interactive SwaggerUI to explore all endpoints, request/response schemas, and try out API calls directly.
Returns the complete OpenAPI 3.0 specification as JSON. Use this to generate SDKs or integrate with tools like Postman.
View OpenAPI JSONInteractive API documentation. Explore all endpoints, see request/response schemas, and test API calls directly from the browser.
Open SwaggerUI