Skip to content

Jobs

Admin API endpoints for managing background jobs. For a conceptual overview, see Background jobs.

GET /admin/jobs

Returns a paginated list of jobs, newest first.

Query parameters:

ParameterTypeDescription
statusstringFilter by status: pending, running, pausing, paused, cancelling, cancelled, completed or failed
limitnumberMaximum number of results, 1 to 100 (default: 50)
cursorstringPagination cursor from a previous response

Permission: jobs:read

Response:

{
"jobs": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"job_type": "export",
"status": "completed",
"input": { "collection": "xyz.statusphere.status" },
"progress": { "processed": 1500 },
"result": { "processed": 1500 },
"error": null,
"created_by": "did:plc:abc123",
"inherit_auth": false,
"api_client_id": null,
"dpop_key_id": null,
"attempt": 1,
"started_at": "2026-07-01T12:00:05Z",
"completed_at": "2026-07-01T12:02:30Z",
"created_at": "2026-07-01T12:00:00Z"
}
],
"cursor": "next-page-cursor"
}
GET /admin/jobs/{id}

Returns a single job by ID.

Permission: jobs:read

Response: Same shape as a single item in the list response.

POST /admin/jobs/{id}/cancel

Request cancellation of a job. If the job is pending or paused, it’s immediately set to cancelled. If the job is running, it’s set to cancelling, and the worker stops the job when the script next calls ctx.job.should_stop().

Permission: jobs:manage

Response:

{
"status": "cancelling"
}

Errors:

StatusCondition
404Job not found
409Job is already completed, failed, or cancelled
409The job’s status changed while the request ran; reload and try again
POST /admin/jobs/{id}/pause

Request pause of a running job. Sets the status to pausing, and the worker pauses the job when the script next calls ctx.job.should_stop().

Permission: jobs:manage

Response:

{
"status": "pausing"
}

Errors:

StatusCondition
404Job not found
409Job is not running
409The job’s status changed while the request ran; reload and try again
POST /admin/jobs/{id}/resume

Resume a paused job. Sets the status back to pending so the worker picks it up again.

Permission: jobs:manage

Response:

{
"status": "pending"
}

Errors:

StatusCondition
404Job not found
409Job is not paused
409The job’s status changed while the request ran; reload and try again
GET /admin/jobs/{id}/logs

Returns the lines a job’s script logged with internal.logging, oldest first. Lines are deleted on the event log’s retention (event_log_retention_days).

Query parameters:

ParameterTypeDescription
limitnumberMaximum number of lines, 1 to 500 (default: 100)
cursorstringThe cursor from a previous response

Permission: jobs:read

Response:

{
"logs": [
{
"id": "…",
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"level": "info",
"message": "processing item",
"createdAt": "2026-07-01T12:00:06Z"
}
],
"cursor": null
}

cursor is set when there are more lines. A job with no lines, or an id that names no job, answers an empty list.

FieldTypeDescription
idstringUUID
job_typestringThe type name passed to jobs.create
statusstringCurrent status (see lifecycle)
inputobjectInput data passed to jobs.create
progressobjectLast progress update from ctx.job.progress()
resultobject|nullReturn value of the script on completion
errorstring|nullError message on failure
created_bystringDID of the user who enqueued the job
inherit_authbooleanWhether the job inherits the creator’s PDS auth
api_client_idstring|nullThe API client whose session the job inherited, when it did
dpop_key_idstring|nullThe DPoP key of the session the job inherited, when it did
attemptnumberHow many runs of the job have started, including one that lost its worker
started_atstring|nullISO 8601 timestamp when the worker started executing
completed_atstring|nullISO 8601 timestamp when the job finished
created_atstringISO 8601 timestamp when the job was enqueued