Jobs
Jobs
One primitive replaces three services. Queue, Task, and Cron are all the same object — what differs is the trigger.
30-second handler constraint: SaaSignal runs on Cloudflare Workers, which impose a 30 s limit on outbound subrequests. Your
handler URL must respond with 2xx within 30 s. For long work, respond immediately with 202 Accepted and POST results to callback_url when done.trigger.type
Concept
Example use case
immediateOne-off task
Send email on signup, call webhook
delayedDelayed task
Send reminder 24h from now
scheduledCron
Nightly billing digest, cache warm-up
queuePush queue
Fan-out pipeline, rate-limited workers
pullPull queue
Work-stealing pool, mobile job claiming
Create Job
GET
typescript
await ss.infra.jobs.create({
trigger: { type: 'immediate' },
handler: 'https://app.acme.com/api/task',
payload: { id: 1 },
max_attempts: 3,
backoff: 'exponential',
})
- Open Dashboard and select your project
- Go to Jobs → click Create Job
- Select a trigger type and enter the handler URL
- Add your payload and configure retry settings
- Click Create
The dashboard also shows job status, run history, and allows manual triggers.
Body field
Type
Description
trigger requiredobject
Trigger config.
{ type: "immediate" }, { type: "delayed", delay_seconds }, { type: "scheduled", schedule, timezone? }, { type: "queue", queue }, or { type: "pull", queue }.handlerstring
HTTPS URL to POST when the job fires. Must respond within 30s.
payloadany JSON
Job payload (max 256 KB serialized)
namestring
Display name (max 256 chars)
timeoutinteger
Handler timeout in seconds. Range 1–30, default
30.max_attemptsinteger
Max retry attempts. Range 1–20, default
3.backoffstring
Retry strategy:
exponential, linear, or fixed. Default exponential.priorityinteger
Priority level. Range 1–10, default
5. Lower = higher priority.callback_urlstring
HTTPS URL to POST results when the job completes
idempotency_keystring
Unique key to prevent duplicate jobs (max 128 chars)
enabledboolean
Whether the job is active. Default
true.Error responses
400 Invalid body (validation error)
401 Unauthorized
402 Insufficient Tokens
429 Rate Limited
Batch Create
GET
typescript
await ss.infra.jobs.batchCreate([
{ trigger: { type: 'immediate' }, handler: 'https://app.acme.com/api/task-a', payload: { id: 1 } },
{ trigger: { type: 'immediate' }, handler: 'https://app.acme.com/api/task-b', payload: { id: 2 } },
])
- Batch create is an API-only feature
- Use the REST API or TypeScript SDK for bulk job creation
You can create jobs individually in Dashboard → Jobs
Body field
Type
Description
jobs requiredarray
Array of job definitions (max 100). Each uses the same schema as Create Job.
Error responses
400 Invalid body (validation error)
401 Unauthorized
402 Insufficient Tokens
429 Rate Limited
List Jobs
GET
typescript
const jobs = await ss.infra.jobs.list({ status: 'pending', limit: 50 })
- Open Dashboard and select your project
- Go to Jobs to see all jobs with filters for status and trigger type
Query param
Type
Description
statusstring
Filter by status:
pending, running, completed, failed, cancelled, deadtrigger_typestring
Filter by trigger:
immediate, delayed, scheduled, queue, pullqueuestring
Filter by queue name
limitinteger
Max results per page. Range 1–500, default
50.cursorstring
Pagination cursor from a previous response
Error responses
401 Unauthorized
402 Insufficient Tokens
429 Rate Limited
Get Job
GET
json — 200 OK
{
"id": "job_01JNXS...",
"status": "completed",
"trigger": { "type": "immediate" },
"handler": "https://app.acme.com/api/on-signup",
"attempts": 1,
"max_attempts": 3,
"created_at": "2026-03-04T12:00:00Z",
"completed_at": "2026-03-04T12:00:01Z"
}
typescript
const job = await ss.infra.jobs.get('job_01JNXS...')
- Open Dashboard and select your project
- Go to Jobs and click on any job to view its details
Path param
Type
Description
job_id requiredstring
Job ID
Error responses
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited
Update Job
GET
typescript
await ss.infra.jobs.update('job_01JNXS...', {
trigger: { schedule: '0 */2 * * *' },
enabled: true,
})
- Open Dashboard and select your project
- Go to Jobs and click on the job you want to update
- Edit the schedule, handler, or toggle enabled/disabled
- Click Save
Path param
Type
Description
job_id requiredstring
Job ID
Body field
Type
Description
handlerstring
Updated handler HTTPS URL
payloadany JSON
Updated payload (max 256 KB)
enabledboolean
Enable or disable the job
triggerobject
Updated trigger config (schedule, timezone, delay_seconds)
Error responses
400 Invalid body (validation error)
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited
Cancel Job
GET
typescript
await ss.infra.jobs.cancel('job_01JNXS...')
- Open Dashboard and select your project
- Go to Jobs and click on the job
- Click Cancel
Path param
Type
Description
job_id requiredstring
Job ID to cancel
Error responses
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited
Claim Job
GET
Claim a pull-type job for processing. Supports work-stealing pools where multiple workers compete for jobs.
typescript
const jobs = await ss.infra.jobs.claim({ queue_name: 'mobile-tasks', limit: 5 })
- Claim is an API-only operation for pull-type job processing
- Use the REST API or TypeScript SDK
Body field
Type
Description
queue requiredstring
Queue name to claim from
countinteger
Number of jobs to claim. Range 1–10, default
1.visibility_timeoutinteger
Seconds before unclaimed job becomes available again. Range 1–3600, default
30.Error responses
400 Invalid body (validation error)
401 Unauthorized
402 Insufficient Tokens
404 No jobs available
429 Rate Limited
Acknowledge Job
GET
typescript
await ss.infra.jobs.ack('job_01JNXS...', {
status: 'completed',
result: { processed: 42 },
})
- Acknowledge is an API-only operation for completing claimed jobs
- Use the REST API or TypeScript SDK
Path param
Type
Description
job_id requiredstring
Job ID to acknowledge
Body field
Type
Description
status requiredstring
Outcome:
completed or failedresultany JSON
Result data (for completed jobs)
errorstring
Error message (for failed jobs)
Error responses
400 Invalid body (validation error)
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited
Trigger Job
GET
json — 202 Accepted
{
"job_id": "job_01JNXS...",
"run_id": "run_01JNXS...",
"triggered_at": "2026-03-05T12:00:00Z"
}
typescript
await ss.infra.jobs.trigger('job_01JNXS...')
- Open Dashboard and select your project
- Go to Jobs and click on the scheduled job
- Click Trigger Now to run it immediately
Path param
Type
Description
job_id requiredstring
Job ID to trigger immediately
Error responses
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited
Retry Job
GET
typescript
await ss.infra.jobs.retry('job_01JNXS...')
- Open Dashboard and select your project
- Go to Jobs and click on the failed job
- Click Retry to re-enqueue it
Path param
Type
Description
job_id requiredstring
Job ID to retry
Error responses
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited
Run History
GET
json — 200 OK
{
"runs": [
{
"id": "run_01JNXS...",
"job_id": "job_01JNXS...",
"scheduled_at": "2026-03-05T09:00:00Z",
"started_at": "2026-03-05T09:00:01Z",
"completed_at": "2026-03-05T09:00:02Z",
"status": "completed",
"duration_ms": 1023,
"handler_status": 200,
"error": null
}
],
"next_cursor": null
}
typescript
const runs = await ss.infra.jobs.runs('job_01JNXS...')
// runs.runs, runs.next_cursor
- Open Dashboard and select your project
- Go to Jobs and click on any job
- The Run History tab shows all execution attempts with timing and status
Path param
Type
Description
job_id requiredstring
Job ID
Query param
Type
Description
limitinteger
Max runs to return. Range 1–500, default
50.cursorstring
Pagination cursor
Error responses
401 Unauthorized
402 Insufficient Tokens
404 Not Found
429 Rate Limited