Query Jobs
List jobs, get details, progress, and logs
Query Jobs
Endpoints for reading job data. All require an API key with jobs:read scope (except Get Progress which also accepts jobs:read:progress).
List Jobs
GET /api/v1/spaces/:spaceId/jobs
Scope: jobs:read
Query params:
| Param | Required | Default | Description |
|---|---|---|---|
status | No | — | Filter: pending, delivered, running, completed, dead, killed |
limit | No | 50 | Max results (max: 100) |
offset | No | 0 | Pagination offset |
curl "https://emit.run/api/v1/spaces/$SPACE_ID/jobs?status=running&limit=20" \
-H "x-api-key: $EMIT_KEY"const res = await fetch(
`${API}/spaces/${spaceId}/jobs?status=running&limit=20`,
{ headers: { "x-api-key": key } }
);
const jobs = await res.json();res = requests.get(
f"{API}/spaces/{space_id}/jobs",
headers={"x-api-key": key},
params={"status": "running", "limit": 20},
)
jobs = res.json()Response:
[
{
"id": "01JLQX...",
"spaceId": "01JLQ...",
"name": "process-video",
"payload": { "url": "s3://bucket/video.mp4", "format": "720p" },
"status": "running",
"maxRetries": 5,
"attemptNumber": 1,
"timeoutSeconds": 600,
"deliveredAt": "2025-02-24T10:31:00.000Z",
"startedAt": "2025-02-24T10:31:05.000Z",
"completedAt": null,
"result": null,
"createdAt": "2025-02-24T10:30:00.000Z",
"updatedAt": "2025-02-24T10:31:05.000Z"
}
]Ordered by creation time (newest first). Returns an empty array if no jobs match.
Get Job
GET /api/v1/jobs/:jobId
Scope: jobs:read
Fetch a job's full details including its event history. Log lines are stored separately and queried via Get Job Logs.
curl https://emit.run/api/v1/jobs/$JOB_ID \
-H "x-api-key: $EMIT_KEY"const res = await fetch(`${API}/jobs/${jobId}`, {
headers: { "x-api-key": key },
});
const job = await res.json();Response:
{
"id": "01JLQX...",
"spaceId": "01JLQ...",
"name": "process-video",
"payload": { "url": "s3://bucket/video.mp4", "format": "720p" },
"status": "completed",
"maxRetries": 5,
"attemptNumber": 0,
"timeoutSeconds": 600,
"callbackUrl": "https://example.com/webhooks/jobs",
"callbackHeaders": { "Authorization": "Bearer your-secret" },
"deliveredAt": "2025-02-24T10:31:00.000Z",
"startedAt": "2025-02-24T10:31:05.000Z",
"completedAt": "2025-02-24T10:34:20.000Z",
"result": { "output_url": "s3://bucket/output.mp4", "duration_ms": 12340 },
"createdAt": "2025-02-24T10:30:00.000Z",
"updatedAt": "2025-02-24T10:34:20.000Z",
"events": [
{
"id": "01JLQY...",
"jobId": "01JLQX...",
"spaceId": "01JLQ...",
"type": "created",
"data": null,
"createdAt": "2025-02-24T10:30:00.000Z"
},
{
"id": "01JLR0...",
"jobId": "01JLQX...",
"spaceId": "01JLQ...",
"type": "completed",
"data": { "output_url": "s3://bucket/output.mp4", "duration_ms": 12340 },
"createdAt": "2025-02-24T10:34:20.000Z"
}
]
}{ "error": "Job not found" }Get Job Progress
GET /api/v1/jobs/:jobId/progress
Scope: jobs:read:progress or jobs:read
Return the most recent progress update (if any). This endpoint only exposes progress data.
curl https://emit.run/api/v1/jobs/$JOB_ID/progress \
-H "x-api-key: $EMIT_KEY"const res = await fetch(`${API}/jobs/${jobId}/progress`, {
headers: { "x-api-key": key },
});
const progress = await res.json();Response:
{
"jobId": "01JLQX...",
"progress": {
"percent": 65,
"message": "Encoding video",
"subProgress": {
"download": { "percent": 100, "message": "Source fetched" },
"transcode": { "percent": 42, "message": "Pass 1/2" }
}
},
"timestamp": "2025-02-24T10:32:00.000Z"
}If no progress has been reported yet, progress and timestamp are null.
Get Job Logs
GET /api/v1/jobs/:jobId/logs
Scope: jobs:read
Query logs for one job. Optimized for tailing (after) and infinite-scroll history (before).
Query params:
| Param | Required | Default | Description |
|---|---|---|---|
limit | No | 200 | Max logs to return (max: 500) |
after | No | — | Return logs with seq greater than this value (tail mode) |
before | No | — | Return logs with seq lower than this value (history mode) |
q | No | — | Full-text query on message |
level | No | — | Filter by one or more levels (trace, debug, info, warn, error, fatal) |
Use either after or before (not both).
curl "https://emit.run/api/v1/jobs/$JOB_ID/logs?after=1200&limit=100" \
-H "x-api-key: $EMIT_KEY"const res = await fetch(`${API}/jobs/${jobId}/logs?after=${lastSeq}&limit=100`, {
headers: { "x-api-key": key },
});
const page = await res.json();Response:
{
"logs": [
{
"id": "01JLOG...",
"seq": 1201,
"level": "info",
"message": "downloaded source chunk",
"source": "worker-a",
"metadata": { "chunk": 12 },
"loggedAt": "2026-03-01T09:21:01.120Z",
"createdAt": "2026-03-01T09:21:01.125Z"
}
],
"cursor": {
"mode": "after",
"oldestSeq": 1201,
"newestSeq": 1201,
"hasMore": false
}
}