Jobs
One primitive replaces three services. Queue, Task, and Cron are all the same object — what differs is the trigger.
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.immediatedelayedscheduledqueuepullCreate Job
Create a job. Payload max 256 KB, name max 256 chars, queue max 128 chars, handler/callback_url must be HTTPS public URLs, max_attempts 1-20, timeout 1-30s, priority 1-10.
curl -X POST https://api.saasignal.saastemly.com/infra/jobs \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"trigger":{"type":"immediate"},"payload":{"id":1}}'
{ "status": "ok" }
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
trigger required{ type: "immediate" }, { type: "delayed", delay_seconds }, { type: "scheduled", schedule, timezone? }, { type: "queue", queue }, or { type: "pull", queue }.handlerpayloadnametimeout30.30max_attempts3.3backoffexponential, linear, or fixed. Default exponential.exponential, linear, fixeddefault exponentialpriority5. Lower = higher priority.5callback_urlidempotency_keyenabledtrue.trueBatch Create
Create up to 100 jobs.
curl -X POST https://api.saasignal.saastemly.com/infra/jobs/batch \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"jobs":[]}'
{ "status": "ok" }
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
jobs requiredList Jobs
List jobs with optional status, trigger type, and queue filters. Supports cursor-based pagination. Max 500 results per page.
curl https://api.saasignal.saastemly.com/infra/jobs \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
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
statuspending, running, completed, failed, cancelled, deadpending, queued, running, completed, failed, dead, cancelledtrigger_typeimmediate, delayed, scheduled, queue, pullimmediate, delayed, scheduled, queue, pullqueuelimit50.50cursorGet Job
Retrieve a single job by ID, including its current status, trigger, and payload.
curl https://api.saasignal.saastemly.com/infra/jobs/{job_id} \
-H "Authorization: Bearer sk_live_..."
{
"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"
}
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
job_id requiredUpdate Job
Update a job's handler, payload, enabled state, or trigger schedule. Only pending or scheduled jobs can be updated.
curl -X PATCH https://api.saasignal.saastemly.com/infra/jobs/{job_id} \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{}'
{ "status": "ok" }
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
job_id requiredhandlerpayloadenabledtriggerCancel Job
Cancel a pending or scheduled job. Running jobs cannot be cancelled.
curl -X DELETE https://api.saasignal.saastemly.com/infra/jobs/{job_id} \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
await ss.infra.jobs.cancel('job_01JNXS...')
- Open Dashboard and select your project
- Go to Jobs and click on the job
- Click Cancel
job_id requiredClaim Job
Claim a pull-type job for processing. Supports work-stealing pools where multiple workers compete for jobs.
curl -X POST https://api.saasignal.saastemly.com/infra/jobs/claim \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"queue":"..."}'
{ "status": "ok" }
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
queue requiredcount1.1visibility_timeout30.30Acknowledge Job
Acknowledge a claimed job as completed or failed. Only the token that claimed the job can acknowledge it.
curl -X POST https://api.saasignal.saastemly.com/infra/jobs/{job_id}/ack \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"status":"completed"}'
{ "status": "ok" }
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
job_id requiredstatus requiredcompleted or failedcompleted, failedresulterrorTrigger Job
Manually trigger a scheduled job to run now.
curl -X POST https://api.saasignal.saastemly.com/infra/jobs/{job_id}/trigger \
-H "Authorization: Bearer sk_live_..."
{
"job_id": "job_01JNXS...",
"run_id": "run_01JNXS...",
"triggered_at": "2026-03-05T12:00:00Z"
}
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
job_id requiredRetry Job
Retry a failed or dead job. Resets the job to pending and re-enqueues it.
curl -X POST https://api.saasignal.saastemly.com/infra/jobs/{job_id}/retry \
-H "Authorization: Bearer sk_live_..."
{ "status": "ok" }
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
job_id requiredRun History
List execution runs for a job with cursor-based pagination. Max 500 results per page.
curl https://api.saasignal.saastemly.com/infra/jobs/{job_id}/runs \
-H "Authorization: Bearer sk_live_..."
{
"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
}
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
job_id requiredlimit50.50cursor