This is a complete reference for all SDK resources and their methods.
const { id, created } = await client.jobs.create({
queueName: 'my-queue', // Required: target queue
payload: { data: 'value' }, // Required: job data (any JSON)
// Optional
priority: 5, // -100 to 100 (default: 0)
maxRetries: 3, // Retry attempts (default: 3)
timeoutSeconds: 300, // Job timeout (default: 300)
scheduledAt: new Date(), // Delay execution
idempotencyKey: 'unique-key', // Prevent duplicates
tags: { env: 'prod' }, // Metadata tags
});const jobs = await client.jobs.list({
queueName: 'my-queue', // Optional: filter by queue
status: 'pending', // Optional: 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled'
tag: 'billing', // Optional: filter by a single tag
limit: 10, // Pagination limit
offset: 0, // Pagination offset
});const job = await client.jobs.get('job_id');
// Returns: { id, queueName, status, payload, priority, ... }await client.jobs.cancel('job_id');const { id } = await client.jobs.retry('job_id');await client.jobs.boostPriority('job_id', 10); // Add 10 to priorityconst stats = await client.jobs.getStats();
// { pending, processing, completed, failed, deadLetter }const result = await client.jobs.bulkEnqueue({
queueName: 'my-queue',
jobs: [
{ payload: { n: 1 } },
{ payload: { n: 2 }, priority: 10 },
{ payload: { n: 3 }, maxRetries: 5 },
],
});
// { jobIds: ['job_1', 'job_2', 'job_3'], enqueuedCount: 3 }const statuses = await client.jobs.batchStatus(['job_1', 'job_2', 'job_3']);
// { job_1: 'completed', job_2: 'processing', job_3: 'pending' }const result = await client.jobs.claim({
queueName: 'my-queue',
workerId: 'worker-1',
limit: 10,
leaseDurationSecs: 300,
});
// { jobs: [...], claimedCount: 5 }await client.jobs.complete('job_id', {
workerId: 'worker-1',
result: { success: true },
});await client.jobs.fail('job_id', {
workerId: 'worker-1',
error: 'Something went wrong',
});await client.jobs.heartbeat('job_id', {
workerId: 'worker-1',
leaseDurationSecs: 300,
});// List DLQ jobs
const dlqJobs = await client.jobs.dlq.list({
queueName: 'my-queue',
limit: 50,
});
// Retry DLQ jobs
await client.jobs.dlq.retry({
jobIds: ['job_1', 'job_2'],
});
// Retry all DLQ jobs for a queue
await client.jobs.dlq.retry({
queueName: 'my-queue',
});
// Purge DLQ
await client.jobs.dlq.purge({
queueName: 'my-queue',
confirm: true,
});const queues = await client.queues.list();
// [{ queueName, enabled, defaultPriority, ... }]const config = await client.queues.get('my-queue');await client.queues.updateConfig('my-queue', {
maxRetries: 5,
defaultTimeout: 600,
rateLimit: 100,
enabled: true,
});const stats = await client.queues.getStats('my-queue');
// { pending, processing, completed, failed, ... }await client.queues.pause('my-queue', 'Maintenance window');await client.queues.resume('my-queue');const schedule = await client.schedules.create({
name: 'Daily Report',
cronExpression: '0 0 9 * * *', // 6-field cron (with seconds)
timezone: 'America/New_York',
queueName: 'reports',
payloadTemplate: { type: 'daily' },
enabled: true,
});const schedules = await client.schedules.list();const schedule = await client.schedules.get('schedule_id');await client.schedules.update('schedule_id', {
cronExpression: '0 0 8 * * *',
enabled: false,
});await client.schedules.delete('schedule_id');await client.schedules.pause('schedule_id');
await client.schedules.resume('schedule_id');const { jobId } = await client.schedules.trigger('schedule_id');const runs = await client.schedules.getHistory('schedule_id', 10);
// Last 10 executionsconst workflow = await client.workflows.create({
name: 'ETL Pipeline',
jobs: [
{ key: 'extract', queueName: 'etl', payload: {} },
{ key: 'transform', queueName: 'etl', payload: {}, dependsOn: ['extract'] },
{ key: 'load', queueName: 'etl', payload: {}, dependsOn: ['transform'] },
],
});
// { workflowId, jobMappings: { extract: 'job_1', ... } }const status = await client.workflows.get('workflow_id');
// { workflowId, status, jobs: [...] }await client.workflows.cancel('workflow_id');Retry all failed jobs in a workflow. Only works on workflows with status failed.
const workflow = await client.workflows.retry('workflow_id');
// Workflow status changes from 'failed' to 'running'
// Failed jobs are reset to 'pending' and reprocessedconst deps = await client.workflows.jobs.getDependencies('job_id');
await client.workflows.jobs.addDependencies('job_id', {
dependsOnJobIds: ['other_job_id'],
});const webhook = await client.webhooks.create({
name: 'Slack Notifications',
url: 'https://hooks.slack.com/...',
events: ['job.completed', 'job.failed'],
secret: 'hmac-secret',
enabled: true,
});const webhooks = await client.webhooks.list();const wh = await client.webhooks.get('webhook_id');
await client.webhooks.update('webhook_id', { enabled: false });
await client.webhooks.delete('webhook_id');const result = await client.webhooks.test('webhook_id');
// { success, statusCode, ... }const deliveries = await client.webhooks.getDeliveries('webhook_id', { limit: 50 });const result = await client.webhooks.retryDelivery('webhook_id', 'delivery_id');
// { success, message }const workers = await client.workers.list();const worker = await client.workers.get('worker_id');const registration = await client.workers.register({
queueName: 'my-queue',
hostname: 'worker-01',
workerType: 'nodejs',
maxConcurrency: 10,
metadata: { version: '1.0.0' },
});
// { id, leaseDurationSecs, heartbeatIntervalSecs }await client.workers.heartbeat('worker_id', {
currentJobs: 5,
status: 'healthy',
});await client.workers.deregister('worker_id');const keys = await client.apiKeys.list();
// Keys are masked (only last 4 chars shown)const { id, key } = await client.apiKeys.create({
name: 'Production API Key',
queues: ['queue-1', 'queue-2'], // Optional: restrict to queues
rateLimit: 1000,
});
// IMPORTANT: 'key' is only shown once!await client.apiKeys.update('key_id', {
name: 'Updated Name',
rateLimit: 2000,
});await client.apiKeys.revoke('key_id');const { organization, apiKey } = await client.organizations.create({
name: 'My Company',
slug: 'my-company',
billingEmail: 'billing@company.com',
});const usage = await client.organizations.getUsage();
// { plan, planDisplayName, usage: { jobsToday, queues, workers, ... } }const orgs = await client.organizations.list();
// Returns list of organizations accessible to your API keyconst { available, valid, suggestion } = await client.organizations.checkSlug('my-company');
// available: boolean - whether slug is available
// valid: boolean - whether slug format is valid
// suggestion: string | null - alternative slug if not availableconst { slug } = await client.organizations.generateSlug('My Company Name');
// Returns a unique, URL-safe slug generated from the nameconst status = await client.billing.getStatus();
// { planTier, hasStripeCustomer, ... }const portal = await client.billing.createPortal({
returnUrl: 'https://yourapp.com/billing',
});
// { url } - Redirect user to this Stripe portal URLconst { accessToken, refreshToken } = await client.auth.login({
apiKey: 'sk_live_...'
});
// Use JWT for subsequent requests
const jwtClient = new SpooledClient({ accessToken });const { valid } = await client.auth.validate({ token: accessToken });const { accessToken } = await client.auth.refresh({ refreshToken });const user = await client.auth.me(); // Requires JWT token
// { organizationId, ... }await client.auth.logout();// Start email login flow (sends magic link)
const result = await client.auth.startEmailLogin('user@example.com');
// { success, message }
// Check if email exists in system
const { exists } = await client.auth.checkEmail('user@example.com');const dashboard = await client.dashboard.get();
// { system, jobs, queues, workers, recentActivity }const health = await client.health.get();
// { status, database, cache, timestamp }const ready = await client.health.readiness();
// true | falseconst metrics = await client.metrics.get();
// Raw Prometheus metrics textRequires adminKey in client config.
const orgs = await client.admin.listOrganizations({
planTier: 'pro',
limit: 10,
});const org = await client.admin.getOrganization('org_id');await client.admin.updateOrganization('org_id', {
planTier: 'enterprise',
});const stats = await client.admin.getStats();
// { organizations, jobs, queues, ... }const { id, key } = await client.admin.createApiKey({
organizationId: 'org_id',
name: 'Admin-created key',
});For receiving webhooks from external services. These are signature-based, not API-key-based.
await client.ingest.custom('org_id', {
queueName: 'custom_events',
eventType: 'custom.event',
payload: { data: 'value' },
});import type {
// Client
SpooledClient,
SpooledClientConfig,
// Jobs
Job,
JobStatus,
CreateJobParams,
JobStats,
// Queues
Queue,
QueueStats,
QueueConfig,
// Schedules
Schedule,
CreateScheduleParams,
// Workflows
Workflow,
CreateWorkflowParams,
// Workers
Worker,
WorkerStatus,
SpooledWorker,
SpooledWorkerOptions,
JobContext,
// Webhooks
Webhook,
WebhookEvent,
// Common
PaginationParams,
JsonObject,
} from '@spooled/sdk';