emit.run

Create Jobs

Submit jobs to the dispatch queue

Create Jobs

POST /api/v1/spaces/:spaceId/jobs

Scope: jobs:create

Submit one or more jobs to the space's dispatch queue.

You can send either:

  • a single job object (backward compatible), or
  • an array of job objects for bulk ingestion in a single request.

Request body

FieldTypeRequiredDefaultDescription
namestringYesJob identifier (e.g., send-email, generate-report)
payloadobjectNonullArbitrary JSON passed to your worker
maxRetriesnumberNo3Max retry attempts on failure (0–25)
timeoutSecondsnumberNo300Timeout per attempt in seconds (1–86400); used for delivery + execution
scheduledForstringNonullISO 8601 timestamp; delays the job until this time (must be in the future)
callbackUrlstringNonullWebhook URL to POST when job reaches a terminal state (completed, dead, killed)
callbackHeadersobjectNonullCustom headers to include in the callback request (string values only)
curl -X POST https://emit.run/api/v1/spaces/$SPACE_ID/jobs \
  -H "x-api-key: $EMIT_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "name": "process-video",
      "payload": { "url": "s3://bucket/video.mp4", "format": "720p" },
      "maxRetries": 5,
      "timeoutSeconds": 600,
      "callbackUrl": "https://example.com/webhooks/jobs",
      "callbackHeaders": { "Authorization": "Bearer your-secret" }
    },
    {
      "name": "generate-thumbnail",
      "payload": { "url": "s3://bucket/video.mp4", "size": "small" }
    }
  ]'
const res = await fetch(`${API}/spaces/${spaceId}/jobs`, {
  method: "POST",
  headers: { "x-api-key": key, "Content-Type": "application/json" },
  body: JSON.stringify([
    {
      name: "process-video",
      payload: { url: "s3://bucket/video.mp4", format: "720p" },
      maxRetries: 5,
      timeoutSeconds: 600,
      callbackUrl: "https://example.com/webhooks/jobs",
      callbackHeaders: { Authorization: "Bearer your-secret" },
    },
    {
      name: "generate-thumbnail",
      payload: { url: "s3://bucket/video.mp4", size: "small" },
    },
  ]),
});
const jobs = await res.json();
res = requests.post(
    f"{API}/spaces/{space_id}/jobs",
    headers={"x-api-key": key, "Content-Type": "application/json"},
    json=[
        {
            "name": "process-video",
            "payload": {"url": "s3://bucket/video.mp4", "format": "720p"},
            "maxRetries": 5,
            "timeoutSeconds": 600,
            "callbackUrl": "https://example.com/webhooks/jobs",
            "callbackHeaders": {"Authorization": "Bearer your-secret"},
        },
        {
            "name": "generate-thumbnail",
            "payload": {"url": "s3://bucket/video.mp4", "size": "small"},
        },
    ],
)
jobs = res.json()

Response

The create endpoint returns minimal job references (id, spaceId) for each created job. It does not include job state fields or convenience URL fields such as realtimeUrl, jobUrl, progressUrl, or logsUrl.

Build those URLs from the returned id:

const jobUrl = `${API}/jobs/${job.id}`;
const progressUrl = `${API}/jobs/${job.id}/progress`;
const logsUrl = `${API}/jobs/${job.id}/logs`;
const realtimeUrl = `wss://emit.run/api/v1/realtime/${job.id}`;
{
  "id": "01JLQX...",
  "spaceId": "01JLQ..."
}
[
  {
    "id": "01JLQX...",
    "spaceId": "01JLQ..."
  },
  {
    "id": "01JLQY...",
    "spaceId": "01JLQ..."
  }
]
{ "error": "jobs[0].name is required" }

Scheduled (delayed) jobs

Set scheduledFor to an ISO 8601 timestamp in the future to delay a job. The job enters the scheduled state and is not available for polling until the scheduled time. When the time arrives, it automatically transitions to pending and enters the dispatch queue like any other job.

{
  "name": "send-report",
  "payload": { "reportId": "abc123" },
  "scheduledFor": "2025-03-01T09:00:00.000Z"
}

Scheduled jobs can be killed before they run. If scheduledFor is omitted or in the past, the job is created as pending immediately.

On this page