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 — the worker will stop 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 — the worker will pause 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.

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